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