890 lines
26 KiB
Plaintext
890 lines
26 KiB
Plaintext
unit dpglib.DpgParser;
|
|
|
|
uses
|
|
{
|
|
dpglib.types;
|
|
}
|
|
|
|
|
|
parser TDpgParser;
|
|
options
|
|
{
|
|
defaultErrorHandler = false;
|
|
importVocab = dpglib.DpgLexer;
|
|
exportVocab = dpglib.DpgParser;
|
|
k = 2;
|
|
}
|
|
|
|
memberdecl
|
|
{
|
|
protected
|
|
fGrammarMaker : IGrammarBehavior;
|
|
fTool : ITool;
|
|
fNesting : integer;
|
|
|
|
fExchangeDir : AnsiString;
|
|
fGrammarFile : AnsiString;
|
|
fGrammarUnit : AnsiString;
|
|
|
|
private
|
|
function lastInRule : boolean;
|
|
procedure checkEndRule( pToken: IToken);
|
|
|
|
public
|
|
constructor Create( pParserState : IParserState;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString); overload;
|
|
|
|
constructor Create( pTokenBuffer : ITokenBuffer;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString); overload;
|
|
|
|
constructor Create( pTokenStream : ITokenStream;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString); overload;
|
|
|
|
destructor Destroy; override;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// grammar
|
|
// ----------------------------------------------------------------------------
|
|
grammar
|
|
local
|
|
{
|
|
unitName: IToken;
|
|
}
|
|
:
|
|
"unit" unitName=qualifiedId {fGrammarUnit := unitName.TokenText;} SEMI
|
|
(usesDecl)?
|
|
(constDecl)?
|
|
(typeDecl)?
|
|
classDecl
|
|
{fGrammarMaker.endGrammar;}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// usesDecl
|
|
// ----------------------------------------------------------------------------
|
|
usesDecl
|
|
:
|
|
USES
|
|
(
|
|
// tr:TOKENREF SEMI {fGrammarMaker.defineUses( tr);}
|
|
// | rr:RULEREF SEMI {fGrammarMaker.defineUses( rr);}
|
|
qualifiedUsesName SEMI
|
|
)*
|
|
|
|
RCURLY
|
|
;
|
|
|
|
qualifiedUsesName
|
|
local
|
|
{
|
|
id: AnsiString;
|
|
}
|
|
: ( r:TOKENREF | r:RULEREF ) { id := r.TokenText; }
|
|
( WILDCARD
|
|
( r:TOKENREF | r:RULEREF) { id := id +'.'+ r.TokenText; }
|
|
)*
|
|
{
|
|
fGrammarMaker.defineUses(id);
|
|
}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// constDecl
|
|
// ----------------------------------------------------------------------------
|
|
constDecl
|
|
:
|
|
"const"
|
|
a:ACTION {fGrammarMaker.RefConstAction( a);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// typeDecl
|
|
// ----------------------------------------------------------------------------
|
|
typeDecl
|
|
:
|
|
"type"
|
|
a:ACTION {fGrammarMaker.RefTypeAction( a);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// classDecl
|
|
// ----------------------------------------------------------------------------
|
|
classDecl
|
|
local
|
|
{
|
|
grType : integer;
|
|
grObject : IToken;
|
|
grSuper : IToken;
|
|
}
|
|
{
|
|
grObject := nil;
|
|
grSuper := nil;
|
|
}
|
|
:
|
|
// ------------------------------------------------------------
|
|
// Determine parser type
|
|
// ------------------------------------------------------------
|
|
( "lexer" { grType := 0; }
|
|
| "parser" { grType := 1; }
|
|
| "treeparser" { grType := 2; }
|
|
)
|
|
|
|
// ------------------------------------------------------------
|
|
// get class name
|
|
// ------------------------------------------------------------
|
|
grObject = id
|
|
|
|
// ------------------------------------------------------------
|
|
// get superclass name
|
|
// ------------------------------------------------------------
|
|
// (
|
|
// LPAREN
|
|
// grSuper=id
|
|
// RPAREN
|
|
// )?
|
|
|
|
SEMI
|
|
|
|
// ------------------------------------------------------------
|
|
// Start the grammar
|
|
// ------------------------------------------------------------
|
|
{
|
|
// ---------------------------------------------------------
|
|
// Now we have enough information to start the grammar.
|
|
// ---------------------------------------------------------
|
|
case grType of
|
|
0: fGrammarMaker.StartLexer( InputState.FileName,
|
|
grObject,
|
|
grSuper);
|
|
|
|
1: fGrammarMaker.StartParser( InputState.FileName,
|
|
grObject,
|
|
grSuper);
|
|
|
|
2: fGrammarMaker.StartTreeWalker( InputState.FileName,
|
|
grObject,
|
|
grSuper);
|
|
end;
|
|
|
|
fGrammarMaker.defineGrammarUnit( fGrammarUnit);
|
|
}
|
|
|
|
// ------------------------------------------------------------
|
|
// Process optional class "options {...}" clause
|
|
// ------------------------------------------------------------
|
|
(classOptions)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Process optional class "tokens {...}" clause
|
|
// But only for lexers.
|
|
// ------------------------------------------------------------
|
|
( {grType=0}? classTokens)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Process optional class "memberDecl {...}" clause
|
|
// ------------------------------------------------------------
|
|
(classMemberDecl)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Well, the rules
|
|
// ------------------------------------------------------------
|
|
rules
|
|
|
|
// ------------------------------------------------------------
|
|
// Process optional class "memberDecl {...}" clause
|
|
// ------------------------------------------------------------
|
|
(classMemberDef)?
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// classOptions
|
|
// ----------------------------------------------------------------------------
|
|
classOptions
|
|
local
|
|
{
|
|
optName : IToken;
|
|
optValue : IToken;
|
|
}
|
|
:
|
|
OPTIONS
|
|
(
|
|
optName = id
|
|
ASSIGN
|
|
optValue = optionValue
|
|
SEMI
|
|
{fGrammarMaker.setGrammarOption( optName, optValue);}
|
|
)*
|
|
|
|
RCURLY
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// classTokens
|
|
// ----------------------------------------------------------------------------
|
|
classTokens
|
|
:
|
|
TOKENS
|
|
(
|
|
{
|
|
tokenName := nil;
|
|
tokenString := nil;
|
|
}
|
|
|
|
(
|
|
tokenName:TOKENREF (ASSIGN tokenString:STRINGLIT)?
|
|
{
|
|
fGrammarMaker.defineToken( tokenName, tokenString);
|
|
}
|
|
(tokenSpecOptions[tokenName])?
|
|
|
|
| tokenString:STRINGLIT
|
|
{
|
|
fGrammarMaker.defineToken( tokenName, tokenString);
|
|
}
|
|
(tokenSpecOptions[tokenString])?
|
|
)
|
|
|
|
SEMI
|
|
|
|
)*
|
|
|
|
RCURLY
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// tokenSpecOptions
|
|
// ----------------------------------------------------------------------------
|
|
tokenSpecOptions[ t: IToken]
|
|
local
|
|
{
|
|
name : IToken;
|
|
value : IToken;
|
|
}
|
|
{
|
|
name := nil;
|
|
value := nil;
|
|
}
|
|
: OPEN
|
|
name=id ASSIGN value=optionValue
|
|
{
|
|
fGrammarMaker.refTokenSpecElemOption( t, name, value);
|
|
}
|
|
(
|
|
name=id ASSIGN value=optionValue
|
|
{
|
|
fGrammarMaker.refTokenSpecElemOption( t, name, value);
|
|
}
|
|
)*
|
|
CLOSE
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// classMemberDecl
|
|
// ----------------------------------------------------------------------------
|
|
classMemberDecl
|
|
:
|
|
"memberDecl"
|
|
memberDecl:ACTION
|
|
{fGrammarMaker.refMemberDecl(memberDecl);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// classMemberDef
|
|
// ----------------------------------------------------------------------------
|
|
classMemberDef
|
|
:
|
|
"memberDef"
|
|
memberDef:ACTION
|
|
{fGrammarMaker.refMemberDef(memberDef);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// rules
|
|
// ----------------------------------------------------------------------------
|
|
rules
|
|
:
|
|
(rule)*
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ruleExceptionBlock
|
|
// ----------------------------------------------------------------------------
|
|
ruleExceptionBlock
|
|
:
|
|
t:"except" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
|
| t:"finally" a:ACTION { fGrammarMaker.RefRuleExHandler( t, a); }
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ruleExceptionBlock
|
|
// ----------------------------------------------------------------------------
|
|
altExceptionBlock
|
|
:
|
|
t:"except" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
|
| t:"finally" a:ACTION { fGrammarMaker.RefAltExHandler( t, a); }
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// rule
|
|
// ----------------------------------------------------------------------------
|
|
rule
|
|
local
|
|
{
|
|
access : AnsiString;
|
|
ag : integer;
|
|
returns : IToken;
|
|
name : IToken;
|
|
}
|
|
{
|
|
access := 'public';
|
|
args := nil;
|
|
name := nil;
|
|
ag := AUTOGEN_NONE;
|
|
}
|
|
:
|
|
// ------------------------------------------------------------
|
|
// Parse rule scope
|
|
// ------------------------------------------------------------
|
|
( "public" { access := 'public'; }
|
|
| "protected" { access := 'protected'; }
|
|
| "private" { access := 'private'; }
|
|
)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Parse rule name
|
|
// ------------------------------------------------------------
|
|
name=id
|
|
|
|
// ------------------------------------------------------------
|
|
// Parse optional BANG operator
|
|
// ------------------------------------------------------------
|
|
// ( BANG { ag := AUTOGEN_BANG;} )?
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional arguments
|
|
// ------------------------------------------------------------
|
|
( args:ARGACTION)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional return type
|
|
// ------------------------------------------------------------
|
|
( "returns" ret:ARGACTION)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Now start the rule definition
|
|
// ------------------------------------------------------------
|
|
{
|
|
fGrammarMaker.defineRuleName( name, access, true, '');
|
|
|
|
if args <> nil then
|
|
fGrammarMaker.refArgAction( args);
|
|
|
|
if ret <> nil then
|
|
fGrammarMaker.refReturnAction( ret);
|
|
}
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional rule options
|
|
// ------------------------------------------------------------
|
|
(ruleOptions)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional rule local variable declarations
|
|
// ------------------------------------------------------------
|
|
(
|
|
"local"
|
|
locals:ACTION
|
|
{fGrammarMaker.refRuleLocals( locals);}
|
|
)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional rule init action
|
|
// ------------------------------------------------------------
|
|
(
|
|
initAction:ACTION
|
|
{fGrammarMaker.refInitAction( initAction);}
|
|
)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Rule block
|
|
// ------------------------------------------------------------
|
|
COLON
|
|
block
|
|
SEMI
|
|
|
|
// ------------------------------------------------------------
|
|
// Optional exception handler
|
|
// ------------------------------------------------------------
|
|
( ruleExceptionBlock)?
|
|
|
|
// ------------------------------------------------------------
|
|
// Finish the rule
|
|
// ------------------------------------------------------------
|
|
{ fGrammarMaker.endRule('');}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// block
|
|
// ----------------------------------------------------------------------------
|
|
block
|
|
{
|
|
INC( fNesting);
|
|
}
|
|
: alternative (OR alternative)* {DEC(fNesting);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// alternative
|
|
// ----------------------------------------------------------------------------
|
|
alternative
|
|
local
|
|
{
|
|
autoGen : boolean;
|
|
}
|
|
{
|
|
autoGen := true;
|
|
}
|
|
:
|
|
// (BANG {autoGen := false;})?
|
|
{fGrammarMaker.beginAlt( autoGen);}
|
|
(elem)*
|
|
(altExceptionBlock)?
|
|
{fGrammarMaker.endAlt;}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// elem
|
|
// ----------------------------------------------------------------------------
|
|
elem
|
|
: element (elementOptions)?
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// element options
|
|
// ----------------------------------------------------------------------------
|
|
elementOptions
|
|
local
|
|
{
|
|
name : IToken;
|
|
value : IToken;
|
|
}
|
|
: OPEN
|
|
name=id ASSIGN value=optionValue
|
|
{
|
|
fGrammarMaker.refElemOption(name,value);
|
|
}
|
|
(
|
|
name=id ASSIGN value=optionValue
|
|
{
|
|
fGrammarMaker.refElemOption(name,value);
|
|
}
|
|
)*
|
|
CLOSE
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// element
|
|
// ----------------------------------------------------------------------------
|
|
element
|
|
local
|
|
{
|
|
assignId : IToken;
|
|
assignLabel : IToken;
|
|
autoGen : integer;
|
|
}
|
|
{
|
|
assignId := nil;
|
|
assignLabel := nil;
|
|
autoGen := AUTOGEN_NONE;
|
|
}
|
|
:
|
|
(
|
|
assignId=id ASSIGN
|
|
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
|
(
|
|
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
|
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
|
|
|
|
tokenRef:TOKENREF (args:ARGACTION)?
|
|
{fGrammarMaker.refToken( assignId, tokenRef, assignLabel, args, false, autoGen, lastInRule);}
|
|
)
|
|
)
|
|
|
|
|
(assignLabel=id COLON {checkEndRule(assignLabel);})?
|
|
(
|
|
ruleRef:RULEREF (args:ARGACTION)? (ag:BANG {autoGen := AUTOGEN_BANG;})?
|
|
{fGrammarMaker.refRule( assignId, ruleRef, assignLabel, args, autoGen);}
|
|
| range[assignLabel]
|
|
| terminal[assignLabel]
|
|
| NOT (notTerminal[assignLabel] | ebnf[ assignLabel, true])
|
|
| ebnf[ assignLabel, false]
|
|
)
|
|
|
|
|
action:ACTION
|
|
{fGrammarMaker.refAction( action);}
|
|
|
|
|
semPred:SEMPRED
|
|
{fGrammarMaker.refSemPred( semPred);}
|
|
|
|
|
tree
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// tree
|
|
// ----------------------------------------------------------------------------
|
|
tree
|
|
: lp:TREE_BEGIN { fGrammarMaker.BeginTree(lp); }
|
|
rootNode { fGrammarMaker.BeginChildList; }
|
|
(element)+ { fGrammarMaker.EndChildList; }
|
|
RPAREN { fGrammarMaker.EndTree; }
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// rootNode
|
|
// ----------------------------------------------------------------------------
|
|
rootNode
|
|
local
|
|
{
|
|
l : IToken;
|
|
}
|
|
: (
|
|
l=id COLON
|
|
{
|
|
CheckEndRule(l);
|
|
}
|
|
)?
|
|
|
|
terminal[l]
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// range
|
|
// ----------------------------------------------------------------------------
|
|
range [pTokenLabel: IToken]
|
|
local
|
|
{
|
|
autoGen: integer;
|
|
}
|
|
{
|
|
autoGen := AUTOGEN_NONE;
|
|
}
|
|
:
|
|
crLeft:CHARLIT
|
|
RANGE
|
|
crRight:CHARLIT
|
|
(BANG {autoGen := AUTOGEN_BANG;} )?
|
|
{fGrammarMaker.refCharRange( crLeft, crRight, pTokenLabel, autoGen, lastInRule);}
|
|
|
|
|
(trLeft:TOKENREF | trLeft:STRINGLIT)
|
|
RANGE
|
|
(trRight:TOKENREF | trRight:STRINGLIT)
|
|
autoGen=astTypeSpec
|
|
{fGrammarMaker.refTokenRange( trLeft, trRight, pTokenLabel, autoGen, lastInRule);}
|
|
;
|
|
// ----------------------------------------------------------------------------
|
|
// terminal
|
|
// ----------------------------------------------------------------------------
|
|
terminal [pTokenLabel: IToken]
|
|
local
|
|
{
|
|
autoGen : integer;
|
|
}
|
|
{
|
|
autoGen := AUTOGEN_NONE;
|
|
aa := nil;
|
|
}
|
|
:
|
|
cl:CHARLIT
|
|
(BANG {autoGen := AUTOGEN_BANG;} )?
|
|
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, false, autoGen, lastInRule);}
|
|
|
|
|
tr:TOKENREF
|
|
autoGen=astTypeSpec
|
|
(aa:ARGACTION)?
|
|
{fGrammarMaker.refToken( nil, tr, pTokenLabel, aa, false, autoGen, lastInRule);}
|
|
|
|
|
sl:STRINGLIT
|
|
autoGen=astTypeSpec
|
|
{fGrammarMaker.refStringLiteral( sl, pTokenLabel, autoGen, lastInRule);}
|
|
|
|
|
wc:WILDCARD
|
|
autogen=astTypeSpec
|
|
{fGrammarMaker.refWildCard( wc, pTokenLabel, autoGen);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// notTerminal
|
|
// ----------------------------------------------------------------------------
|
|
notTerminal [pTokenLabel: IToken]
|
|
local
|
|
{
|
|
autoGen : integer;
|
|
}
|
|
{
|
|
autoGen := AUTOGEN_NONE;
|
|
}
|
|
:
|
|
cl:CHARLIT
|
|
(BANG {autoGen := AUTOGEN_BANG;} )?
|
|
{fGrammarMaker.refCharLiteral( cl, pTokenLabel, true, autoGen, lastInRule);}
|
|
|
|
|
tr:TOKENREF
|
|
autoGen=astTypeSpec
|
|
{fGrammarMaker.refToken( nil, tr, pTokenLabel, nil, true, autoGen, lastInRule);}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ebnf
|
|
// ----------------------------------------------------------------------------
|
|
ebnf [pTokenLabel: IToken; pTokenNot: boolean]
|
|
:
|
|
lp:LPAREN
|
|
{fGrammarMaker.beginSubrule( pTokenLabel, lp, pTokenNot);}
|
|
|
|
(
|
|
// ---------------------------------------------------------
|
|
// 2nd alt and optional branch ambig due to linear approx
|
|
// LL(2) issue. COLON ACTION matched correctly in 2nd alt.
|
|
// ---------------------------------------------------------
|
|
options
|
|
{
|
|
warnWhenFollowAmbig = false;
|
|
}
|
|
:
|
|
subRuleOptions
|
|
(aa:ACTION {fGrammarMaker.refInitAction(aa);} )?
|
|
COLON
|
|
|
|
|
aa:ACTION {fGrammarMaker.refInitAction(aa);}
|
|
COLON
|
|
)?
|
|
|
|
|
|
block
|
|
RPAREN
|
|
|
|
(
|
|
( QUEST { fGrammarMaker.optionalSubrule; }
|
|
| STAR { fGrammarMaker.zeroOrMoreSubrule; }
|
|
| PLUS { fGrammarMaker.oneOrMoreSubrule; }
|
|
| AT { fGrammarMaker.nmSubrule; }
|
|
LPAREN
|
|
(
|
|
m:INTEGER { fGrammarMaker.refRangeLow( StrToInt(m.TokenText)); }
|
|
(
|
|
COMMA { fGrammarMaker.refRangeHigh( maxint); }
|
|
(
|
|
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
|
)?
|
|
)?
|
|
|
|
|
COMMA
|
|
n:INTEGER { fGrammarMaker.refRangeHigh(StrToInt(n.TokenText)); }
|
|
)
|
|
RPAREN
|
|
| IMPLIES {fGrammarMaker.synPred; }
|
|
)?
|
|
|
|
// ( BANG {fGrammarMaker.noASTSubrule;} )?
|
|
)
|
|
|
|
{fGrammarMaker.endSubRule;}
|
|
;
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// optionValue
|
|
// ----------------------------------------------------------------------------
|
|
optionValue returns [IToken]
|
|
:
|
|
result=qualifiedId
|
|
| result:STRINGLIT
|
|
| result:CHARLIT
|
|
| result:INTEGER
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// subruleOptions
|
|
// ----------------------------------------------------------------------------
|
|
subruleOptions
|
|
local
|
|
{
|
|
optName : IToken;
|
|
optValue : IToken;
|
|
}
|
|
:
|
|
OPTIONS
|
|
(
|
|
optName = id
|
|
ASSIGN
|
|
optValue = optionValue
|
|
SEMI
|
|
{fGrammarMaker.setSubruleOption( optName, optValue);}
|
|
)*
|
|
|
|
RCURLY
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// ruleOptions
|
|
// ----------------------------------------------------------------------------
|
|
ruleOptions
|
|
local
|
|
{
|
|
optName : IToken;
|
|
optValue : IToken;
|
|
}
|
|
:
|
|
OPTIONS
|
|
(
|
|
optName = id
|
|
ASSIGN
|
|
optValue = optionValue
|
|
SEMI
|
|
{fGrammarMaker.setRuleOption( optName, optValue);}
|
|
)*
|
|
|
|
RCURLY
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// astTypeSpec
|
|
// ----------------------------------------------------------------------------
|
|
astTypeSpec returns [integer]
|
|
{
|
|
result := AUTOGEN_NONE;
|
|
}
|
|
:
|
|
( CARET { result := AUTOGEN_CARET; }
|
|
| BANG { result := AUTOGEN_BANG; }
|
|
)?
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// qualifiedId
|
|
// ----------------------------------------------------------------------------
|
|
qualifiedId returns [IToken]
|
|
local
|
|
{
|
|
buf : AnsiString;
|
|
a : IToken;
|
|
}
|
|
:
|
|
a=id { buf := a.TokenText; }
|
|
(
|
|
WILDCARD a=id { buf := buf + '.' + a.TokenText; }
|
|
)*
|
|
{
|
|
// -----------------------------------------------------------
|
|
// Can either TOKENREF or RULEREF. Should really create QID or
|
|
// something else instead.
|
|
// -----------------------------------------------------------
|
|
result := TToken.Create( TT_TOKENREF, buf);
|
|
result.TokenLine := a.TokenLine;
|
|
result.TokenColumn := a.TokenColumn;
|
|
}
|
|
;
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// id
|
|
// ----------------------------------------------------------------------------
|
|
id returns [IToken]
|
|
:
|
|
result:TOKENREF
|
|
| result:RULEREF
|
|
;
|
|
|
|
memberdef
|
|
{
|
|
// ============================================================================
|
|
// Constructor
|
|
// ============================================================================
|
|
constructor TDpgParser.Create( pParserState : IParserState;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString);
|
|
begin
|
|
inherited Create( pParserState, 2);
|
|
|
|
fGrammarMaker := pGrammarMaker;
|
|
fExchangeDir := pExchangeDir;
|
|
fTool := pTool;
|
|
fNesting := 0;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// Constructor
|
|
// ============================================================================
|
|
constructor TDpgParser.Create( pTokenBuffer : ITokenBuffer;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString);
|
|
begin
|
|
inherited Create( pTokenBuffer, 2);
|
|
|
|
fGrammarMaker := pGrammarMaker;
|
|
fExchangeDir := pExchangeDir;
|
|
fTool := pTool;
|
|
fNesting := 0;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// Constructor
|
|
// ============================================================================
|
|
constructor TDpgParser.Create( pTokenStream : ITokenStream;
|
|
pGrammarMaker : IGrammarBehavior;
|
|
pTool : ITool;
|
|
pExchangeDir : AnsiString);
|
|
begin
|
|
inherited Create( pTokenStream, 2);
|
|
|
|
fGrammarMaker := pGrammarMaker;
|
|
fExchangeDir := pExchangeDir;
|
|
fTool := pTool;
|
|
fNesting := 0;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// Destructor
|
|
// ============================================================================
|
|
destructor TDpgParser.Destroy;
|
|
begin
|
|
fGrammarMaker := nil;
|
|
fTool := nil;
|
|
|
|
inherited;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// lastInRule
|
|
// ============================================================================
|
|
function TDpgParser.lastInRule: boolean;
|
|
begin
|
|
if (fNesting = 0) and (LA(1) in [TT_SEMI, TT_OR])
|
|
then result := true
|
|
else result := false;
|
|
end;
|
|
|
|
// ============================================================================
|
|
// checkEndRule
|
|
// ============================================================================
|
|
procedure TDpgParser.checkEndRule( pToken: IToken);
|
|
begin
|
|
if pToken <> nil then
|
|
if pToken.TokenColumn = 1 then
|
|
fTool.Warning('Did you forget to close the previous rule?',
|
|
InputState.FileName,
|
|
pToken.TokenLine,
|
|
pToken.TokenColumn);
|
|
end;
|
|
}
|
|
|
|
|