1/* 2 * [The "BSD license"] 3 * Copyright (c) 2007-2008 Johannes Luber 4 * Copyright (c) 2005-2007 Kunle Odutola 5 * Copyright (c) 2011 Sam Harwell 6 * Copyright (c) 2011 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 32@outputFile.imports() ::= << 33<@super.imports()> 34 35<if(!TREE_PARSER)> 36<! tree parser would already have imported !> 37using Antlr.Runtime.Tree; 38using RewriteRuleITokenStream = Antlr.Runtime.Tree.RewriteRuleTokenStream; 39<endif> 40>> 41 42@genericParser.members() ::= << 43<@super.members()> 44<parserMembers()> 45>> 46 47parserCtorBody() ::= <% 48<super.parserCtorBody()><\n> 49TreeAdaptor = 50<if(actions.(actionScope).treeAdaptorInitializer)> 51 <actions.(actionScope).treeAdaptorInitializer> 52<else> 53 new <actions.(actionScope).treeAdaptorType; null="CommonTreeAdaptor">() 54<end> 55; 56%> 57 58/** Add an adaptor property that knows how to build trees */ 59parserMembers() ::= << 60private <treeAdaptorType()> adaptor; 61 62public <treeAdaptorType()> TreeAdaptor 63{ 64 get 65 { 66 return adaptor; 67 } 68 69 set 70 { 71 this.adaptor = value; 72 <grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor = this.adaptor;}> 73 } 74} 75>> 76 77treeAdaptorType() ::= << 78<actions.(actionScope).treeAdaptorType; null="ITreeAdaptor"> 79>> 80 81ruleReturnBaseType() ::= <% 82Ast<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope\<<ASTLabelType>, <labelType>> 83%> 84 85/** Add a variable to track rule's return AST */ 86ruleDeclarations() ::= << 87<super.ruleDeclarations()> 88<ASTLabelType> root_0 = default(<ASTLabelType>);<\n> 89>> 90 91ruleLabelDefs() ::= << 92<super.ruleLabelDefs()> 93<[ruleDescriptor.tokenLabels,ruleDescriptor.wildcardTreeLabels,ruleDescriptor.wildcardTreeListLabels] 94 :{it|<ASTLabelType> <it.label.text>_tree = default(<ASTLabelType>);}; separator="\n"> 95<ruleDescriptor.tokenListLabels:{it|<ASTLabelType> <it.label.text>_tree = default(<ASTLabelType>);}; separator="\n"> 96<ruleDescriptor.allTokenRefsInAltsWithRewrites 97 :{it|RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>");}; separator="\n"> 98<ruleDescriptor.allRuleRefsInAltsWithRewrites 99 :{it|RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"rule <it>");}; separator="\n"> 100>> 101 102/** When doing auto AST construction, we must define some variables; 103 * These should be turned off if doing rewrites. This must be a "mode" 104 * as a rule could have both rewrite and AST within the same alternative 105 * block. 106 */ 107@alt.declarations() ::= << 108<if(autoAST)> 109<if(outerAlt)> 110<if(!rewriteMode)> 111root_0 = (<ASTLabelType>)adaptor.Nil(); 112<endif> 113<endif> 114<endif> 115>> 116 117// T r a c k i n g R u l e E l e m e n t s 118 119/** ID and track it for use in a rewrite rule */ 120tokenRefTrack(token,label,elementIndex,terminalOptions) ::= << 121<tokenRefBang(...)> <! Track implies no auto AST construction!> 122<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>stream_<token>.Add(<label>);<\n> 123>> 124 125/** ids+=ID and track it for use in a rewrite rule; adds to ids *and* 126 * to the tracking list stream_ID for use in the rewrite. 127 */ 128tokenRefTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 129<tokenRefTrack(...)> 130<listLabelElem(elem=label,elemType=labelType,...)> 131>> 132 133/** ^(ID ...) track for rewrite */ 134tokenRefRuleRootTrack(token,label,elementIndex,terminalOptions) ::= << 135<tokenRefBang(...)> 136<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>stream_<token>.Add(<label>); 137>> 138 139/** Match ^(label+=TOKEN ...) track for rewrite */ 140tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,terminalOptions) ::= << 141<tokenRefRuleRootTrack(...)> 142<listLabelElem(elem=label,elemType=labelType,...)> 143>> 144 145/** rule when output=AST and tracking for rewrite */ 146ruleRefTrack(rule,label,elementIndex,args,scope) ::= << 147<super.ruleRef(...)> 148<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>stream_<rule.name>.Add(<label>.Tree); 149>> 150 151/** x+=rule when output=AST and tracking for rewrite */ 152ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 153<ruleRefTrack(...)> 154<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 155>> 156 157/** ^(rule ...) rewrite */ 158ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= << 159<ruleRefRuleRoot(...)> 160<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>stream_<rule>.Add(<label>.Tree); 161>> 162 163/** ^(x+=rule ...) rewrite */ 164ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= << 165<ruleRefRuleRootTrack(...)> 166<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 167>> 168 169// R e w r i t e 170 171rewriteCode( 172 alts, description, 173 referencedElementsDeep, // ALL referenced elements to right of -> 174 referencedTokenLabels, 175 referencedTokenListLabels, 176 referencedRuleLabels, 177 referencedRuleListLabels, 178 referencedWildcardLabels, 179 referencedWildcardListLabels, 180 rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::= << 181<\n>{ 182// AST REWRITE 183// elements: <referencedElementsDeep; separator=", "> 184// token labels: <referencedTokenLabels; separator=", "> 185// rule labels: <referencedRuleLabels; separator=", "> 186// token list labels: <referencedTokenListLabels; separator=", "> 187// rule list labels: <referencedRuleListLabels; separator=", "> 188// wildcard labels: <[referencedWildcardLabels,referencedWildcardListLabels]; separator=", "> 189<if(backtracking)> 190if (<actions.(actionScope).synpredgate>) { 191<endif> 192<prevRuleRootRef()>.Tree = root_0; 193<rewriteCodeLabels()> 194root_0 = (<ASTLabelType>)adaptor.Nil(); 195<alts:rewriteAlt(); separator="else "> 196<! if tree parser and rewrite=true !> 197<if(TREE_PARSER&&rewriteMode)> 198<prevRuleRootRef()>.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0); 199input.ReplaceChildren(adaptor.GetParent(retval.Start), 200 adaptor.GetChildIndex(retval.Start), 201 adaptor.GetChildIndex(_last), 202 retval.Tree); 203<endif> 204<! if parser or tree-parser && rewrite!=true, we need to set result !> 205<if(!TREE_PARSER||!rewriteMode)> 206<prevRuleRootRef()>.Tree = root_0; 207<endif> 208<if(backtracking)> 209} 210<endif> 211} 212 213>> 214 215rewriteCodeLabels() ::= << 216<referencedTokenLabels 217 :{it|RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>",<it>);}; 218 separator="\n" 219> 220<referencedTokenListLabels 221 :{it|RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>", list_<it>);}; 222 separator="\n" 223> 224<referencedWildcardLabels 225 :{it|RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"wildcard <it>",<it>);}; 226 separator="\n" 227> 228<referencedWildcardListLabels 229 :{it|RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"wildcard <it>",list_<it>);}; 230 separator="\n" 231> 232<referencedRuleLabels 233 :{it|RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"rule <it>",<it>!=null?<it>.Tree:null);}; 234 separator="\n" 235> 236<referencedRuleListLabels 237 :{it|RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"token <it>",list_<it>);}; 238 separator="\n" 239> 240>> 241 242/** Generate code for an optional rewrite block; note it uses the deep ref'd element 243 * list rather shallow like other blocks. 244 */ 245rewriteOptionalBlock( 246 alt,rewriteBlockLevel, 247 referencedElementsDeep, // all nested refs 248 referencedElements, // elements in immediately block; no nested blocks 249 description) ::= 250<< 251// <fileName>:<description> 252if (<referencedElementsDeep:{el | stream_<el>.HasNext}; separator="||">) 253{ 254 <alt> 255} 256<referencedElementsDeep:{el | stream_<el>.Reset();<\n>}> 257>> 258 259rewriteClosureBlock( 260 alt,rewriteBlockLevel, 261 referencedElementsDeep, // all nested refs 262 referencedElements, // elements in immediately block; no nested blocks 263 description) ::= 264<< 265// <fileName>:<description> 266while ( <referencedElements:{el | stream_<el>.HasNext}; separator="||"> ) 267{ 268 <alt> 269} 270<referencedElements:{el | stream_<el>.Reset();<\n>}> 271>> 272 273rewritePositiveClosureBlock( 274 alt,rewriteBlockLevel, 275 referencedElementsDeep, // all nested refs 276 referencedElements, // elements in immediately block; no nested blocks 277 description) ::= 278<< 279if (!(<referencedElements:{el | stream_<el>.HasNext}; separator="||">)) 280{ 281 throw new RewriteEarlyExitException(); 282} 283while ( <referencedElements:{el | stream_<el>.HasNext}; separator="||"> ) 284{ 285 <alt> 286} 287<referencedElements:{el | stream_<el>.Reset();<\n>}> 288>> 289 290rewriteAlt(a) ::= << 291// <a.description> 292<if(a.pred)> 293if (<a.pred>) 294{ 295 <a.alt> 296} 297<else> 298{ 299 <a.alt> 300} 301<endif> 302>> 303 304/** For empty rewrites: "r : ... -> ;" */ 305rewriteEmptyAlt() ::= "root_0 = null;" 306 307rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= << 308// <fileName>:<description> 309{ 310<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.Nil(); 311<root:rewriteElement()> 312<children:rewriteElement()> 313adaptor.AddChild(root_<enclosingTreeLevel>, root_<treeLevel>); 314}<\n> 315>> 316 317rewriteElementList(elements) ::= "<elements:rewriteElement()>" 318 319rewriteElement(e) ::= <% 320<@pregen()> 321DebugLocation(<e.line>, <e.pos>);<\n> 322<e.el> 323%> 324 325/** Gen ID or ID[args] */ 326rewriteTokenRef(token,elementIndex,terminalOptions,args) ::= << 327adaptor.AddChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n> 328>> 329 330/** Gen $label ... where defined via label=ID */ 331rewriteTokenLabelRef(label,elementIndex) ::= << 332adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n> 333>> 334 335/** Gen $label ... where defined via label+=ID */ 336rewriteTokenListLabelRef(label,elementIndex) ::= << 337adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n> 338>> 339 340/** Gen ^($label ...) */ 341rewriteTokenLabelRefRoot(label,elementIndex) ::= << 342root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n> 343>> 344 345/** Gen ^($label ...) where label+=... */ 346rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot 347 348/** Gen ^(ID ...) or ^(ID[args] ...) */ 349rewriteTokenRefRoot(token,elementIndex,terminalOptions,args) ::= << 350root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>);<\n> 351>> 352 353rewriteImaginaryTokenRef(args,token,terminalOptions,elementIndex) ::= << 354adaptor.AddChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n> 355>> 356 357rewriteImaginaryTokenRefRoot(args,token,terminalOptions,elementIndex) ::= << 358root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>);<\n> 359>> 360 361/** plain -> {foo} action */ 362rewriteAction(action) ::= << 363root_0 = <action>;<\n> 364>> 365 366/** What is the name of the previous value of this rule's root tree? This 367 * let's us refer to $rule to mean previous value. I am reusing the 368 * variable 'tree' sitting in retval struct to hold the value of root_0 right 369 * before I set it during rewrites. The assign will be to retval.tree. 370 */ 371prevRuleRootRef() ::= "retval" 372 373rewriteRuleRef(rule) ::= << 374adaptor.AddChild(root_<treeLevel>, stream_<rule>.NextTree());<\n> 375>> 376 377rewriteRuleRefRoot(rule) ::= << 378root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<rule>.NextNode(), root_<treeLevel>);<\n> 379>> 380 381rewriteNodeAction(action) ::= << 382adaptor.AddChild(root_<treeLevel>, <action>);<\n> 383>> 384 385rewriteNodeActionRoot(action) ::= << 386root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<action>, root_<treeLevel>);<\n> 387>> 388 389/** Gen $ruleLabel ... where defined via ruleLabel=rule */ 390rewriteRuleLabelRef(label) ::= << 391adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n> 392>> 393 394/** Gen $ruleLabel ... where defined via ruleLabel+=rule */ 395rewriteRuleListLabelRef(label) ::= << 396adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n> 397>> 398 399/** Gen ^($ruleLabel ...) where ruleLabel=rule */ 400rewriteRuleLabelRefRoot(label) ::= << 401root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n> 402>> 403 404/** Gen ^($ruleLabel ...) where ruleLabel+=rule */ 405rewriteRuleListLabelRefRoot(label) ::= << 406root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n> 407>> 408 409rewriteWildcardLabelRef(label) ::= << 410adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n> 411>> 412 413createImaginaryNode(tokenType,terminalOptions,args) ::= <% 414<if(terminalOptions.node)> 415<! new MethodNode(IDLabel, args) !> 416new <terminalOptions.node>(<tokenType><if(args)>, <args; separator=", "><endif>) 417<else> 418(<ASTLabelType>)adaptor.Create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>) 419<endif> 420%> 421 422createRewriteNodeFromElement(token,terminalOptions,args) ::= <% 423<if(terminalOptions.node)> 424new <terminalOptions.node>(stream_<token>.NextToken()<if(args)>, <args; separator=", "><endif>) 425<else> 426<if(args)> <! must create new node from old !> 427adaptor.Create(<token>, <args; separator=", ">) 428<else> 429stream_<token>.NextNode() 430<endif> 431<endif> 432%> 433