Home | History | Annotate | Download | only in Delphi
      1 /*
      2  [The "BSD license"]
      3  Copyright (c) 2008 Erik van Bilsen
      4  Copyright (c) 2007-2008 Johannes Luber
      5  Copyright (c) 2005-2007 Kunle Odutola
      6  Copyright (c) 2005 Terence Parr
      7  All rights reserved.
      8 
      9  Redistribution and use in source and binary forms, with or without
     10  modification, are permitted provided that the following conditions
     11  are met:
     12  1. Redistributions of source code must retain the above copyright
     13     notice, this list of conditions and the following disclaimer.
     14  2. Redistributions in binary form must reproduce the above copyright
     15     notice, this list of conditions and the following disclaimer in the
     16     documentation and/or other materials provided with the distribution.
     17  3. The name of the author may not be used to endorse or promote products
     18     derived from this software without specific prior written permission.
     19 
     20  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 group AST;
     32 
     33 @outputFile.imports() ::= <<
     34 <@super.imports()><if(!TREE_PARSER)><! tree parser would already have imported !>  Antlr.Runtime.Tree,<\n><endif>
     35 >>
     36 
     37 @genericParser.members() ::= <<
     38 <@super.members()>
     39 <parserMembers()>
     40 >>
     41 
     42 @genericParser.membersConstructor() ::= <<
     43 <@super.membersConstructor()>
     44 <parserMembersConstructor()>
     45 >>
     46 
     47 @genericParser.membersImplementation() ::= <<
     48 <@super.membersImplementation()>
     49 <parserMembersImplementation()>
     50 >>
     51 
     52 /** Add an adaptor property that knows how to build trees */
     53 parserMembers() ::= <<
     54   strict protected
     55     FAdaptor: ITreeAdaptor;
     56     procedure SetAdaptor(const Value: ITreeAdaptor);
     57     property Adaptor: ITreeAdaptor read FAdaptor;
     58   public
     59     property TreeAdaptor: ITreeAdaptor read FAdaptor write SetAdaptor;
     60 
     61 >>
     62 
     63 parserMembersConstructor() ::= <<
     64 FAdaptor := TCommonTreeAdaptor.Create;
     65 >>
     66 
     67 parserMembersImplementation() ::= <<
     68 procedure T<grammar.recognizerName>.SetAdaptor(const Value: ITreeAdaptor);
     69 begin
     70   FAdaptor := Value;
     71   <grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor := FAdaptor;}>
     72 end;
     73 >>
     74 
     75 @returnScope.ruleReturnMembers() ::= <<
     76 function T<grammar.recognizerName>.T<ruleDescriptor:returnStructName()>.GetTree: IANTLRInterface;
     77 begin
     78   Result := FTree;
     79 end;
     80 
     81 procedure T<grammar.recognizerName>.T<ruleDescriptor:returnStructName()>.SetTree(const Value: IANTLRInterface);
     82 begin
     83   FTree := Value as I<ASTLabelType>;
     84 end;
     85 >>
     86 
     87 @returnScopeDeclaration.ruleReturnMembers() ::= <<
     88 strict private
     89   FTree: I<ASTLabelType>;
     90 protected
     91   { IRuleReturnScope }
     92   function GetTree: IANTLRInterface; override;
     93   procedure SetTree(const Value: IANTLRInterface); override;
     94 >>
     95 
     96 /** Add a variable to track rule's return AST */
     97 ruleDeclarations() ::= <<
     98 <super.ruleDeclarations()>
     99 Root[0] := nil;<\n>
    100 >>
    101 
    102 ruleDeclarationVars() ::= <<
    103 <super.ruleDeclarationVars()>
    104 Root: array [0..63] of I<ASTLabelType>;
    105 >>
    106 
    107 ruleLabelDefs() ::= <<
    108 <super.ruleLabelDefs()>
    109 <ruleDescriptor.tokenLabels:{<it.label.text>_tree := nil;}; separator="\n">
    110 <ruleDescriptor.tokenListLabels:{<it.label.text>_tree := nil;}; separator="\n">
    111 <ruleDescriptor.allTokenRefsInAltsWithRewrites:{Locals['Stream_<it>'] := TRewriteRule<rewriteElementType>Stream.Create(Adaptor,'token <it>');}; separator="\n">
    112 <ruleDescriptor.allRuleRefsInAltsWithRewrites:{Locals['Stream_<it>'] := TRewriteRuleSubtreeStream.Create(Adaptor,'rule <it>');}; separator="\n">
    113 >>
    114 
    115 ruleLabelDefVars() ::= <<
    116 <super.ruleLabelDefVars()>
    117 <ruleDescriptor.tokenLabels:{<it.label.text>_tree: I<ASTLabelType>;}; separator="\n">
    118 <ruleDescriptor.tokenListLabels:{<it.label.text>_tree: I<ASTLabelType>;}; separator="\n">
    119 >>
    120 /** When doing auto AST construction, we must define some variables;
    121  *  These should be turned off if doing rewrites.  This must be a "mode"
    122  *  as a rule could have both rewrite and AST within the same alternative
    123  *  block.
    124  */
    125 @alt.declarations() ::= <<
    126 <if(autoAST)>
    127 <if(outerAlt)>
    128 <if(!rewriteMode)>
    129 Root[0] := Adaptor.GetNilNode as I<ASTLabelType>;
    130 <endif>
    131 <endif>
    132 <endif>
    133 >>
    134 
    135 // T r a c k i n g  R u l e  E l e m e n t s
    136 
    137 /** ID and track it for use in a rewrite rule */
    138 tokenRefTrack(token,label,elementIndex,terminalOptions) ::= <<
    139 <tokenRefBang(...)> <! Track implies no auto AST construction!>
    140 <if(backtracking)>if (State.Backtracking = 0) then <endif>(Locals['Stream_<token>'] as IRewriteRuleElementStream).Add(<label>);<\n>
    141 >>
    142 
    143 /** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
    144  *  to the tracking list stream_ID for use in the rewrite.
    145  */
    146 tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
    147 <tokenRefTrack(...)>
    148 <listLabel(elem=label,...)>
    149 >>
    150 
    151 /** ^(ID ...) track for rewrite */
    152 tokenRefRuleRootTrack(token,label,elementIndex,terminalOptions) ::= <<
    153 <tokenRefBang(...)>
    154 <if(backtracking)>if (State.Backtracking = 0) then <endif>(Locals['Stream_<token>'] as IRewriteRuleElementStream).Add(<label>);<\n>
    155 >>
    156 
    157 /** Match ^(label+=TOKEN ...) track for rewrite */
    158 tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
    159 <tokenRefRuleRootTrack(...)>
    160 <listLabel(elem=label,...)>
    161 >>
    162 
    163 wildcardTrack(label,elementIndex) ::= <<
    164 <super.wildcard(...)>
    165 >>
    166 
    167 /** rule when output=AST and tracking for rewrite */
    168 ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
    169 <super.ruleRef(...)>
    170 <if(backtracking)>if (State.Backtracking = 0) then <endif>(Locals['Stream_<rule.name>'] as IRewriteRuleElementStream).Add(<label>.Tree);<\n>
    171 >>
    172 
    173 /** x+=rule when output=AST and tracking for rewrite */
    174 ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    175 <ruleRefTrack(...)>
    176 <listLabel(elem=label+".Tree",...)>
    177 >>
    178 
    179 /** ^(rule ...) rewrite */
    180 ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
    181 <ruleRefRuleRoot(...)>
    182 <if(backtracking)>if (State.Backtracking = 0) then <endif>(Locals['Stream_<rule>'] as IRewriteRuleElementStream).Add(<label>.Tree);
    183 >>
    184 
    185 /** ^(x+=rule ...) rewrite */
    186 ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    187 <ruleRefRuleRootTrack(...)>
    188 <listLabel(elem=label+".Tree",...)>
    189 >>
    190 
    191 // R e w r i t e
    192 
    193 rewriteCode(
    194 	alts, description,
    195 	referencedElementsDeep, // ALL referenced elements to right of ->
    196 	referencedTokenLabels,
    197 	referencedTokenListLabels,
    198 	referencedRuleLabels,
    199 	referencedRuleListLabels,
    200     referencedWildcardLabels,
    201     referencedWildcardListLabels,
    202 	rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
    203 <<
    204 
    205 // AST REWRITE
    206 // elements:          <referencedElementsDeep; separator=", ">
    207 // token labels:      <referencedTokenLabels; separator=", ">
    208 // rule labels:       <referencedRuleLabels; separator=", ">
    209 // token list labels: <referencedTokenListLabels; separator=", ">
    210 // rule list labels:  <referencedRuleListLabels; separator=", ">
    211 <if(backtracking)>
    212 if (State.Backtracking = 0) then
    213 begin<\n>
    214 <endif>
    215 <prevRuleRootRef()>.Tree := Root[0];
    216 <rewriteCodeLabels()>
    217 Root[0] := Adaptor.GetNilNode as I<ASTLabelType>;
    218 <alts:rewriteAlt(); separator="else ">
    219 <! if tree parser and rewrite=true !>
    220 <if(TREE_PARSER)>
    221 <if(rewriteMode)>
    222 <prevRuleRootRef()>.Tree = (<ASTLabelType>)adaptor.rulePostProcessing(root[0]);
    223 input.ReplaceChildren(adaptor.GetParent(retval.Start),
    224                       adaptor.GetChildIndex(retval.Start),
    225                       adaptor.GetChildIndex(_last),
    226                       retval.Tree);
    227 <endif>
    228 <endif>
    229 <! if parser or rewrite!=true, we need to set result !>
    230 <if(!TREE_PARSER)>
    231 <prevRuleRootRef()>.Tree := Root[0];<\n>
    232 <endif>
    233 <if(!rewriteMode)>
    234 <prevRuleRootRef()>.Tree := Root[0];<\n>
    235 <endif>
    236 <if(backtracking)>
    237 end;
    238 <endif>
    239 >>
    240 
    241 rewriteCodeLabels() ::= <<
    242 <referencedTokenLabels
    243     :{Locals['Stream_<it>'] := TRewriteRule<rewriteElementType>Stream.Create(Adaptor, 'token <it>', <it>);};
    244     separator="\n"
    245 >
    246 <referencedTokenListLabels
    247     :{Locals['Stream_<it>'] := TRewriteRule<rewriteElementType>Stream.Create(Adaptor,'token <it>', list_<it>);};
    248     separator="\n"
    249 >
    250 <referencedRuleLabels:{
    251 if Assigned(<it>) then
    252   Locals['Stream_<it>'] := TRewriteRuleSubtreeStream.Create(Adaptor, 'token <it>', <it>.Tree)
    253 else
    254   Locals['Stream_<it>'] := TRewriteRuleSubtreeStream.Create(Adaptor, 'token <it>', nil);}; separator="\n">
    255 <referencedRuleListLabels
    256     :{Locals['Stream_<it>'] := TRewriteRuleSubtreeStream.Create(Adaptor, 'token <it>', list_<it>);};
    257     separator="\n"
    258 >
    259 >>
    260 
    261 /** Generate code for an optional rewrite block; note it uses the deep ref'd element
    262   *  list rather shallow like other blocks.
    263   */
    264 rewriteOptionalBlock(
    265 	alt,rewriteBlockLevel,
    266 	referencedElementsDeep, // all nested refs
    267 	referencedElements,     // elements in immediately block; no nested blocks
    268 	description) ::=
    269 <<
    270 (* <fileName>:<description> *)
    271 if (<referencedElementsDeep:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) then
    272 begin
    273   <alt>
    274 end;
    275 <referencedElementsDeep:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset;<\n>}>
    276 >>
    277 
    278 rewriteClosureBlock(
    279 	alt,rewriteBlockLevel,
    280 	referencedElementsDeep, // all nested refs
    281 	referencedElements,     // elements in immediately block; no nested blocks
    282 	description) ::=
    283 <<
    284 (* <fileName>:<description> *)
    285 while (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) do
    286 begin
    287   <alt>
    288 end;
    289 <referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset();<\n>}>
    290 >>
    291 
    292 rewritePositiveClosureBlock(
    293 	alt,rewriteBlockLevel,
    294 	referencedElementsDeep, // all nested refs
    295 	referencedElements,     // elements in immediately block; no nested blocks
    296 	description) ::=
    297 <<
    298 if (not (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">)) then
    299   raise ERewriteEarlyExitException.Create('');
    300 
    301 while (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) do
    302 begin
    303   <alt>
    304 end;
    305 <referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset();<\n>}>
    306 >>
    307 
    308 rewriteAlt(a) ::= <<
    309 (* <a.description> *)
    310 <if(a.pred)>
    311 if (<a.pred>) then
    312 begin
    313   <a.alt>
    314 end<\n>
    315 <else>
    316 begin
    317   <a.alt>
    318 end;<\n>
    319 <endif>
    320 >>
    321 
    322 /** For empty rewrites: "r : ... -> ;" */
    323 rewriteEmptyAlt() ::= "Root[0] = null;"
    324 
    325 rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
    326 (* <fileName>:<description> *)
    327 begin
    328   Root[<treeLevel>] := Adaptor.GetNilNode as I<ASTLabelType>;
    329   <root:rewriteElement()>
    330   <children:rewriteElement()>
    331   Adaptor.AddChild(Root[<enclosingTreeLevel>], Root[<treeLevel>]);
    332 end;<\n>
    333 >>
    334 
    335 rewriteElementList(elements) ::= "<elements:rewriteElement()>"
    336 
    337 rewriteElement(e) ::= <<
    338 <@pregen()>
    339 <e.el>
    340 >>
    341 
    342 /** Gen ID or ID[args] */
    343 rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= <<
    344 Adaptor.AddChild(Root[<treeLevel>], <createRewriteNodeFromElement(...)>);<\n>
    345 >>
    346 
    347 /** Gen $label ... where defined via label=ID */
    348 rewriteTokenLabelRef(label,elementIndex) ::= <<
    349 Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode());<\n>
    350 >>
    351 
    352 /** Gen $label ... where defined via label+=ID */
    353 rewriteTokenListLabelRef(label,elementIndex) ::= <<
    354 Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode);<\n>
    355 >>
    356 
    357 /** Gen ^($label ...) */
    358 rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
    359 Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode(), Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    360 >>
    361 
    362 /** Gen ^($label ...) where label+=... */
    363 rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
    364 
    365 /** Gen ^(ID ...) or ^(ID[args] ...) */
    366 rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= <<
    367 Root[<treeLevel>] := Adaptor.BecomeRoot(<createRewriteNodeFromElement(...)>, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    368 >>
    369 
    370 rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= <<
    371 Adaptor.AddChild(Root[<treeLevel>], <createImaginaryNode(tokenType=token, ...)>);<\n>
    372 >>
    373 
    374 rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= <<
    375 Root[<treeLevel>] := Adaptor.BecomeRoot(<createImaginaryNode(tokenType=token, ...)>, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    376 >>
    377 
    378 /** plain -> {foo} action */
    379 rewriteAction(action) ::= <<
    380 Root[0] = <action>;<\n>
    381 >>
    382 
    383 /** What is the name of the previous value of this rule's root tree?  This
    384  *  let's us refer to $rule to mean previous value.  I am reusing the
    385  *  variable 'tree' sitting in retval struct to hold the value of Root[0] right
    386  *  before I set it during rewrites.  The assign will be to retval.Tree.
    387  */
    388 prevRuleRootRef() ::= "RetVal"
    389 
    390 rewriteRuleRef(rule) ::= <<
    391 Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<rule>'] as IRewriteRuleElementStream).NextTree());<\n>
    392 >>
    393 
    394 rewriteRuleRefRoot(rule) ::= <<
    395 Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<rule>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    396 >>
    397 
    398 rewriteNodeAction(action) ::= <<
    399 Adaptor.AddChild(Root[<treeLevel>], <action>);<\n>
    400 >>
    401 
    402 rewriteNodeActionRoot(action) ::= <<
    403 Root[<treeLevel>] := Adaptor.BecomeRoot(<action>, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    404 >>
    405 
    406 /** Gen $ruleLabel ... where defined via ruleLabel=rule */
    407 rewriteRuleLabelRef(label) ::= <<
    408 Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextTree());<\n>
    409 >>
    410 
    411 /** Gen $ruleLabel ... where defined via ruleLabel+=rule */
    412 rewriteRuleListLabelRef(label) ::= <<
    413 Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextTree());<\n>
    414 >>
    415 
    416 /** Gen ^($ruleLabel ...) where ruleLabel=rule */
    417 rewriteRuleLabelRefRoot(label) ::= <<
    418 Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    419 >>
    420 
    421 /** Gen ^($ruleLabel ...) where ruleLabel+=rule */
    422 rewriteRuleListLabelRefRoot(label) ::= <<
    423 Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n>
    424 >>
    425 
    426 createImaginaryNode(tokenType,terminalOptions,args) ::= <<
    427 <if(terminalOptions.node)>
    428 <! new MethodNode(IDLabel, args) !>
    429 T<terminalOptions.node>.Create(<tokenType><if(args)>, <args; separator=", "><endif>)
    430 <else>
    431 Adaptor.CreateNode(<tokenType>, <args; separator=", "><if(!args)>'<tokenType>'<endif>) as I<ASTLabelType>
    432 <endif>
    433 >>
    434 
    435 createRewriteNodeFromElement(token,terminalOptions,args) ::= <<
    436 <if(terminalOptions.node)>
    437 T<terminalOptions.node>.Create((Locals['Stream_<token>'] as IRewriteRuleElementStream).NextToken<if(args)>, <args; separator=", "><endif>)
    438 <else>
    439 <if(args)> <! must create new node from old !>
    440 Adaptor.Create(<token>, <args; separator=", ">)
    441 <else>
    442 (Locals['Stream_<token>'] as IRewriteRuleElementStream).NextNode
    443 <endif>
    444 <endif>
    445 >>
    446