Home | History | Annotate | Download | only in Delphi
      1 /* [The "BSD license"]
      2  Copyright (c) 2008 Erik van Bilsen
      3  Copyright (c) 2007-2008 Johannes Luber
      4  Copyright (c) 2005-2007 Kunle Odutola
      5  Copyright (c) 2005-2006 Terence Parr
      6  All rights reserved.
      7 
      8  Redistribution and use in source and binary forms, with or without
      9  modification, are permitted provided that the following conditions
     10  are met:
     11  1. Redistributions of source code must retain the above copyright
     12     notice, this list of conditions and the following disclaimer.
     13  2. Redistributions in binary form must reproduce the above copyright
     14     notice, this list of conditions and the following disclaimer in the
     15     documentation and/or other materials provided with the distribution.
     16  3. The name of the author may not be used to endorse or promote products
     17     derived from this software without specific prior written permission.
     18 
     19  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     20  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     21  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     22  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     23  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     24  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     28  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29 */
     30 group Delphi;
     31 
     32 csharpTypeInitMap ::= [
     33   "int":"0",
     34   "uint":"0",
     35   "long":"0",
     36   "ulong":"0",
     37   "float":"0.0",
     38   "double":"0.0",
     39   "bool":"False",
     40   "byte":"0",
     41   "sbyte":"0",
     42   "short":"0",
     43   "ushort":"0",
     44   "char":"#0",
     45   "string":"''",
     46   "String":"''",
     47   default:"nil" // anything other than an atomic type
     48 ]
     49 
     50 /** The overall file structure of a recognizer; stores methods for rules
     51  *  and cyclic DFAs plus support code.
     52  *  LEXER (Boolean): should we generate lexer code?
     53  *  PARSER (Boolean): should we generate parser code?
     54  *  TREE_PARSER (Boolean): should we generate tree parser code?
     55  *  actionScope (String): 'lexer', 'parser', 'tree_parser' or custom scope
     56  *  actions (HashMap):
     57  *  docComment (String): document comment
     58  *  recognizer (Object): recognizer class generator
     59  *  name (String): name of grammar
     60  *  tokens (HashMap<name: String, type: Integer>):
     61  *  tokenNames:
     62  *  rules:
     63  *  cyclicDFAs:
     64  *  bitsets:
     65  *  buildTemplate (Boolean): should we generate a string template?
     66  *  buildAST (Boolean): should we generate an AST?
     67  *  rewriteMode (Boolean): are we rewriteing nodes?
     68  *  profile (Boolean):
     69  *  backtracking (Boolean): backtracking mode?
     70  *  synpreds (): syntactic predicates
     71  *  memoize (Boolean): should we memoize?
     72  *  numRules (Integer): number of rules
     73  *  fileName (String): fully qualified name of original .g file
     74  *  ANTLRVersion (String): ANTLR version in Major.Minor.Build format
     75  *  generatedTimestamp (String): date/time when the file is generated
     76  *  trace (Boolean): should we trace input/output?
     77  *  scopes:
     78  *  superClass (String): name of base class, or empty string
     79  *  literals:
     80  */
     81 outputFile(LEXER,PARSER,TREE_PARSER, actionScope, actions,
     82            docComment, recognizer,
     83            name, tokens, tokenNames, rules, cyclicDFAs,
     84      bitsets, buildTemplate, buildAST, rewriteMode, profile,
     85      backtracking, synpreds, memoize, numRules,
     86      fileName, ANTLRVersion, generatedTimestamp, trace,
     87      scopes, superClass, literals) ::=
     88 <<
     89 unit <name>;
     90 
     91 {$HINTS OFF}
     92 
     93 // $ANTLR <ANTLRVersion> <fileName> <generatedTimestamp>
     94 
     95 <actions.(actionScope).header>
     96 
     97 interface
     98 
     99 <@imports>
    100 uses<\n>
    101 <@end>
    102   <actions.(actionScope).usesInterface>
    103 <if(TREE_PARSER)>
    104   Antlr.Runtime.Tree,<\n>
    105 <endif>
    106   Antlr.Runtime,
    107   Antlr.Runtime.Collections,
    108   Antlr.Runtime.Tools;
    109 
    110 <docComment>
    111 <recognizer>
    112 >>
    113 
    114 /** Generates source code for the lexer class
    115  * grammar (Grammar object)
    116  */
    117 lexer(grammar, name, tokens, scopes, rules, numRules, labelType="Token",
    118       filterMode, superClass="Lexer") ::= <<
    119 type
    120   I<grammar.recognizerName> = interface(I<@superClassName><superClass><@end>)
    121   end;
    122 
    123   T<grammar.recognizerName> = class(T<@superClassName><superClass><@end>, I<grammar.recognizerName>)
    124   strict private
    125     FCnt: array [0..<grammar.numberOfDecisions>] of Byte;
    126     FLA: array [0..<grammar.numberOfDecisions>, 0..255] of Integer;
    127     FException: ERecognitionException;
    128     procedure InitializeCyclicDFAs;
    129   <cyclicDFAs:cyclicDFADeclaration()>
    130   public
    131     const
    132       <tokens:{<it.name> = <it.type>;}; separator="\n">
    133     <scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
    134   strict private
    135     <actions.(actionScope).memberDeclarations>
    136   public
    137     // delegates
    138     <grammar.delegates: {g|<g:delegateName()>: I<superClass>; {<g.recognizerName>}}; separator="\n">
    139   public
    140     // delegators
    141     <grammar.delegators: {g|<g:delegateName()>: Pointer; {<g.recognizerName>}}; separator="\n">
    142     <last(grammar.delegators):{g|gParent: Pointer; {<g.recognizerName>}}>
    143   protected
    144     { IBaseRecognizer }
    145     function GetGrammarFileName: String; override;
    146 <if(filterMode)>
    147     function AlreadyParsedRule(const Input: IIntStream;
    148       const RuleIndex: Integer): Boolean; override;
    149     procedure Memoize(const Input: IIntStream; const RuleIndex,
    150       RuleStartIndex: Integer); override;
    151   protected
    152     { ILexer }
    153     function NextToken: IToken; override;<\n>
    154 <endif>
    155   protected
    156     { ILexer }
    157     procedure DoTokens; override;
    158   public
    159     constructor Create; overload;
    160     constructor Create(const AInput: ICharStream<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>); overload;
    161     constructor Create(const AInput: ICharStream; const AState: IRecognizerSharedState<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>); overload;
    162 
    163     <rules: {r | <if(!r.ruleDescriptor.isSynPred)><lexerRuleDeclaration(r)><endif>}>
    164     <synpreds:{p | <lexerSynpredDeclaration(p)>}; separator="\n">
    165   end;
    166 
    167 implementation
    168 
    169 uses
    170   <grammar.delegates: {g|<g.recognizerName>,}; separator="\n">
    171   <grammar.delegators: {g|<g.recognizerName>,}; separator="\n">
    172   <actions.(actionScope).usesImplementation>
    173   SysUtils,
    174   StrUtils,
    175   Math;
    176 
    177 { T<grammar.recognizerName> }
    178 
    179 constructor T<grammar.recognizerName>.Create;
    180 begin
    181   InitializeCyclicDFAs;
    182 end;
    183 
    184 constructor T<grammar.recognizerName>.Create(const AInput: ICharStream<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>);
    185 begin
    186   Create(AInput, nil<grammar.delegators:{g|, A<g:delegateName()>}>);
    187 end;
    188 
    189 constructor T<grammar.recognizerName>.Create(const AInput: ICharStream; const AState: IRecognizerSharedState<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>);
    190 begin
    191   inherited Create(AInput, AState);
    192   InitializeCyclicDFAs; { TODO: Necessary in Delphi??? Not removed yet. }
    193   <if(memoize)>
    194   <if(grammar.grammarIsRoot)>
    195   State.RuleMemoCount := <numRules>+1;<\n> <! index from 1..n !>
    196   <endif>
    197   <endif>
    198   <grammar.directDelegates:
    199    {g|<g:delegateName()> := T<g.recognizerName>.Create(AInput, State<trunc(g.delegators):{p|, <p:delegateName()>}>, Self);}; separator="\n">
    200   <grammar.delegators:
    201    {g|<g:delegateName()> := Pointer(A<g:delegateName()>);}; separator="\n">
    202   <last(grammar.delegators):{g|gParent := Pointer(A<g:delegateName()>);}>
    203   <actions.(actionScope).memberInitializations>
    204 end;
    205 <actions.(actionScope).memberImplementations>
    206 function T<grammar.recognizerName>.GetGrammarFileName: String;
    207 begin
    208   Result := '<fileName>';
    209 end;
    210 
    211 <if(filterMode)>
    212 <filteringNextToken()>
    213 <endif>
    214 
    215 <rules; separator="\n\n">
    216 <synpreds:{p | <lexerSynpred(p)>}>
    217 
    218 procedure T<grammar.recognizerName>.InitializeCyclicDFAs;
    219 begin
    220   <cyclicDFAs:{dfa | FDFA<dfa.decisionNumber> := TDFA<dfa.decisionNumber>.Create(Self<@debugAddition()>);}; separator="\n">
    221   <cyclicDFAs:{dfa | <if(dfa.specialStateSTs)>FDFA<dfa.decisionNumber>.SpecialStateTransitionHandler := DFA<dfa.decisionNumber>_SpecialStateTransition;<endif>}; separator="\n">
    222 end;
    223 
    224 <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
    225 end.>>
    226 
    227 lexerRuleDeclaration(rule) ::= <<
    228 procedure m<rule.ruleName>(<rule.ruleDescriptor.parameterScope:parameterScope(scope=rule)>);<\n>
    229 >>
    230 
    231 /** A override of Lexer.nextToken() that backtracks over mTokens() looking
    232  *  for matches.  No error can be generated upon error; just rewind, consume
    233  *  a token and then try again.  backtracking needs to be set as well.
    234  *
    235  *  Make rule memoization happen only at levels above 1 as we start mTokens
    236  *  at backtracking==1.
    237  */
    238 filteringNextToken() ::= <<
    239 function T<grammar.recognizerName>.NextToken: IToken;
    240 var
    241   M: Integer;
    242 begin
    243   while (True) do
    244   begin
    245     if (Input.LA(1) = Integer(cscEOF)) then
    246       Exit(TToken.EOF_TOKEN);
    247 
    248     State.Token := nil;
    249     State.Channel := TToken.DEFAULT_CHANNEL;
    250     State.TokenStartCharIndex := Input.Index;
    251     State.TokenStartCharPositionInLine := Input.CharPositionInLine;
    252     State.TokenStartLine := Input.Line;
    253     State.Text := '';
    254     try
    255       M := Input.Mark();
    256       State.Backtracking := 1; <! means we won't throw slow exception !>
    257       State.Failed := False;
    258       mTokens();
    259       State.Backtracking := 0;
    260 <!
    261       mTokens backtracks with synpred at backtracking==2
    262             and we set the synpredgate to allow actions at level 1.
    263 !>
    264       if (State.Failed) then
    265       begin
    266         Input.Rewind(M);
    267         Input.Consume; <! // advance one char and try again !>
    268       end
    269       else
    270       begin
    271         Emit;
    272         Exit(State.Token);
    273       end;
    274     except
    275       on RE: ERecognitionException do
    276       begin
    277         // shouldn't happen in backtracking mode, but...
    278         ReportError(RE);
    279         Recover(RE);
    280       end;
    281     end;
    282   end;
    283 end;
    284 
    285 function T<grammar.recognizerName>.AlreadyParsedRule(const Input: IIntStream;
    286   const RuleIndex: Integer): Boolean;
    287 begin
    288   if (State.Backtracking > 1) then
    289     Result := inherited AlreadyParsedRule(Input, RuleIndex)
    290   else
    291     Result := False;
    292 end;
    293 
    294 procedure T<grammar.recognizerName>.Memoize(const Input: IIntStream; const RuleIndex,
    295   RuleStartIndex: Integer);
    296 begin
    297   if (State.Backtracking > 1) then
    298     inherited Memoize(Input, RuleIndex, RuleStartIndex);
    299 end;
    300 
    301 >>
    302 
    303 filteringActionGate() ::= "(State.Backtracking = 1)"
    304 
    305 /** How to generate a parser */
    306 genericParser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
    307               bitsets, inputStreamType, superClass, filterMode,
    308               ASTLabelType="ANTLRInterface", labelType, members, rewriteElementType) ::= <<
    309 type
    310   <rules: {r | <genericParserRuleReturnType(rule=r, ruleDescriptor=r.ruleDescriptor)>}>
    311   I<grammar.recognizerName> = interface(I<@superClassName><superClass><@end>)
    312     <rules: {r | <genericParserRuleInterface(rule=r, ruleDescriptor=r.ruleDescriptor)>}>
    313   end;
    314 
    315   T<grammar.recognizerName> = class(T<@superClassName><superClass><@end>, I<grammar.recognizerName>)
    316 <if(grammar.grammarIsRoot)>
    317   public
    318     const
    319       TOKEN_NAMES: array [0..<length(tokenNames)>+3] of String = (
    320         '\<invalid>',
    321         '\<EOR>',
    322         '\<DOWN>',
    323         '\<UP>',
    324         <tokenNames; separator=",\n">);<\n>
    325 <endif>
    326   public
    327     const
    328       <tokens:{<it.name> = <it.type>;}; separator="\n">
    329   public
    330     // delegates
    331     <grammar.delegates: {g|<g:delegateName()>: I<superClass>; {<g.recognizerName>}}; separator="\n">
    332   public
    333     // delegators
    334     <grammar.delegators: {g|<g:delegateName()>: Pointer; {<g.recognizerName>}}; separator="\n">
    335     <last(grammar.delegators):{g|gParent: Pointer; {<g.recognizerName>}}>
    336 
    337     <scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScopeDeclaration(scope=it)><endif>}>
    338 <@members>
    339     <! WARNING. bug in ST: this is cut-n-paste into Dbg.stg !>
    340   public
    341     constructor Create(const AInput: <inputStreamType><grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>); overload;
    342     constructor Create(const AInput: <inputStreamType>; const AState: IRecognizerSharedState<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>); overload;
    343 <@end>
    344   protected
    345     { IBaseRecognizer }
    346     function GetTokenNames: TStringArray; override;
    347     function GetGrammarFileName: String; override;
    348   strict private
    349     <actions.(actionScope).memberDeclarations>
    350   <rules: {r | <genericParserRuleDeclaration(rule=r, ruleDescriptor=r.ruleDescriptor)>}>
    351 
    352 <! generate rule/method definitions for imported rules so they
    353    appear to be defined in this recognizer. !>
    354     // Delegated rules
    355     <grammar.delegatedRules:{ruleDescriptor| <delegatedRuleDeclaration(ruleDescriptor)>}>
    356 
    357     <synpreds:{p | <synpredDeclaration(p)>}; separator="\n">
    358   <cyclicDFAs:cyclicDFADeclaration()>
    359   strict private
    360     FException: ERecognitionException;
    361     FLA: array [0..<grammar.numberOfDecisions>, 0..255] of Integer;
    362     FCnt: array [0..<grammar.numberOfDecisions>] of Byte;
    363     procedure InitializeCyclicDFAs;
    364 <if(bitsets)>
    365   public
    366     class var
    367       <bitsets:bitsetDecl(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>})>
    368   public
    369     class procedure InitializeBitsets; static;<\n>
    370 <endif>
    371   end;
    372 
    373 implementation
    374 
    375 uses
    376   <grammar.delegates: {g|<g.recognizerName>,}; separator="\n">
    377   <grammar.delegators: {g|<g.recognizerName>,}; separator="\n">
    378   <actions.(actionScope).usesImplementation>
    379   SysUtils,
    380   StrUtils,
    381   Math;
    382 
    383 { T<grammar.recognizerName> }
    384 
    385 constructor T<grammar.recognizerName>.Create(const AInput: <inputStreamType><grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>);
    386 begin
    387   Create(AInput, TRecognizerSharedState.Create<grammar.delegators:{g|, A<g:delegateName()>}>);
    388 end;
    389 
    390 constructor T<grammar.recognizerName>.Create(const AInput: <inputStreamType>;
    391   const AState: IRecognizerSharedState<grammar.delegators:{g|; const A<g:delegateName()>: IBaseRecognizer{<g.recognizerName>}}>);
    392 begin
    393   inherited Create(AInput, AState);
    394   <@membersConstructor>
    395   <@end>
    396   <parserCtorBody()>
    397   <grammar.directDelegates:{g|<g:delegateName()> := T<g.recognizerName>.Create(Input, State<trunc(g.delegators):{p|, <p:delegateName()>}>, Self);}; separator="\n">
    398   <grammar.indirectDelegates:{g | <g:delegateName()> := <g.delegator:delegateName()>.<g:delegateName()>;}; separator="\n">
    399   <last(grammar.delegators):{g|gParent := Pointer(A<g:delegateName()>);}>
    400   <rules: {r | <ruleAttributeScopeInit(scope=r.ruleDescriptor.ruleScope)>}>
    401   <scopes:{<if(it.isDynamicGlobalScope)><globalAttributeScope(scope=it)><endif>}>
    402   <actions.(actionScope).memberInitializations>
    403 end;
    404 <actions.(actionScope).memberImplementations>
    405 
    406 <grammar.delegatedRules:{ruleDescriptor| <delegatedRuleImplementation(ruleDescriptor)>}; separator="\n">
    407 procedure T<grammar.recognizerName>.InitializeCyclicDFAs;
    408 begin
    409   <cyclicDFAs:{dfa | FDFA<dfa.decisionNumber> := TDFA<dfa.decisionNumber>.Create(Self);}; separator="\n">
    410   <cyclicDFAs:{dfa | <if(dfa.specialStateSTs)>FDFA<dfa.decisionNumber>.SpecialStateTransitionHandler := DFA<dfa.decisionNumber>_SpecialStateTransition;<endif>}; separator="\n">
    411 end;
    412 
    413 <if(bitsets)>
    414 class procedure T<grammar.recognizerName>.InitializeBitsets;
    415 begin
    416   <bitsets:bitset(name={FOLLOW_<it.name>_in_<it.inName><it.tokenIndex>}, words64=it.bits)>
    417 end;
    418 <endif>
    419 
    420 <@membersImplementation>
    421  <@end>
    422 
    423 function T<grammar.recognizerName>.GetTokenNames: TStringArray;
    424 var
    425   I: Integer;
    426 begin
    427   SetLength(Result,Length(T<grammar.composite.rootGrammar.recognizerName>.TOKEN_NAMES));
    428   for I := 0 to Length(T<grammar.composite.rootGrammar.recognizerName>.TOKEN_NAMES) - 1 do
    429     Result[I] := T<grammar.composite.rootGrammar.recognizerName>.TOKEN_NAMES[I];
    430 end;
    431 
    432 function T<grammar.recognizerName>.GetGrammarFileName: String;
    433 begin
    434   Result := '<fileName>';
    435 end;
    436 
    437 <rules; separator="\n\n">
    438 <synpreds:{p | <synpred(p)>}>
    439 
    440 <cyclicDFAs:cyclicDFA()> <! dump tables for all DFA !>
    441 <if(bitsets)>
    442 initialization
    443   T<grammar.recognizerName>.InitializeBitsets;<\n>
    444 <endif>
    445 end.>>
    446 
    447 delegatedRuleDeclaration(ruleDescriptor) ::= <<
    448 <if(ruleDescriptor.hasMultipleReturnValues)>
    449 function <ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): I<returnType()>;<\n>
    450 <else>
    451 <if(ruleDescriptor.hasSingleReturnValue)>
    452 function <ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): <returnType()>;<\n>
    453 <else>
    454 procedure <ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>);<\n>
    455 <endif>
    456 <endif>
    457 >>
    458 
    459 delegatedRuleImplementation(ruleDescriptor) ::= <<
    460 <if(ruleDescriptor.hasMultipleReturnValues)>
    461 function T<grammar.recognizerName>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): I<returnType()>;<\n>
    462 <else>
    463 <if(ruleDescriptor.hasSingleReturnValue)>
    464 function T<grammar.recognizerName>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): <returnType()>;<\n>
    465 <else>
    466 procedure T<grammar.recognizerName>.<ruleDescriptor.name>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>);<\n>
    467 <endif>
    468 <endif>
    469 begin
    470   <if(ruleDescriptor.hasReturnValue)>Result :=<endif> T<ruleDescriptor.grammar.recognizerName>(<ruleDescriptor.grammar:delegateName()>.Implementor).<ruleDescriptor.name>(<ruleDescriptor.parameterScope.attributes:{a|<a.name>}; separator=", ">);
    471 end;
    472 
    473 >>
    474 
    475 parserCtorBody() ::= <<
    476 InitializeCyclicDFAs;
    477 <if(memoize)>
    478 <if(grammar.grammarIsRoot)>
    479 State.RuleMemoCount := <length(grammar.allImportedRules)>+1;<\n> <! index from 1..n !>
    480 <endif>
    481 <endif>
    482 <grammar.delegators: {g|<g:delegateName()> := Pointer(A<g:delegateName()>);}; separator="\n">
    483 >>
    484 
    485 parser(grammar, name, scopes, tokens, tokenNames, rules, numRules, bitsets, ASTLabelType, superClass="Parser", labelType="Token", members={<actions.parser.members>}) ::= <<
    486 <genericParser(inputStreamType="ITokenStream", rewriteElementType="Token", ...)>
    487 >>
    488 
    489 /** How to generate a tree parser; same as parser except the input
    490  *  stream is a different type.
    491  */
    492 treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules, numRules, bitsets, labelType={<ASTLabelType>}, ASTLabelType="object", superClass="TreeParser", members={<actions.treeparser.members>}, filterMode) ::= <<
    493 <genericParser(inputStreamType="ITreeNodeStream", rewriteElementType="Node", ...)>
    494 >>
    495 
    496 /** A simpler version of a rule template that is specific to the imaginary
    497  *  rules created for syntactic predicates.  As they never have return values
    498  *  nor parameters etc..., just give simplest possible method.  Don't do
    499  *  any of the normal memoization stuff in here either; it's a waste.
    500  *  As predicates cannot be inlined into the invoking rule, they need to
    501  *  be in a rule by themselves.
    502  */
    503 synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock) ::=
    504 <<
    505 // $ANTLR start "<ruleName>"
    506 procedure T<grammar.recognizerName>.<ruleName>_fragment(<ruleDescriptor.parameterScope:parameterScope(scope=it)>);
    507 var
    508   Alt: array [0..<grammar.numberOfDecisions>] of Integer;
    509   <ruleLabelDefVars()>
    510 begin
    511   <ruleLabelDefs()>
    512 <if(trace)>
    513   TraceIn('<ruleName>_fragment', <ruleDescriptor.index>);
    514   try
    515     <block>
    516   finally
    517     TraceOut('<ruleName>_fragment', <ruleDescriptor.index>);
    518   end;
    519 <else>
    520   <block>
    521 <endif>
    522 end;
    523 // $ANTLR end "<ruleName>"
    524 >>
    525 
    526 synpredDecls(name) ::= <<
    527 SynPredPointer <name>;<\n>
    528 >>
    529 
    530 synpred(name) ::= <<
    531 
    532 function T<grammar.recognizerName>.<name>: Boolean;
    533 var
    534   Start: Integer;
    535   Success: Boolean;
    536 begin
    537   State.Backtracking := State.Backtracking + 1;
    538   <@start()>
    539   Start := Input.Mark;
    540   try
    541     <name>_fragment(); // can never throw exception
    542   except
    543     on RE: ERecognitionException do
    544       WriteLn('Impossible: ' + RE.ToString);
    545   end;
    546   Success := not State.Failed;
    547   Input.Rewind(Start);
    548   <@stop()>
    549   State.Backtracking := State.Backtracking - 1;
    550   State.Failed := False;
    551   Result := Success;
    552 end;<\n>
    553 >>
    554 
    555 lexerSynpred(name) ::= <<
    556 <synpred(name)>
    557 >>
    558 
    559 lexerSynpredDeclaration(name) ::= <<
    560 function <name>: Boolean;
    561 procedure <name>_fragment;
    562 >>
    563 
    564 synpredDeclaration(name) ::= <<
    565 function <name>: Boolean;
    566 procedure <name>_fragment;
    567 >>
    568 
    569 ruleMemoization(name) ::= <<
    570 <if(memoize)>
    571 if ((State.Backtracking > 0) and AlreadyParsedRule(Input, <ruleDescriptor.index>)) then
    572   Exit(<ruleReturnValue()>);
    573 <endif>
    574 >>
    575 
    576 /** How to test for failure and return from rule */
    577 checkRuleBacktrackFailure() ::= <<
    578 <if(backtracking)><\n>if (State.Failed) then Exit(<ruleReturnValue()>);<\n><endif>
    579 >>
    580 
    581 /** This rule has failed, exit indicating failure during backtrack */
    582 ruleBacktrackFailure() ::= <<
    583 <if(backtracking)>if (State.Backtracking > 0) then
    584 begin
    585   State.Failed := True;
    586   Exit(<ruleReturnValue()>);
    587 end;<endif>
    588 >>
    589 
    590 genericParserRuleDeclaration(rule, ruleDescriptor) ::= <<
    591 <if(ruleDescriptor.isSynPred)>
    592 <else>
    593 <ruleAttributeScopeDeclaration(scope=ruleDescriptor.ruleScope)>
    594 <returnScopeDeclaration(scope=ruleDescriptor.returnScope)>
    595 public
    596 <if(ruleDescriptor.hasMultipleReturnValues)>
    597   function <rule.ruleName>: I<returnType()>;<\n>
    598 <else>
    599 <if(ruleDescriptor.hasSingleReturnValue)>
    600   function <rule.ruleName>: <returnType()>;<\n>
    601 <else>
    602   procedure <rule.ruleName>;<\n>
    603 <endif>
    604 <endif>
    605 <endif>
    606 >>
    607 
    608 genericParserRuleInterface(rule, ruleDescriptor) ::= <<
    609 <if(ruleDescriptor.isSynPred)>
    610 <else>
    611 <if(ruleDescriptor.hasMultipleReturnValues)>
    612 function <rule.ruleName>: I<returnType()>;<\n>
    613 <else>
    614 <if(ruleDescriptor.hasSingleReturnValue)>
    615 function <rule.ruleName>: <returnType()>;<\n>
    616 <else>
    617 procedure <rule.ruleName>;<\n>
    618 <endif>
    619 <endif>
    620 <endif>
    621 >>
    622 
    623 genericParserRuleReturnType(rule, ruleDescriptor) ::= <<
    624 <if(ruleDescriptor.hasMultipleReturnValues)>
    625 <if(ruleDescriptor.isSynPred)>
    626 <else>
    627 I<returnType()> = interface(I<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope)
    628 end;<\n>
    629 <endif>
    630 <endif>
    631 >>
    632 
    633 /** How to generate code for a rule.  This includes any return type
    634  *  data aggregates required for multiple return values.
    635  */
    636 rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize) ::= <<
    637 <ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
    638 <returnScope(scope=ruleDescriptor.returnScope)>
    639 
    640 // $ANTLR start "<ruleName>"
    641 (* <fileName>:<description> *)
    642 <if(ruleDescriptor.hasMultipleReturnValues)>
    643 function T<grammar.recognizerName>.<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): I<returnType()>;
    644 <else>
    645 <if(ruleDescriptor.hasSingleReturnValue)>
    646 function T<grammar.recognizerName>.<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>): <returnType()>;
    647 <else>
    648 procedure T<grammar.recognizerName>.<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>);
    649 <endif>
    650 <endif>
    651 
    652 var
    653 <ruleDescriptor.actions.vars>
    654   Locals: TLocalStorage;
    655 <if(ruleDescriptor.hasMultipleReturnValues)>
    656   RetVal: I<returnType()>;<\n>
    657 <else>
    658 <if(ruleDescriptor.hasSingleReturnValue)>
    659   RetVal: <returnType()>;<\n>
    660 <else>
    661 <endif>
    662 <endif>
    663   Alt: array [0..<grammar.numberOfDecisions>] of Integer;
    664   <ruleDeclarationVars()>
    665   <ruleLabelDefVars()>
    666 begin
    667   Locals.Initialize;
    668   try
    669     <if(trace)>TraceIn('<ruleName>', <ruleDescriptor.index>);<endif>
    670     <ruleScopeSetUp()>
    671     <ruleDeclarations()>
    672     <ruleLabelDefs()>
    673     <ruleDescriptor.actions.init>
    674     <@preamble()>
    675     try
    676       try
    677         <ruleMemoization(name=ruleName)>
    678         <block>
    679         <ruleCleanUp()>
    680         <(ruleDescriptor.actions.after):execAction()>
    681 <if(exceptions)>
    682         <exceptions:{e|<catch(decl=e.decl,action=e.action)><\n>}>
    683 <else>
    684 <if(!emptyRule)>
    685 <if(actions.(actionScope).rulecatch)>
    686         <actions.(actionScope).rulecatch>
    687 <else>
    688       except
    689         on RE: ERecognitionException do
    690         begin
    691           ReportError(RE);
    692           Recover(Input,RE);
    693           <@setErrorReturnValue()>
    694         end;<\n>
    695 <endif>
    696 <endif>
    697 <endif>
    698       end;
    699     finally
    700       <if(trace)>TraceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    701       <memoize()>
    702       <ruleScopeCleanUp()>
    703       <finally>
    704     end;
    705     <@postamble()>
    706   finally
    707     Locals.Finalize;
    708   end;
    709   Exit(<ruleReturnValue()>);
    710 end;
    711 // $ANTLR end "<ruleName>"
    712 >>
    713 
    714 catch(decl,action) ::= <<
    715 catch (<e.decl>)
    716 {
    717     <e.action>
    718 }
    719 >>
    720 
    721 ruleDeclarations() ::= <<
    722 <if(ruleDescriptor.hasMultipleReturnValues)>
    723 RetVal := T<returnType()>.Create;
    724 RetVal.Start := Input.LT(1);<\n>
    725 <else>
    726 <ruleDescriptor.returnScope.attributes:{ a |
    727 <a.name> := <if(a.initValue)><a.initValue><else><initValue(a.type)><endif>;
    728 }>
    729 <endif>
    730 <if(memoize)>
    731 <ruleDescriptor.name>_StartIndex := Input.Index();
    732 <endif>
    733 >>
    734 
    735 ruleDeclarationVars() ::= <<
    736 <if(ruleDescriptor.hasMultipleReturnValues)>
    737 <else>
    738 <ruleDescriptor.returnScope.attributes:{ a |
    739 <a.name>: <a.type>;
    740 }>
    741 <endif>
    742 <if(memoize)>
    743 <ruleDescriptor.name>_StartIndex: Integer;
    744 <endif>
    745 >>
    746 
    747 ruleScopeSetUp() ::= <<
    748 <ruleDescriptor.useScopes:{<it>Stack.Push(T<it>Scope.Create);}; separator="\n">
    749 <ruleDescriptor.ruleScope:{<it.name>Stack.Push(T<it.name>Scope.Create);}; separator="\n">
    750 >>
    751 
    752 ruleScopeCleanUp() ::= <<
    753 <ruleDescriptor.useScopes:{<it>Stack.Pop();}; separator="\n">
    754 <ruleDescriptor.ruleScope:{<it.name>Stack.Pop;}; separator="\n">
    755 >>
    756 
    757 ruleLabelDefs() ::= <<
    758 <[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels]:{<it.label.text> := nil;}; separator="\n">
    759 <[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]:{list_<it.label.text> := nil;}; separator="\n">
    760 <ruleDescriptor.ruleLabels:ruleLabelDef(label=it); separator="\n">
    761 <ruleDescriptor.ruleListLabels:{ll|<ll.label.text> := nil;}; separator="\n">
    762 >>
    763 
    764 ruleLabelDefVars() ::= <<
    765 <[ruleDescriptor.tokenLabels,ruleDescriptor.tokenListLabels]:{<it.label.text>: I<labelType>;}; separator="\n">
    766 <[ruleDescriptor.tokenListLabels,ruleDescriptor.ruleListLabels]:{list_<it.label.text>: IList\<IANTLRInterface\>;}; separator="\n">
    767 <ruleDescriptor.ruleLabels:ruleLabelDefVar(label=it); separator="\n">
    768 <ruleDescriptor.ruleListLabels:{ll|<ll.label.text>: <ruleLabelType(referencedRule=ll.referencedRule)>;}; separator="\n">
    769 >>
    770 
    771 lexerRuleLabelDefs() ::= <<
    772 <[ruleDescriptor.tokenLabels,
    773   ruleDescriptor.tokenListLabels,
    774   ruleDescriptor.ruleLabels]
    775     :{<it.label.text> := nil;}; separator="\n"
    776 >
    777 <ruleDescriptor.charLabels:{int <it.label.text>;}; separator="\n">
    778 <[ruleDescriptor.tokenListLabels,
    779   ruleDescriptor.ruleListLabels,
    780   ruleDescriptor.ruleListLabels]
    781     :{List_<it.label.text> := nil;}; separator="\n"
    782 >
    783 >>
    784 
    785 lexerRuleLabelDefDeclarations() ::= <<
    786 <[ruleDescriptor.tokenLabels,
    787   ruleDescriptor.tokenListLabels,
    788   ruleDescriptor.ruleLabels]
    789     :{<it.label.text>: I<labelType>;}; separator="\n"
    790 >
    791 <ruleDescriptor.charLabels:{int <it.label.text>;}; separator="\n">
    792 <[ruleDescriptor.tokenListLabels,
    793   ruleDescriptor.ruleListLabels,
    794   ruleDescriptor.ruleListLabels]
    795     :{List_<it.label.text>: IList;}; separator="\n"
    796 >
    797 >>
    798 
    799 ruleReturnValue() ::= <<
    800 <if(!ruleDescriptor.isSynPred)>
    801 <if(ruleDescriptor.hasReturnValue)>
    802 <if(ruleDescriptor.hasSingleReturnValue)>
    803 <ruleDescriptor.singleValueReturnName>
    804 <else>
    805 RetVal
    806 <endif>
    807 <else>
    808 <! nil !>
    809 <endif>
    810 <endif>
    811 >>
    812 
    813 ruleCleanUp() ::= <<
    814 <if(ruleDescriptor.hasMultipleReturnValues)>
    815 <if(!TREE_PARSER)>
    816 RetVal.Stop := Input.LT(-1);
    817 <endif>
    818 <endif>
    819 >>
    820 
    821 memoize() ::= <<
    822 <if(memoize)>
    823 <if(backtracking)>
    824 if (State.Backtracking > 0) then
    825   Memoize(Input, <ruleDescriptor.index>, <ruleDescriptor.name>_StartIndex);
    826 <endif>
    827 <endif>
    828 >>
    829 
    830 /** How to generate a rule in the lexer; naked blocks are used for
    831  *  fragment rules.
    832  */
    833 lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize) ::= <<
    834 // $ANTLR start "<ruleName>"
    835 <ruleDescriptor.parameterScope>
    836 procedure T<grammar.recognizerName>.m<ruleName>(<ruleDescriptor.parameterScope:parameterScope(scope=it)>);
    837 var
    838   <ruleDescriptor.actions.vars>
    839   Locals: TLocalStorage;
    840   TokenType, Channel: Integer;
    841   Alt: array [0..<grammar.numberOfDecisions>] of Integer;
    842   <lexerRuleLabelDefDeclarations()>
    843 begin
    844   Locals.Initialize;
    845   try
    846     <ruleAttributeScope(scope=ruleDescriptor.ruleScope)>
    847     <if(trace)>TraceIn("<ruleName>", <ruleDescriptor.index>);<endif>
    848     <ruleScopeSetUp()>
    849     <ruleDeclarations()>
    850     try
    851 <if(nakedBlock)>
    852       <ruleMemoization(name=ruleName)>
    853       <lexerRuleLabelDefs()>
    854       <ruleDescriptor.actions.init>
    855       <block><\n>
    856 <else>
    857       TokenType := <ruleName>;
    858       Channel := DEFAULT_TOKEN_CHANNEL;
    859       <ruleMemoization(name=ruleName)>
    860       <lexerRuleLabelDefs()>
    861       <ruleDescriptor.actions.init>
    862       <block>
    863       <ruleCleanUp()>
    864       State.TokenType := TokenType;
    865       State.Channel := Channel;
    866       <(ruleDescriptor.actions.after):execAction()>
    867 <endif>
    868     finally
    869       <if(trace)>TraceOut("<ruleName>", <ruleDescriptor.index>);<endif>
    870       <ruleScopeCleanUp()>
    871       <memoize()>
    872     end;
    873   finally
    874     Locals.Finalize;
    875   end;
    876 end;
    877 // $ANTLR end "<ruleName>"
    878 >>
    879 
    880 /** How to generate code for the implicitly-defined lexer grammar rule
    881  *  that chooses between lexer rules.
    882  */
    883 tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor) ::= <<
    884 procedure T<grammar.recognizerName>.mTokens;
    885 var
    886   Alt: array [0..<grammar.numberOfDecisions>] of Integer;
    887 begin
    888   <block>
    889 end;
    890 
    891 procedure T<grammar.recognizerName>.DoTokens;
    892 begin
    893   mTokens;
    894 end;
    895 >>
    896 
    897 // S U B R U L E S
    898 
    899 /** A (...) subrule with multiple alternatives */
    900 block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    901 (* <fileName>:<description> *)
    902 Alt[<decisionNumber>] := <maxAlt>;
    903 <decls>
    904 <@predecision()>
    905 <decision>
    906 <@postdecision()>
    907 <@prebranch()>
    908 case Alt[<decisionNumber>] of
    909   <alts:altSwitchCase()>
    910 end;
    911 <@postbranch()>
    912 >>
    913 
    914 /** A rule block with multiple alternatives */
    915 ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    916 (* <fileName>:<description> *)
    917 Alt[<decisionNumber>] := <maxAlt>;
    918 <decls>
    919 <@predecision()>
    920 <decision>
    921 <@postdecision()>
    922 case Alt[<decisionNumber>] of
    923   <alts:altSwitchCase()>
    924 end;
    925 >>
    926 
    927 ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
    928 (* <fileName>:<description> *)
    929 <decls>
    930 <@prealt()>
    931 <alts>
    932 <@postalt()>
    933 >>
    934 
    935 /** A special case of a (...) subrule with a single alternative */
    936 blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::= <<
    937 (* <fileName>:<description> *)
    938 <decls>
    939 <@prealt()>
    940 <alts>
    941 <@postalt()>
    942 >>
    943 
    944 /** A (..)+ block with 1 or more alternatives */
    945 positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    946 (* <fileName>:<description> *)
    947 FCnt[<decisionNumber>] := 0;
    948 <decls>
    949 <@preloop()>
    950 while (True) do
    951 begin
    952   Alt[<decisionNumber>] := <maxAlt>;
    953   <@predecision()>
    954   <decision>
    955   <@postdecision()>
    956   case Alt[<decisionNumber>] of
    957     <alts:altSwitchCase()>
    958   else
    959     begin
    960       if (FCnt[<decisionNumber>] >= 1) then
    961         Break;
    962       <ruleBacktrackFailure()>
    963       raise EEarlyExitException.Create(<decisionNumber>, Input);
    964       <@earlyExitException()>
    965     end;
    966   end;
    967   Inc(FCnt[<decisionNumber>]);
    968 end;
    969 <@postloop()>
    970 >>
    971 
    972 positiveClosureBlockSingleAlt ::= positiveClosureBlock
    973 
    974 /** A (..)* block with 1 or more alternatives */
    975 closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::= <<
    976 (* <fileName>:<description> *)
    977 <decls>
    978 <@preloop()>
    979 while (True) do
    980 begin
    981   Alt[<decisionNumber>] := <maxAlt>;
    982   <@predecision()>
    983   <decision>
    984   <@postdecision()>
    985   case Alt[<decisionNumber>] of
    986     <alts:altSwitchCase()>
    987   else
    988     Break;
    989   end;
    990 end;
    991 <@postloop()>
    992 >>
    993 
    994 closureBlockSingleAlt ::= closureBlock
    995 
    996 /** Optional blocks (x)? are translated to (x|) by before code generation
    997  *  so we can just use the normal block template
    998  */
    999 optionalBlock ::= block
   1000 
   1001 optionalBlockSingleAlt ::= block
   1002 
   1003 /** A case in a switch that jumps to an alternative given the alternative
   1004  *  number.  A DFA predicts the alternative and then a simple switch
   1005  *  does the jump to the code that actually matches that alternative.
   1006  */
   1007 altSwitchCase() ::= <<
   1008 <i>:
   1009   <@prealt()>
   1010   <it><\n>
   1011 >>
   1012 
   1013 /** An alternative is just a list of elements; at outermost level */
   1014 alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew) ::= <<
   1015 (* <fileName>:<description> *)
   1016 begin
   1017   <@declarations()>
   1018   <elements:element()>
   1019   <rew>
   1020   <@cleanup()>
   1021 end;
   1022 >>
   1023 
   1024 /** What to emit when there is no rewrite.  For auto build
   1025  *  mode, does nothing.
   1026  */
   1027 noRewrite(rewriteBlockLevel, treeLevel) ::= ""
   1028 
   1029 // E L E M E N T S
   1030 
   1031 /** Dump the elements one per line */
   1032 element() ::= <<
   1033 <@prematch()>
   1034 <it.el>
   1035 >>
   1036 
   1037 /** match a token optionally with a label in front */
   1038 tokenRef(token,label,elementIndex,terminalOptions) ::= <<
   1039 <if(label)><label> := <endif>Match(Input, <token>, FOLLOW_<token>_in_<ruleName><elementIndex>)<if(label)> as I<labelType><endif>;<\n><checkRuleBacktrackFailure()>
   1040 >>
   1041 
   1042 /** ids+=ID */
   1043 tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
   1044 <tokenRef(...)>
   1045 <listLabel(elem=label,...)>
   1046 >>
   1047 
   1048 listLabel(label,elem) ::= <<
   1049 if (list_<label> = nil) then list_<label> := TList\<IANTLRInterface\>.Create;
   1050 list_<label>.Add(<elem>);<\n>
   1051 >>
   1052 
   1053 /** match a character */
   1054 charRef(char,label) ::= <<
   1055 <if(label)>
   1056 <label> := Input.LA(1);<\n>
   1057 <endif>
   1058 Match(<char>); <checkRuleBacktrackFailure()>
   1059 >>
   1060 
   1061 /** match a character range */
   1062 charRangeRef(a,b,label) ::= <<
   1063 <if(label)>
   1064 <label> := Input.LA(1);<\n>
   1065 <endif>
   1066 MatchRange(<a>, <b>); <checkRuleBacktrackFailure()>
   1067 >>
   1068 
   1069 /** For now, sets are interval tests and must be tested inline */
   1070 matchSet(s,label,elementIndex,postmatchCode="") ::= <<
   1071 <if(label)>
   1072 <if(LEXER)>
   1073 <label> := Input.LA(1);<\n>
   1074 <else>
   1075 <label> := Input.LT(1) as I<labelType>;<\n>
   1076 <endif>
   1077 <endif>
   1078 if (<s>) then
   1079 begin
   1080   Input.Consume;
   1081   <postmatchCode>
   1082   <if(!LEXER)>
   1083   State.ErrorRecovery := False;<endif>
   1084   <if(backtracking)>State.Failed := False;<endif>
   1085 end
   1086 else
   1087 begin
   1088   <ruleBacktrackFailure()>
   1089   FException := EMismatchedSetException.Create(nil, Input);
   1090   <@mismatchedSetException()>
   1091 <if(LEXER)>
   1092   Recover(FException);
   1093   raise FException;<\n>
   1094 <else>
   1095   raise FException;
   1096   <! use following code to make it recover inline; remove throw mse;
   1097   RecoverFromMismatchedSet(input,mse,FOLLOW_set_in_<ruleName><elementIndex>);
   1098   !>
   1099 <endif>
   1100 end;<\n>
   1101 >>
   1102 
   1103 matchRuleBlockSet ::= matchSet
   1104 
   1105 matchSetAndListLabel(s,label,elementIndex,postmatchCode) ::= <<
   1106 <matchSet(...)>
   1107 <listLabel(elem=label,...)>
   1108 >>
   1109 
   1110 /** Match a string literal */
   1111 lexerStringRef(string,label,elementIndex) ::= <<
   1112 <if(label)>
   1113 Locals.AsInteger['<label>Start'] := CharIndex;
   1114 Match(<string>); <checkRuleBacktrackFailure()>
   1115 <label> := TCommonToken.Create(Input, TToken.INVALID_TOKEN_TYPE, TToken.DEFAULT_CHANNEL, Locals.AsInteger['<label>Start'], CharIndex-1);
   1116 <else>
   1117 Match(<string>); <checkRuleBacktrackFailure()>
   1118 <endif>
   1119 >>
   1120 
   1121 wildcard(label,elementIndex) ::= <<
   1122 <if(label)>
   1123 <label> := Input.LT(1) as I<labelType>;<\n>
   1124 <endif>
   1125 MatchAny(input); <checkRuleBacktrackFailure()>
   1126 >>
   1127 
   1128 wildcardAndListLabel(label,elementIndex) ::= <<
   1129 <wildcard(...)>
   1130 <listLabel(elem=label,...)>
   1131 >>
   1132 
   1133 /** Match . wildcard in lexer */
   1134 wildcardChar(label, elementIndex) ::= <<
   1135 <if(label)>
   1136 <label> := Input.LA(1);<\n>
   1137 <endif>
   1138 MatchAny(); <checkRuleBacktrackFailure()>
   1139 >>
   1140 
   1141 wildcardCharListLabel(label, elementIndex) ::= <<
   1142 <wildcardChar(...)>
   1143 <listLabel(elem=label,...)>
   1144 >>
   1145 
   1146 /** Match a rule reference by invoking it possibly with arguments
   1147  *  and a return value or values.  The 'rule' argument was the
   1148  *  target rule name, but now is type Rule, whose toString is
   1149  *  same: the rule name.  Now though you can access full rule
   1150  *  descriptor stuff.
   1151  */
   1152 ruleRef(rule,label,elementIndex,args,scope) ::= <<
   1153 PushFollow(FOLLOW_<rule.name>_in_<ruleName><elementIndex>);
   1154 <if(label)>
   1155 <label> := <if(scope)><scope:delegateName()>.<endif><rule.name>(<args; separator=", ">);<\n>
   1156 <else>
   1157 <if(scope)>T<scope.recognizerName>(IANTLRObject(<scope:delegateName()>).Implementor).<endif><rule.name>(<args; separator=", ">);<\n>
   1158 <endif>
   1159 State.FollowingStackPointer := State.FollowingStackPointer - 1;
   1160 <checkRuleBacktrackFailure()>
   1161 >>
   1162 
   1163 /** ids+=r */
   1164 ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
   1165 <ruleRef(...)>
   1166 <listLabel(elem=label,...)>
   1167 >>
   1168 
   1169 /** A lexer rule reference.
   1170  *
   1171  *  The 'rule' argument was the target rule name, but now
   1172  *  is type Rule, whose toString is same: the rule name.
   1173  *  Now though you can access full rule descriptor stuff.
   1174  */
   1175 lexerRuleRef(rule,label,args,elementIndex,scope) ::= <<
   1176 <if(label)>
   1177 Locals.AsInteger['<label>Start<elementIndex>'] := CharIndex;
   1178 <if(scope)><scope:delegateName()>.<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
   1179 <label> := TCommonToken.Create(Input, TToken.INVALID_TOKEN_TYPE, TToken.DEFAULT_CHANNEL,
   1180   Locals.AsInteger['<label>Start<elementIndex>'], CharIndex - 1);
   1181 <else>
   1182 <if(scope)>(<scope:delegateName()>.Implementor as T<scope.recognizerName>).<endif>m<rule.name>(<args; separator=", ">); <checkRuleBacktrackFailure()>
   1183 <endif>
   1184 >>
   1185 
   1186 /** i+=INT in lexer */
   1187 lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope) ::= <<
   1188 <lexerRuleRef(...)>
   1189 <listLabel(elem=label,...)>
   1190 >>
   1191 
   1192 /** EOF in the lexer */
   1193 lexerMatchEOF(label,elementIndex) ::= <<
   1194 <if(label)>
   1195 Locals.AsInteger['<label>Start<elementIndex>'] := CharIndex;
   1196 Match(EOF); <checkRuleBacktrackFailure()>
   1197 Locals['<label>'] := TCommonToken.Create(Input, EOF, TToken.DEFAULT_CHANNEL, Locals.AsInteger['<label>Start<elementIndex>'], CharIndex-1);
   1198 <else>
   1199 Match(EOF); <checkRuleBacktrackFailure()>
   1200 <endif>
   1201 >>
   1202 
   1203 /** match ^(root children) in tree parser */
   1204 tree(root, actionsAfterRoot, children, nullableChildList,
   1205      enclosingTreeLevel, treeLevel) ::= <<
   1206 <root:element()>
   1207 <actionsAfterRoot:element()>
   1208 <if(nullableChildList)>
   1209 if (Input.LA(1) = TToken.DOWN) then
   1210 begin
   1211   Match(Input, TToken.DOWN, nil); <checkRuleBacktrackFailure()>
   1212   <children:element()>
   1213   Match(Input, TToken.UP, nil); <checkRuleBacktrackFailure()>
   1214 end;
   1215 <else>
   1216 Match(Input, TToken.DOWN, nil); <checkRuleBacktrackFailure()>
   1217 <children:element()>
   1218 Match(Input, TToken.UP, nil);<\n><checkRuleBacktrackFailure()>
   1219 <endif>
   1220 >>
   1221 
   1222 /** Every predicate is used as a validating predicate (even when it is
   1223  *  also hoisted into a prediction expression).
   1224  */
   1225 validateSemanticPredicate(pred,description) ::= <<
   1226 if (not (<evalPredicate(...)>)) then
   1227 begin
   1228   <ruleBacktrackFailure()>
   1229   raise EFailedPredicateException.Create(Input, '<ruleName>', '<description>');
   1230 end;<\n>
   1231 >>
   1232 
   1233 // F i x e d  D F A  (if-then-else)
   1234 
   1235 dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1236 FLA[<decisionNumber>,<stateNumber>] := Input.LA(<k>);<\n>
   1237 <edges; separator="\nelse ">
   1238 else
   1239 begin
   1240 <if(eotPredictsAlt)>
   1241   Alt[<decisionNumber>] := <eotPredictsAlt>;<\n>
   1242 <else>
   1243   <ruleBacktrackFailure()>
   1244   raise ENoViableAltException.Create('<description>', <decisionNumber>, <stateNumber>, Input);<\n>
   1245 <endif>
   1246 end;
   1247 >>
   1248 
   1249 /** Same as a normal DFA state except that we don't examine lookahead
   1250  *  for the bypass alternative.  It delays error detection but this
   1251  *  is faster, smaller, and more what people expect.  For (X)? people
   1252  *  expect "if ( LA(1)==X ) match(X);" and that's it.
   1253  */
   1254 dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1255 FLA[<decisionNumber>,<stateNumber>] := Input.LA(<k>);<\n>
   1256 <edges; separator="\nelse ">;
   1257 >>
   1258 
   1259 /** A DFA state that is actually the loopback decision of a closure
   1260  *  loop.  If end-of-token (EOT) predicts any of the targets then it
   1261  *  should act like a default clause (i.e., no error can be generated).
   1262  *  This is used only in the lexer so that for ('a')* on the end of a rule
   1263  *  anything other than 'a' predicts exiting.
   1264  */
   1265 dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1266 FLA[<decisionNumber>,<stateNumber>] := Input.LA(<k>);
   1267 <edges; separator="\nelse ">;<\n>
   1268 <if(eotPredictsAlt)>
   1269 <if(!edges)>
   1270 Alt[<decisionNumber>] := <eotPredictsAlt>; <! if no edges, don't gen ELSE !>
   1271 <else>
   1272 else
   1273 begin
   1274   Alt[<decisionNumber>] := <eotPredictsAlt>;
   1275 end;<\n>
   1276 <endif>
   1277 <endif>
   1278 >>
   1279 
   1280 /** An accept state indicates a unique alternative has been predicted */
   1281 dfaAcceptState(alt) ::= "Alt[<decisionNumber>] := <alt>;"
   1282 
   1283 /** A simple edge with an expression.  If the expression is satisfied,
   1284  *  enter to the target state.  To handle gated productions, we may
   1285  *  have to evaluate some predicates for this edge.
   1286  */
   1287 dfaEdge(labelExpr, targetState, predicates) ::= <<
   1288 if ((<labelExpr>)<if(predicates)> and (<predicates>)<endif>) then
   1289 begin
   1290   <targetState>
   1291 end <! no ; here !>
   1292 >>
   1293 
   1294 // F i x e d  D F A  (switch case)
   1295 
   1296 /** A DFA state where a SWITCH may be generated.  The code generator
   1297  *  decides if this is possible: CodeGenerator.canGenerateSwitch().
   1298  */
   1299 dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1300 case Input.LA(<k>) of
   1301   <edges; separator="\n">
   1302 else
   1303   begin
   1304 <if(eotPredictsAlt)>
   1305     Alt[<decisionNumber>] := <eotPredictsAlt>;
   1306 <else>
   1307     <ruleBacktrackFailure()>
   1308     <@noViableAltException()>
   1309     raise ENoViableAltException.Create('<description>', <decisionNumber>, <stateNumber>, Input);<\n>
   1310 <endif>
   1311   end;
   1312 end;<\n>
   1313 >>
   1314 
   1315 dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1316 case Input.LA(<k>) of
   1317   <edges; separator="\n">
   1318 end;<\n>
   1319 >>
   1320 
   1321 dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<
   1322 case Input.LA(<k>) of
   1323   <edges; separator="\n"><\n>
   1324 <if(eotPredictsAlt)>
   1325 else
   1326   Alt[<decisionNumber>] := <eotPredictsAlt>;<\n>
   1327 <endif>
   1328 end;<\n>
   1329 >>
   1330 
   1331 dfaEdgeSwitch(labels, targetState) ::= <<
   1332 <labels:{<it>}; separator=",\n">:
   1333   begin
   1334     <targetState>
   1335   end;
   1336 >>
   1337 
   1338 // C y c l i c  D F A
   1339 
   1340 /** The code to initiate execution of a cyclic DFA; this is used
   1341  *  in the rule to predict an alt just like the fixed DFA case.
   1342  *  The <name> attribute is inherited via the parser, lexer, ...
   1343  */
   1344 dfaDecision(decisionNumber,description) ::= <<
   1345 Alt[<decisionNumber>] := FDFA<decisionNumber>.Predict(Input);
   1346 >>
   1347 
   1348 /* Dump DFA tables.
   1349  */
   1350 cyclicDFADeclaration(dfa) ::= <<
   1351 strict protected
   1352   type
   1353     TDFA<dfa.decisionNumber> = class(TDFA)
   1354     protected
   1355       { IDFA }
   1356       function Description: String; override;
   1357     public
   1358       constructor Create(const ARecognizer: IBaseRecognizer);
   1359     end;
   1360   var
   1361     FDFA<dfa.decisionNumber>: IDFA;
   1362 <if(dfa.specialStateSTs)>
   1363 strict protected
   1364   function DFA<dfa.decisionNumber>_SpecialStateTransition(const DFA: IDFA; S: Integer;
   1365     const AInput: IIntStream): Integer;<endif>
   1366 >>
   1367 
   1368 cyclicDFA(dfa) ::= <<
   1369 { T<grammar.recognizerName>.TDFA<dfa.decisionNumber> }
   1370 
   1371 constructor T<grammar.recognizerName>.TDFA<dfa.decisionNumber>.Create(const ARecognizer: IBaseRecognizer);
   1372 const
   1373   DFA<dfa.decisionNumber>_EOT = '<dfa.javaCompressedEOT; wrap="'+\n    '">';
   1374   DFA<dfa.decisionNumber>_EOF = '<dfa.javaCompressedEOF; wrap="'+\n    '">';
   1375   DFA<dfa.decisionNumber>_MIN = '<dfa.javaCompressedMin; wrap="'+\n    '">';
   1376   DFA<dfa.decisionNumber>_MAX = '<dfa.javaCompressedMax; wrap="'+\n    '">';
   1377   DFA<dfa.decisionNumber>_ACCEPT = '<dfa.javaCompressedAccept; wrap="'+\n    '">';
   1378   DFA<dfa.decisionNumber>_SPECIAL = '<dfa.javaCompressedSpecial; wrap="'+\n    '">';
   1379   DFA<dfa.decisionNumber>_TRANSITION: array [0..<length(dfa.javaCompressedTransition)>-1] of String = (
   1380     <dfa.javaCompressedTransition:{s|'<s; wrap="'+\n'">'}; separator=",\n">);
   1381 begin
   1382   inherited Create;
   1383   Recognizer := ARecognizer;
   1384   DecisionNumber := <dfa.decisionNumber>;
   1385   EOT := TDFA.UnpackEncodedString(DFA<dfa.decisionNumber>_EOT);
   1386   EOF := TDFA.UnpackEncodedString(DFA<dfa.decisionNumber>_EOF);
   1387   Min := TDFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_MIN);
   1388   Max := TDFA.UnpackEncodedStringToUnsignedChars(DFA<dfa.decisionNumber>_MAX);
   1389   Accept := TDFA.UnpackEncodedString(DFA<dfa.decisionNumber>_ACCEPT);
   1390   Special := TDFA.UnpackEncodedString(DFA<dfa.decisionNumber>_SPECIAL);
   1391   Transition := TDFA.UnpackEncodedStringArray(DFA<dfa.decisionNumber>_TRANSITION);
   1392 end;
   1393 
   1394 function T<grammar.recognizerName>.TDFA<dfa.decisionNumber>.Description: String;
   1395 begin
   1396   Result := '<dfa.description>';
   1397 end;<\n>
   1398 <if(dfa.specialStateSTs)>
   1399 function T<grammar.recognizerName>.DFA<dfa.decisionNumber>_SpecialStateTransition(const DFA: IDFA; S: Integer;
   1400   const AInput: IIntStream): Integer;
   1401 var
   1402   Locals: TLocalStorage;
   1403   <if(LEXER)>
   1404   Input: IIntStream;
   1405   <endif>
   1406   <if(PARSER)>
   1407   Input: ITokenStream;
   1408   <endif>
   1409   <if(TREE_PARSER)>
   1410   Input: ITreeNodeStream;
   1411   <endif>
   1412   _S: Integer;
   1413   NVAE: ENoViableAltException;
   1414 begin
   1415   Result := -1;
   1416   Locals.Initialize;
   1417   try
   1418     <if(LEXER)>
   1419     Input := AInput;
   1420     <endif>
   1421     <if(PARSER)>
   1422     Input := AInput as ITokenStream;
   1423     <endif>
   1424     <if(TREE_PARSER)>
   1425     Input := AInput as ITreeNodeStream;
   1426     <endif>
   1427     _S := S;
   1428     case S of
   1429       <dfa.specialStateSTs:{state | <i0>: begin<! compressed special state numbers 0..n-1 !>
   1430      <state> <\n>   end;}; separator="\n">
   1431     end;
   1432 <if(backtracking)>
   1433     if (State.Backtracking > 0) then
   1434     begin
   1435       State.Failed := True;
   1436       Exit(-1);
   1437     end;<\n>
   1438 <endif>
   1439     NVAE := ENoViableAltException.Create(DFA.Description, <dfa.decisionNumber>, _S, Input);
   1440     DFA.Error(NVAE);
   1441     raise NVAE;
   1442   finally
   1443     Locals.Finalize;
   1444   end;
   1445 end;<\n>
   1446 <endif>
   1447 >>
   1448 
   1449 /** A state in a cyclic DFA; it's a special state and part of a big switch on
   1450  *  state.
   1451  */
   1452 cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<
   1453 FLA[<decisionNumber>,<stateNumber>] := Input.LA(1);<\n>
   1454 <if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>
   1455 Locals.AsInteger['index<decisionNumber>_<stateNumber>'] := Input.Index;
   1456 Input.Rewind;<\n>
   1457 <endif>
   1458 S := -1;
   1459 <edges; separator="\nelse ">;
   1460 <if(semPredState)> <! return input cursor to state before we rewound !>
   1461 Input.Seek(Locals.AsInteger['index<decisionNumber>_<stateNumber>']);<\n>
   1462 <endif>
   1463 if (S >= 0) then
   1464   Exit(S);
   1465 >>
   1466 
   1467 /** Just like a fixed DFA edge, test the lookahead and indicate what
   1468  *  state to jump to next if successful.
   1469  */
   1470 cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<
   1471 if ((<labelExpr>)<if(predicates)> and (<predicates>)<endif>) then
   1472   S := <targetStateNumber>
   1473 >>
   1474 
   1475 /** An edge pointing at end-of-token; essentially matches any char;
   1476  *  always jump to the target.
   1477  */
   1478 eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<
   1479 S := <targetStateNumber>;<\n>
   1480 >>
   1481 
   1482 
   1483 // D F A  E X P R E S S I O N S
   1484 
   1485 andPredicates(left,right) ::= "((<left>) and (<right>))"
   1486 
   1487 orPredicates(operands) ::= "((<first(operands)>)<rest(operands):{o | or (<o>)}>)"
   1488 
   1489 notPredicate(pred) ::= "!(<evalPredicate(...)>)"
   1490 
   1491 evalPredicate(pred,description) ::= "(<pred>)"
   1492 
   1493 evalSynPredicate(pred,description) ::= "<pred>()"
   1494 
   1495 lookaheadTest(atom,k,atomAsInt) ::= "FLA[<decisionNumber>,<stateNumber>] = <atomAsInt>"
   1496 
   1497 /** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
   1498  *  somewhere.  Must ask for the lookahead directly.
   1499  */
   1500 isolatedLookaheadTest(atom,k,atomAsInt) ::= "Input.LA(<k>) = <atomAsInt>"
   1501 
   1502 lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <<
   1503 ((FLA[<decisionNumber>,<stateNumber>] \>= <lowerAsInt>) and (FLA[<decisionNumber>,<stateNumber>] \<= <upperAsInt>))
   1504 >>
   1505 
   1506 isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(Input.LA(<k>) \>= <lowerAsInt>) and (Input.LA(<k>) \<= <upperAsInt>)"
   1507 
   1508 setTest(ranges) ::= "<ranges; separator=\") or (\">"
   1509 
   1510 // A T T R I B U T E S
   1511 
   1512 globalAttributeScope(scope) ::= <<
   1513 <scope.name>Stack := TStackList\<I<scope.name>Scope\>.Create;<\n>
   1514 <endif>
   1515 >>
   1516 
   1517 globalAttributeScopeDeclaration(scope) ::= <<
   1518 <if(scope.attributes)>
   1519 strict protected
   1520   type
   1521     I<scope.name>Scope = interface(IANTLRObject)
   1522     end;
   1523     T<scope.name>Scope = class(TANTLRObject, I<scope.name>Scope)
   1524     protected
   1525       <scope.attributes:{<it.name>: <it.type>;}; separator="\n">
   1526     end;
   1527 strict protected
   1528   <scope.name>Stack: IStackList\<I<scope.name>Scope\>;
   1529 <endif>
   1530 >>
   1531 
   1532 ruleAttributeScopeDeclaration(scope) ::= <<
   1533 <if(scope.attributes)>
   1534 strict protected
   1535   type
   1536     I<scope.name>Scope = interface(IANTLRObject)
   1537     end;
   1538     T<scope.name>Scope = class(TANTLRObject, I<scope.name>Scope)
   1539     protected
   1540       <scope.attributes:{<it.name>: <it.type>;}; separator="\n">
   1541     end;
   1542 strict protected
   1543   <scope.name>Stack: IStackList\<I<scope.name>Scope\>;
   1544 <endif>
   1545 >>
   1546 
   1547 ruleAttributeScope(scope) ::= <<
   1548 <! protected Stack <scope.name>Stack = new Stack();<\n> !>
   1549 >>
   1550 
   1551 ruleAttributeScopeInit(scope) ::= <<
   1552 <if(scope)>
   1553 <scope.name>Stack := TStackList\<I<scope.name>Scope\>.Create;<\n>
   1554 <endif>
   1555 >>
   1556 
   1557 returnStructName() ::= "<it.name>_return"
   1558 
   1559 returnType() ::= <<
   1560 <if(ruleDescriptor.hasMultipleReturnValues)>
   1561 <ruleDescriptor:returnStructName()>
   1562 <! I<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope !>
   1563 <else>
   1564 <if(ruleDescriptor.hasSingleReturnValue)>
   1565 <ruleDescriptor.singleValueReturnType>
   1566 <else>
   1567 <! Pointer/void !>
   1568 <endif>
   1569 <endif>
   1570 >>
   1571 
   1572 /** Generate the C# type associated with a single or multiple return
   1573  *  values.
   1574  */
   1575 ruleLabelType(referencedRule) ::= <<
   1576 <if(referencedRule.hasMultipleReturnValues)>
   1577 I<referencedRule.name>_return
   1578 <else>
   1579 <if(referencedRule.hasSingleReturnValue)>
   1580 <referencedRule.singleValueReturnType>
   1581 <else>
   1582 void
   1583 <endif>
   1584 <endif>
   1585 >>
   1586 
   1587 delegateName() ::= <<
   1588 <if(it.label)><it.label><else>g<it.name><endif>
   1589 >>
   1590 
   1591 /** Using a type to init value map, try to init a type; if not in table
   1592  *  must be an object, default value is "null".
   1593  */
   1594 initValue(typeName) ::= <<
   1595 <csharpTypeInitMap.(typeName)>
   1596 >>
   1597 
   1598 /** Define a rule label including default value */
   1599 ruleLabelDef(label) ::= <<
   1600 <label.label.text> := <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n>
   1601 >>
   1602 
   1603 ruleLabelDefVar(label) ::= <<
   1604 <label.label.text>: <ruleLabelType(referencedRule=label.referencedRule)>;
   1605 >>
   1606 
   1607 /** Define a return struct for a rule if the code needs to access its
   1608  *  start/stop tokens, tree stuff, attributes, ...  Leave a hole for
   1609  *  subgroups to stick in members.
   1610  */
   1611 returnScope(scope) ::= <<
   1612 <if(ruleDescriptor.hasMultipleReturnValues)>
   1613 { T<ruleDescriptor:returnStructName()> }
   1614 
   1615 <scope.attributes:{public <it.decl>;}; separator="\n">
   1616 <@ruleReturnMembers()>
   1617 <endif>
   1618 >>
   1619 
   1620 returnScopeDeclaration(scope) ::= <<
   1621 <if(ruleDescriptor.hasMultipleReturnValues)>
   1622 public
   1623   type
   1624     T<ruleDescriptor:returnStructName()> = class(T<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope, I<ruleDescriptor:returnStructName()>)
   1625     <scope.attributes:{public <it.decl>;}; separator="\n">
   1626     <@ruleReturnMembers()>
   1627     end;
   1628 <endif>
   1629 >>
   1630 
   1631 parameterScope(scope) ::= <<
   1632 <scope.attributes:{<it.decl>}; separator=", ">
   1633 >>
   1634 
   1635 parameterAttributeRef(attr) ::= "<attr.name>"
   1636 parameterSetAttributeRef(attr,expr) ::= "<attr.name> := <expr>;"
   1637 
   1638 scopeAttributeRef(scope,attr,index,negIndex) ::= <<
   1639 <if(negIndex)>
   1640 (<scope>Stack[<scope>Stack.Count-<negIndex>-1] as T<scope>Scope).<attr.name>
   1641 <else>
   1642 <if(index)>
   1643 (<scope>Stack[<index>] as T<scope>Scope).<attr.name>
   1644 ((<scope>_scope)<scope>_stack[<index>]).<attr.name>
   1645 <else>
   1646 (<scope>Stack.Peek.Implementor as T<scope>Scope).<attr.name>
   1647 <endif>
   1648 <endif>
   1649 >>
   1650 
   1651 scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <<
   1652 <if(negIndex)>
   1653 (<scope>Stack[<scope>Stack.Count-<negIndex>-1] as T<scope>Scope).<attr.name> := <expr>;<\n>
   1654 <else>
   1655 <if(index)>
   1656 (<scope>Stack[<index>] as T<scope>Scope).<attr.name> := <expr>;<\n>
   1657 <else>
   1658 (<scope>Stack.Peek.Implementor as T<scope>Scope).<attr.name> := <expr>;<\n>
   1659 <endif>
   1660 <endif>
   1661 >>
   1662 
   1663 /** $x is either global scope or x is rule with dynamic scope; refers
   1664  *  to stack itself not top of stack.  This is useful for predicates
   1665  *  like {$function.size()>0 && $function::name.equals("foo")}?
   1666  */
   1667 isolatedDynamicScopeRef(scope) ::= "<scope>Stack"
   1668 
   1669 /** reference an attribute of rule; might only have single return value */
   1670 ruleLabelRef(referencedRule,scope,attr) ::= <<
   1671 <if(referencedRule.hasMultipleReturnValues)>
   1672 (IfThen(Assigned(<scope>),Def(<scope>).<attr.name>,<initValue(attr.type)>))
   1673 <else>
   1674 <scope>
   1675 <endif>
   1676 >>
   1677 
   1678 returnAttributeRef(ruleDescriptor,attr) ::= <<
   1679 <if(ruleDescriptor.hasMultipleReturnValues)>
   1680 RetVal.<attr.name>
   1681 <else>
   1682 <attr.name>
   1683 <endif>
   1684 >>
   1685 
   1686 returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <<
   1687 <if(ruleDescriptor.hasMultipleReturnValues)>
   1688 RetVal.<attr.name> := <expr>;
   1689 <else>
   1690 <attr.name> := <expr>;
   1691 <endif>
   1692 >>
   1693 
   1694 /** How to translate $tokenLabel */
   1695 tokenLabelRef(label) ::= "<label>"
   1696 
   1697 /** ids+=ID {$ids} or e+=expr {$e} */
   1698 listLabelRef(label) ::= "list_<label>"
   1699 
   1700 
   1701 // not sure the next are the right approach
   1702 
   1703 tokenLabelPropertyRef_text(scope,attr) ::= "(Def(<scope>).Text)"
   1704 tokenLabelPropertyRef_type(scope,attr) ::= "(Def(<scope>).TokenType)"
   1705 tokenLabelPropertyRef_line(scope,attr) ::= "(Def(<scope>).Line)"
   1706 tokenLabelPropertyRef_pos(scope,attr) ::= "(Def(<scope>).CharPositionInLine)"
   1707 tokenLabelPropertyRef_channel(scope,attr) ::= "(Def(<scope>).Channel)"
   1708 tokenLabelPropertyRef_index(scope,attr) ::= "(Def(<scope>).TokenIndex)"
   1709 tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"
   1710 tokenLabelPropertyRef_int(scope,attr) ::= "(StrToIntDef(Def(<scope>).Text,0))"
   1711 
   1712 ruleLabelPropertyRef_start(scope,attr) ::= "(IfThen(Assigned(<scope>), Def(<scope>).Start, nil) as I<labelType>)"
   1713 ruleLabelPropertyRef_stop(scope,attr) ::= "(Def(<scope>).Stop as I<labelType>)"
   1714 ruleLabelPropertyRef_tree(scope,attr) ::= "(Def(Def(<scope>).Tree as I<ASTLabelType>))"
   1715 ruleLabelPropertyRef_text(scope,attr) ::= <<
   1716 <if(TREE_PARSER)>
   1717 IfThen(Assigned(<scope>), Input.TokenStream.ToString(
   1718   Input.TreeAdaptor.GetTokenStartIndex(Def(<scope>).Start),
   1719   Input.TreeAdaptor.GetTokenStopIndex(Def(<scope>).Start)), '')
   1720 <else>
   1721 IfThen(Assigned(<scope>), Input.ToString(
   1722   (Def(<scope>).Start) as IToken,(Def(<scope>).Stop) as IToken), '')
   1723 <endif>
   1724 >>
   1725 ruleLabelPropertyRef_st(scope,attr) ::= "((<scope> != null) ? <scope>.ST : null)"
   1726 
   1727 /** Isolated $RULE ref ok in lexer as it's a Token */
   1728 lexerRuleLabel(label) ::= "<label>"
   1729 
   1730 lexerRuleLabelPropertyRef_type(scope,attr) ::= "(Def(<scope>).TokenType)"
   1731 lexerRuleLabelPropertyRef_line(scope,attr) ::= "(Def(<scope>).Line)"
   1732 lexerRuleLabelPropertyRef_pos(scope,attr) ::= "(IfThen(Assigned(<scope>),Def(<scope>).CharPositionInLine,-1))"
   1733 lexerRuleLabelPropertyRef_channel(scope,attr) ::= "(Def(<scope>).Channel)"
   1734 lexerRuleLabelPropertyRef_index(scope,attr) ::= "(Def(<scope>).TokenIndex)"
   1735 lexerRuleLabelPropertyRef_text(scope,attr) ::= "(Def(<scope>).Text)"
   1736 lexerRuleLabelPropertyRef_int(scope,attr) ::= "(StrToIntDef(Def(<scope>).Text,0))"
   1737 
   1738 // Somebody may ref $template or $tree or $stop within a rule:
   1739 rulePropertyRef_start(scope,attr) ::= "(RetVal.Start as I<labelType>)"
   1740 rulePropertyRef_stop(scope,attr) ::= "(RetVal.Stop as I<labelType>)"
   1741 rulePropertyRef_tree(scope,attr) ::= "(RetVal.Tree as I<ASTLabelType>)"
   1742 rulePropertyRef_text(scope,attr) ::= <<
   1743 <if(TREE_PARSER)>
   1744 Input.TokenStream.ToString(
   1745   Input.TreeAdaptor.GetTokenStartIndex(RetVal.Start),
   1746   Input.TreeAdaptor.GetTokenStopIndex(RetVal.Start))
   1747 <else>
   1748 Input.ToString(RetVal.Start as IToken,Input.LT(-1))
   1749 <endif>
   1750 >>
   1751 rulePropertyRef_st(scope,attr) ::= "RetVal.ST"
   1752 
   1753 lexerRulePropertyRef_text(scope,attr) ::= "Text"
   1754 lexerRulePropertyRef_type(scope,attr) ::= "TokenType"
   1755 lexerRulePropertyRef_line(scope,attr) ::= "State.TokenStartLine"
   1756 lexerRulePropertyRef_pos(scope,attr) ::= "State.TokenStartCharPositionInLine"
   1757 lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexer
   1758 lexerRulePropertyRef_channel(scope,attr) ::= "Channel"
   1759 lexerRulePropertyRef_start(scope,attr) ::= "State.TokenStartCharIndex"
   1760 lexerRulePropertyRef_stop(scope,attr) ::= "(CharIndex-1)"
   1761 lexerRulePropertyRef_int(scope,attr) ::= "StrToInt(<scope>.Text)"
   1762 
   1763 // setting $st and $tree is allowed in local rule. everything else
   1764 // is flagged as error
   1765 ruleSetPropertyRef_tree(scope,attr,expr) ::= "RetVal.Tree := <expr>;"
   1766 ruleSetPropertyRef_st(scope,attr,expr) ::= "RetVal.ST := <expr>;"
   1767 
   1768 
   1769 /** How to execute an action (only when not backtracking) */
   1770 execAction(action) ::= <<
   1771 <if(backtracking)>
   1772 <if(actions.(actionScope).synpredgate)>
   1773 if (<actions.(actionScope).synpredgate>) then
   1774 begin
   1775   <action>
   1776 end;
   1777 <else>
   1778 if (State.Backtracking = 0) then
   1779 begin
   1780   <action>
   1781 end;<\n>
   1782 <endif>
   1783 <else>
   1784 <action>
   1785 <endif>
   1786 >>
   1787 
   1788 
   1789 /** How to always execute an action even when backtracking */
   1790 execForcedAction(action) ::= "<action>"
   1791 
   1792 // M I S C (properties, etc...)
   1793 
   1794 bitset(name, words64) ::= <<
   1795 <name> := TBitSet.Create([<words64:{<it>};separator=",">]);<\n>
   1796 >>
   1797 
   1798 bitsetDecl(name) ::= <<
   1799 <name>: IBitSet;<\n>
   1800 >>
   1801 
   1802 codeFileExtension() ::= ".pas"
   1803 
   1804 true() ::= "True"
   1805 false() ::= "False"
   1806