Leaked source code of windows server 2003
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.
 
 
 
 
 
 

290 lines
8.4 KiB

// Copyright (c) 1996-1999 Microsoft Corporation
------ state of the system ---------
Each parsing of an open brace should change
the state of the system.
As a feature, option, switch(feature), case(option)
or other construct is parsed this is noted.
this construct stack allows us to select the appropriate
context for parsing:
is this a local keyword to this option (construct) or is it
EXTERN:?
What tree structure should be built for this construct?
then the parsing code should continue parsing
tokens as normal.
There will be tables that state what the
local keywords are for each situation.
constructs:
UIGroup, Feature, Option, Switch, Case,
Commands, Font, OEM
state stack:
each state is of the form: state / symbol
The stack is empty at the root level.
state allowed transitions may contain
root UIGroup any global attributes
Feature
Switch
Commands
Font
OEM
UIGroup Feature none
UIGroup
Feature Switch feature attributes
Options
Switch Case none
Options Switch option attributes
relocatable Global Attributes
Case Switch
relocatable local Attributes
of immediately enclosing
construct outside of Switch.
relocatable Global Attributes
Commands none command attributes
ShortCommands none cmdName:invocation
Font none font attributes
OEM none oem attributes
Note: Commands and Fonts are considered
relocatable Global Attributes
Tables: root attributes (divide into relocatable and non)
feature attributes ()
option attributes ()
command attributes
font attributes
oem attributes
Tables of allowed transitions:
Rules: how to construct a tree and where to plant the tree
for a local or global attribute
---- implementation of this state machine -------
typedef enum {CONSTRUCT, LOCAL, GLOBAL,
INVALID_CONSTRUCT, INVALID_LOCAL, INVALID_GLOBAL,
INVALID_UNRECOGNIZED, COMMENT, EOF } keywordClass ;
GroundState()
{
STATE StateStack[] ;
for(1)
{
extract Keyword(keyword)
class = ClassifyKeyword(keyword)
switch (class)
{
case (CONSTRUCT):
parseSymbol(symbol) ;
parseOpenBrace() ; // somewhere we need to register symbol
// and allocate memory for structure
// and return ptr or index to new
// or existing structure
changeState(keyword) ;
case (COMMENT):
absorbCommentLine() ;
case (LOCAL) :
ProcessLocalAttribute(keyword) ;
case (GLOBAL) :
ProcessGlobalAttribute(keyword) ;
case (SPECIAL) :
ProcessSpecialAttribute(keyword) ;
case (EOF)
return(1);
default:
ErrorHandling() ;
}
if(rc == FATAL)
return(1);
}
}
class = ClassifyKeyword(keyword)
{
if(commentline)
return(COMMENT) ;
if(EOF)
return(EOF) ;
The current state determines which sets of
keywords are allowed.
state = DetermineCurrentState()
implement this table:
for each state there is a list of all the keywords
arranged in a fixed order (by keyword ID) each keyword
is assigned a classification:
Valid Constructs
InValid Constructs
Valid Local Attribute
InValid Local Attribute
Valid Global Attribute
InValid Global Attribute
Valid Special Attribute
InValid Special Attribute
if(keyword not found it table)
return(INVALID_UNRECOGNIZED) ;
return(classTable[keyword][state]) ;
}
typedef enum {ROOT, UIGROUP, FEATURE, SWITCH, OPTIONS, CASE_ROOT,
CASE_FEATURE, CASE_OPTION, COMMAND, SHORT_COMMAND,
FONT, OEM, any other passive construct} STATES ;
Sample Table
KEYWORD STATES ---->
*Command
*UIGroup *Switch *CaseRoot *CaseOption *Font
*Root *Feature *Options *CaseFeature *ShortCmd *OEM
UIGroup : VC VC IC IC IC IC IC IC IC IC IC IC
Feature : VC VC IC IC IC IC IC IC IC IC IC IC
Switch : VC IC VC IC VC VC VC VC IC IC IC IC
Options : IC IC VC IC IC IC IC IC IC IC IC IC
Case : IC IC IC VC IC IC IC IC IC IC IC IC
Command : VC IC IC IC VC VC VC VC IC IC IC IC
Font : VC IC IC IC VC VC VC VC IC IC IC IC
OEM : VC IC IC IC IC IC IC IC IC IC IC IC
UIConstraints : IS IS VS IS VS IS IS IS IS IS IS IS
note: UIConstraints appearing in a Feature is treated differently
than appearing under Options. The processing of UIConstraints
causes one, two or many elements to be added to the Constraints
Array. This is in stark contrast to normal keywords hence
the classification of Special.
state stack:
each state is of the form: state / symbol
DetermineCurrentState()
{
// this state is only used to determine
// which catagories of keywords are
// assigned which TYPES in ClassifyKeyword().
if(CurState == 0)
return(ROOT) ; // No further processing needed.
return(stateStack[CurState - 1].state) ;
}
changeState(keyword, symbol, mode)
{
// Change needed: shortcut *Command
// does not initiate a state change. This should
// be treated as a special keyword.
// mode determines if the *Command keyword
// introduces a normal command construct or
// the short version.
switch(keyword)
{
case (*UIGroup):
addState(UIGROUP, symbol);
case (*Feature):
addState(FEATURE, symbol);
case (*Switch):
addState(SWITCH, symbol);
case (*Option):
addState(OPTIONS, symbol);
case (*Font):
addState(FONT, symbol);
case (*OEM):
addState(OEM, symbol);
case (*Command):
{
if(mode == short)
addState(SHORT_CMD, symbol);
else
addState(COMMAND, symbol);
}
case (*Case):
{
if(stateStack[CurState - 2].state == ROOT ||
stateStack[CurState - 2].state == CASE_ROOT)
addState(CASE_ROOT, symbol);
if(stateStack[CurState - 2].state == FEATURE ||
stateStack[CurState - 2].state == CASE_FEATURE)
addState(CASE_FEATURE, symbol);
if(stateStack[CurState - 2].state == OPTIONS ||
stateStack[CurState - 2].state == CASE_OPTIONS)
addState(CASE_OPTIONS, symbol);
}
}
}
// these two functions will grow an appropriate
// tree for each keyword based on the StateStack
// and plant the tree in the appropriate attribute
// field in the appropriate structure, (index) etc.
// or add a branch to an existing tree,
// and set the value at the node of the tree.
ProcessLocalAttribute(keyword) ;
ProcessGlobalAttribute(keyword, lpvalue)
{
locate entry in Dglobals corresponding
to keyword.
OR the current branch (constructed using the state stack)
with any existing tree pointed to by entry in Dglobals.
if this branch exists in the existing tree, locate the offset
in heap and overwrite that by
(lptype)(lpRef + attributeTree[i].offset) = (lptype)lpvalue ;
otherwise
offset = lpCurHeapPos - lpRef ;
lpCurHeapPos += sizeof(datatype) ;
Note: an attribute tree should not be constructed
piecemeal. It is an error if the tree is subsequently
redefined/elaborated using a different feature nesting
order.
}
may need to keep a table for each keyword
with the following info per keyword.
keyword, datastructure, offset within datastructure, sizeof(data)