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*/ 31group 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 */ 53parserMembers() ::= << 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 63parserMembersConstructor() ::= << 64FAdaptor := TCommonTreeAdaptor.Create; 65>> 66 67parserMembersImplementation() ::= << 68procedure T<grammar.recognizerName>.SetAdaptor(const Value: ITreeAdaptor); 69begin 70 FAdaptor := Value; 71 <grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor := FAdaptor;}> 72end; 73>> 74 75@returnScope.ruleReturnMembers() ::= << 76function T<grammar.recognizerName>.T<ruleDescriptor:returnStructName()>.GetTree: IANTLRInterface; 77begin 78 Result := FTree; 79end; 80 81procedure T<grammar.recognizerName>.T<ruleDescriptor:returnStructName()>.SetTree(const Value: IANTLRInterface); 82begin 83 FTree := Value as I<ASTLabelType>; 84end; 85>> 86 87@returnScopeDeclaration.ruleReturnMembers() ::= << 88strict private 89 FTree: I<ASTLabelType>; 90protected 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 */ 97ruleDeclarations() ::= << 98<super.ruleDeclarations()> 99Root[0] := nil;<\n> 100>> 101 102ruleDeclarationVars() ::= << 103<super.ruleDeclarationVars()> 104Root: array [0..63] of I<ASTLabelType>; 105>> 106 107ruleLabelDefs() ::= << 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 115ruleLabelDefVars() ::= << 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)> 129Root[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 */ 138tokenRefTrack(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 */ 146tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 147<tokenRefTrack(...)> 148<listLabel(elem=label,...)> 149>> 150 151/** ^(ID ...) track for rewrite */ 152tokenRefRuleRootTrack(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 */ 158tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 159<tokenRefRuleRootTrack(...)> 160<listLabel(elem=label,...)> 161>> 162 163wildcardTrack(label,elementIndex) ::= << 164<super.wildcard(...)> 165>> 166 167/** rule when output=AST and tracking for rewrite */ 168ruleRefTrack(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 */ 174ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 175<ruleRefTrack(...)> 176<listLabel(elem=label+".Tree",...)> 177>> 178 179/** ^(rule ...) rewrite */ 180ruleRefRuleRootTrack(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 */ 186ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 187<ruleRefRuleRootTrack(...)> 188<listLabel(elem=label+".Tree",...)> 189>> 190 191// R e w r i t e 192 193rewriteCode( 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)> 212if (State.Backtracking = 0) then 213begin<\n> 214<endif> 215<prevRuleRootRef()>.Tree := Root[0]; 216<rewriteCodeLabels()> 217Root[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]); 223input.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)> 237end; 238<endif> 239>> 240 241rewriteCodeLabels() ::= << 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:{ 251if Assigned(<it>) then 252 Locals['Stream_<it>'] := TRewriteRuleSubtreeStream.Create(Adaptor, 'token <it>', <it>.Tree) 253else 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 */ 264rewriteOptionalBlock( 265 alt,rewriteBlockLevel, 266 referencedElementsDeep, // all nested refs 267 referencedElements, // elements in immediately block; no nested blocks 268 description) ::= 269<< 270(* <fileName>:<description> *) 271if (<referencedElementsDeep:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) then 272begin 273 <alt> 274end; 275<referencedElementsDeep:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset;<\n>}> 276>> 277 278rewriteClosureBlock( 279 alt,rewriteBlockLevel, 280 referencedElementsDeep, // all nested refs 281 referencedElements, // elements in immediately block; no nested blocks 282 description) ::= 283<< 284(* <fileName>:<description> *) 285while (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) do 286begin 287 <alt> 288end; 289<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset();<\n>}> 290>> 291 292rewritePositiveClosureBlock( 293 alt,rewriteBlockLevel, 294 referencedElementsDeep, // all nested refs 295 referencedElements, // elements in immediately block; no nested blocks 296 description) ::= 297<< 298if (not (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">)) then 299 raise ERewriteEarlyExitException.Create(''); 300 301while (<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).HasNext}; separator=" or ">) do 302begin 303 <alt> 304end; 305<referencedElements:{el | (Locals['Stream_<el>'] as IRewriteRuleElementStream).Reset();<\n>}> 306>> 307 308rewriteAlt(a) ::= << 309(* <a.description> *) 310<if(a.pred)> 311if (<a.pred>) then 312begin 313 <a.alt> 314end<\n> 315<else> 316begin 317 <a.alt> 318end;<\n> 319<endif> 320>> 321 322/** For empty rewrites: "r : ... -> ;" */ 323rewriteEmptyAlt() ::= "Root[0] = null;" 324 325rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= << 326(* <fileName>:<description> *) 327begin 328 Root[<treeLevel>] := Adaptor.GetNilNode as I<ASTLabelType>; 329 <root:rewriteElement()> 330 <children:rewriteElement()> 331 Adaptor.AddChild(Root[<enclosingTreeLevel>], Root[<treeLevel>]); 332end;<\n> 333>> 334 335rewriteElementList(elements) ::= "<elements:rewriteElement()>" 336 337rewriteElement(e) ::= << 338<@pregen()> 339<e.el> 340>> 341 342/** Gen ID or ID[args] */ 343rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= << 344Adaptor.AddChild(Root[<treeLevel>], <createRewriteNodeFromElement(...)>);<\n> 345>> 346 347/** Gen $label ... where defined via label=ID */ 348rewriteTokenLabelRef(label,elementIndex) ::= << 349Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode());<\n> 350>> 351 352/** Gen $label ... where defined via label+=ID */ 353rewriteTokenListLabelRef(label,elementIndex) ::= << 354Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode);<\n> 355>> 356 357/** Gen ^($label ...) */ 358rewriteTokenLabelRefRoot(label,elementIndex) ::= << 359Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode(), Root[<treeLevel>]) as I<ASTLabelType>;<\n> 360>> 361 362/** Gen ^($label ...) where label+=... */ 363rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot 364 365/** Gen ^(ID ...) or ^(ID[args] ...) */ 366rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= << 367Root[<treeLevel>] := Adaptor.BecomeRoot(<createRewriteNodeFromElement(...)>, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 368>> 369 370rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= << 371Adaptor.AddChild(Root[<treeLevel>], <createImaginaryNode(tokenType=token, ...)>);<\n> 372>> 373 374rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= << 375Root[<treeLevel>] := Adaptor.BecomeRoot(<createImaginaryNode(tokenType=token, ...)>, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 376>> 377 378/** plain -> {foo} action */ 379rewriteAction(action) ::= << 380Root[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 */ 388prevRuleRootRef() ::= "RetVal" 389 390rewriteRuleRef(rule) ::= << 391Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<rule>'] as IRewriteRuleElementStream).NextTree());<\n> 392>> 393 394rewriteRuleRefRoot(rule) ::= << 395Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<rule>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 396>> 397 398rewriteNodeAction(action) ::= << 399Adaptor.AddChild(Root[<treeLevel>], <action>);<\n> 400>> 401 402rewriteNodeActionRoot(action) ::= << 403Root[<treeLevel>] := Adaptor.BecomeRoot(<action>, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 404>> 405 406/** Gen $ruleLabel ... where defined via ruleLabel=rule */ 407rewriteRuleLabelRef(label) ::= << 408Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextTree());<\n> 409>> 410 411/** Gen $ruleLabel ... where defined via ruleLabel+=rule */ 412rewriteRuleListLabelRef(label) ::= << 413Adaptor.AddChild(Root[<treeLevel>], (Locals['Stream_<label>'] as IRewriteRuleElementStream).NextTree());<\n> 414>> 415 416/** Gen ^($ruleLabel ...) where ruleLabel=rule */ 417rewriteRuleLabelRefRoot(label) ::= << 418Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 419>> 420 421/** Gen ^($ruleLabel ...) where ruleLabel+=rule */ 422rewriteRuleListLabelRefRoot(label) ::= << 423Root[<treeLevel>] := Adaptor.BecomeRoot((Locals['Stream_<label>'] as IRewriteRuleElementStream).NextNode, Root[<treeLevel>]) as I<ASTLabelType>;<\n> 424>> 425 426createImaginaryNode(tokenType,terminalOptions,args) ::= << 427<if(terminalOptions.node)> 428<! new MethodNode(IDLabel, args) !> 429T<terminalOptions.node>.Create(<tokenType><if(args)>, <args; separator=", "><endif>) 430<else> 431Adaptor.CreateNode(<tokenType>, <args; separator=", "><if(!args)>'<tokenType>'<endif>) as I<ASTLabelType> 432<endif> 433>> 434 435createRewriteNodeFromElement(token,terminalOptions,args) ::= << 436<if(terminalOptions.node)> 437T<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 !> 440Adaptor.Create(<token>, <args; separator=", ">) 441<else> 442(Locals['Stream_<token>'] as IRewriteRuleElementStream).NextNode 443<endif> 444<endif> 445>> 446