You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
6.9 KiB
183 lines
6.9 KiB
// Copyright (c) 1996-1999 Microsoft Corporation
|
|
A quick tour of the GPD parser:
|
|
|
|
A GPD source file is consists of a series of
|
|
statements. Each statement typically consists of
|
|
a Keyword - value pair separated by a colon delimiter.
|
|
The parser classifies keywords into Attribute and
|
|
non-Attribute keywords. Attribute keywords require
|
|
a context before they can be defined. They are used
|
|
to define the value for individual attributes.
|
|
Non-Attribute keywords establish the context for
|
|
the other keywords. Construct keywords are examples
|
|
of Non-Attribute keywords.
|
|
|
|
BcreateGPDbinary() - framwrk1.c: current entry point for
|
|
parsing of GPD source file. Calls functions to initialize
|
|
gMasterTable[] which contains almost all allocated buffers.
|
|
|
|
Then calls other functions to process the GPD file.
|
|
|
|
BcreateTokenMap() - token1.c : memory maps root file, SOURCEBUFFER holds
|
|
pointers to memory address and current position.
|
|
They are accessed via the macros mpubSrcRef and mdwSrcInd.
|
|
|
|
The source file is parsed into Keywords and Values.
|
|
Since a variety of syntax rules are allowed for the different
|
|
value types, the parsing is very liberal with little syntax
|
|
checking.
|
|
|
|
All arbitrary whitespace is discarded (replaced by space chars).
|
|
This includes all comments and continuation lines.
|
|
|
|
One TKMAP structure is initialized for each
|
|
GPD statement parsed. If the keyword is found to be
|
|
a non-Attribute keyword, its keywordID is stored in the
|
|
TKMAP, else it is marked as an "Unidentified" keyword.
|
|
|
|
|
|
BevaluateMacros() Macro replacement stage: Not implemented yet.
|
|
This is where macro substitution and shortcut expansion
|
|
occurs. Some token map entries are deleted and new ones
|
|
are added.
|
|
|
|
|
|
First pass of BInterpretTokens():
|
|
|
|
*Feature: PaperSize
|
|
{
|
|
*Option: Letter
|
|
{
|
|
}
|
|
}
|
|
*Command: CmdStartJob
|
|
{
|
|
}
|
|
|
|
Each entry in the Tokenmap is examined.
|
|
If the entry is a Construct keyword (a subset of non-Attribute
|
|
keyword), the associated symbolname value is registered in the
|
|
appropriate symboltree. For example, BlockMacroNames, FontCartridge names,
|
|
and FeatureNames occupy different symboltrees (and hence different
|
|
namespaces). OptionNames occupy subtrees branching from the
|
|
associated FeatureName.
|
|
|
|
Each Construct keyword encountered causes a statemachine change.
|
|
The previous state is restored when the closing brace is encountered.
|
|
|
|
If the entry is an attribute keyword, the current state
|
|
is used to determine which construct they are a part of
|
|
and hence which dictionary to use. The EXTERN_GLOBAL
|
|
prefix will override this for global attributes, permitting
|
|
globals to be used within other constructs.
|
|
|
|
The dictionary defines
|
|
the name of the keyword, what type of keyword it is, if
|
|
it is an Attribute, the subtype determines what structure
|
|
the value is stored in and what state the keyword
|
|
may legally appear in, the offset determines the location within
|
|
the structure, the AllowedValue determines the syntax of the value
|
|
and the format it is stored. The namespaces of attributes belonging
|
|
to different constructs are separate. Hence the attribute *Name used in
|
|
a *Feature construct is not confused with *Name used within an *Option
|
|
construct.
|
|
|
|
|
|
|
|
BallocateCountableObjects():
|
|
By counting the number of symbols registered in the first pass
|
|
of BInterpretTokens() we know how many structures of each type
|
|
to alloc. Now we can actually store the values associated
|
|
with the attribute keywords.
|
|
|
|
Second pass of BInterpretTokens():
|
|
|
|
Construct keywords are again parsed to establish the current
|
|
state.
|
|
Attribute Keywords are checked against the current state.
|
|
Does this Keyword belong in this state?
|
|
If the attribute is legal, the parser proceeds to
|
|
a) locate the root of attribute.
|
|
b) create or identify an existing branch in the attribute
|
|
tree which corresponds to the set of states defined by
|
|
the nested constructs.
|
|
c) parse the value token associated with the attribute
|
|
and store its value in the appropriate format.
|
|
d) write a link into the appropriate node at the end of the
|
|
branch in the attribute tree.
|
|
|
|
|
|
example, a string referenced from GlobalAttributes structure:
|
|
|
|
typedef struct
|
|
{
|
|
....
|
|
ATREEREF atrModelName ; contains index of an
|
|
ATTRIB_TREE structure in the array of structures
|
|
|
|
...
|
|
} GLOBALATTRIB, * PGLOBALATTRIB ; // the prefix tag shall be 'ga'
|
|
|
|
The field dwOffset in a ATTRIB_TREE leaf node contains
|
|
a heap offset which contains a STRINGREF (aka ARRAYREF)
|
|
which contains the heap offset and byte count of the
|
|
actual string.
|
|
|
|
BInterpretTokens()
|
|
BidentifyAttributeKeyword(ptkmap + wEntry) )
|
|
BprocessAttribute(ptkmap + wEntry) ;
|
|
BstoreGlobalAttrib(ptkmap) ; // different function for each construct
|
|
// identifies which structure and offset contains ATREEREF
|
|
// (root of tree)
|
|
BaddBranchToTree(ptkmap, (PATREEREF)(pub + dwOffset)) ;
|
|
// navigates or adds branch to tree
|
|
BaddValueToHeap() ;
|
|
// if value is stored in dedicated structure,
|
|
// accesses or allocates that element, provides
|
|
// address of that memory location to
|
|
BparseAndWrite((PBYTE)pcmd + dwOffset, ptkmap,
|
|
FALSE, NULL ) )
|
|
// else the address of the dwOffset field is provided.
|
|
// this function determines the type of value
|
|
// to be parsed and calls the appropriate
|
|
// function to parse the token and to store
|
|
// it in the proper format.
|
|
BparseAndTerminateString(&aarValue, (PARRAYREF)pubTmp) ;
|
|
|
|
Special cases:
|
|
|
|
Is the attribute value stored in a dedicated structure ?
|
|
ie does the value in the node of the attribute tree reference
|
|
a heap offset or a dedicated structure?
|
|
|
|
Does the root of the tree reference a heap offset or a
|
|
ATTRIB_TREE structure?
|
|
|
|
Does the attribute tree have a global default initializer node?
|
|
Does each feature level in the attribute tree have a default
|
|
initializer corresponding to the *default keyword?
|
|
|
|
|
|
|
|
AddBranchToTree() - token2.c
|
|
The loop uses the state stack to navigate or create a
|
|
particular branch of the attribute tree,
|
|
then after exiting the loop, the value is parsed
|
|
and its heap offset is written to the node in the
|
|
attribute tree.
|
|
|
|
Value1.c : this module contains functions to parse
|
|
the different value types defined in the GPD spec.
|
|
|
|
integers, POINT, RECT, Constants, Symbols, strings,
|
|
commands, LISTS, QualifiedNames, OrderDependency,
|
|
Constraints and InvalidCombinations. (found in constrnt.c)
|
|
Functions that parse Command invocations are found in command.c
|
|
|
|
BconsolidateBuffers() this function copies portions of
|
|
some buffers listed in gMasterTable[] into a new consolidated
|
|
buffer. This buffer is saved as the *.BUD binary file.
|
|
|
|
Code to create a snapshot and other helper functions.
|
|
Not completed at this time.
|
|
|