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/** Templates for building ASTs during normal parsing. 33 * 34 * Deal with many combinations. Dimensions are: 35 * Auto build or rewrite 36 * no label, label, list label (label/no-label handled together) 37 * child, root 38 * token, set, rule, wildcard 39 * 40 * The situation is not too bad as rewrite (->) usage makes ^ and ! 41 * invalid. There is no huge explosion of combinations. 42 */ 43 44@rule.setErrorReturnValue() ::= << 45retval.Tree = (<ASTLabelType>)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); 46<! System.out.WriteLine("<ruleName> returns "+((CommonTree)retval.tree).toStringTree()); !> 47>> 48 49// TOKEN AST STUFF 50 51/** ID and output=AST */ 52tokenRef(token,label,elementIndex,terminalOptions) ::= << 53<super.tokenRef(...)> 54<if(backtracking)>if (state.backtracking == 0) {<endif> 55<label>_tree = <createNodeFromToken(...)>; 56adaptor.AddChild(root_0, <label>_tree); 57<if(backtracking)>}<endif> 58>> 59 60/** ID! and output=AST (same as plain tokenRef) */ 61tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>" 62 63/** ID^ and output=AST */ 64tokenRefRuleRoot(token,label,elementIndex,terminalOptions) ::= << 65<super.tokenRef(...)> 66<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 67<label>_tree = <createNodeFromToken(...)>; 68root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0); 69<if(backtracking)>}<endif> 70>> 71 72/** ids+=ID! and output=AST */ 73tokenRefBangAndListLabel(token,label,elementIndex,terminalOptions) ::= << 74<tokenRefBang(...)> 75<listLabelElem(elem=label,elemType=labelType,...)> 76>> 77 78/** label+=TOKEN when output=AST but not rewrite alt */ 79tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= << 80<tokenRef(...)> 81<listLabelElem(elem=label,elemType=labelType,...)> 82>> 83 84/** Match label+=TOKEN^ when output=AST but not rewrite alt */ 85tokenRefRuleRootAndListLabel(token,label,terminalOptions,elementIndex) ::= << 86<tokenRefRuleRoot(...)> 87<listLabelElem(elem=label,elemType=labelType,...)> 88>> 89 90// SET AST 91 92// the match set stuff is interesting in that it uses an argument list 93// to pass code to the default matchSet; another possible way to alter 94// inherited code. I don't use the region stuff because I need to pass 95// different chunks depending on the operator. I don't like making 96// the template name have the operator as the number of templates gets 97// large but this is the most flexible--this is as opposed to having 98// the code generator call matchSet then add root code or ruleroot code 99// plus list label plus ... The combinations might require complicated 100// rather than just added on code. Investigate that refactoring when 101// I have more time. 102 103matchSet(s,label,terminalOptions,elementIndex,postmatchCode) ::= << 104<super.matchSet(postmatchCode={<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>adaptor.AddChild(root_0, <createNodeFromToken(...)>);}, ...)> 105>> 106 107matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= << 108<matchSet(...)> 109>> 110 111matchSetBang(s,label,elementIndex,terminalOptions,postmatchCode) ::= "<super.matchSet(...)>" 112 113// note there is no matchSetTrack because -> rewrites force sets to be 114// plain old blocks of alts: (A|B|...|C) 115 116matchSetRuleRoot(s,label,terminalOptions,elementIndex,debug) ::= << 117<if(label)> 118<label>=(<labelType>)input.LT(1); 119<endif> 120<super.matchSet(postmatchCode={<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<createNodeFromToken(...)>, root_0);}, ...)> 121>> 122 123// RULE REF AST 124 125/** rule when output=AST */ 126ruleRef(rule,label,elementIndex,args,scope) ::= << 127<super.ruleRef(...)> 128<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>adaptor.AddChild(root_0, <label>.Tree); 129>> 130 131/** rule! is same as normal rule ref */ 132ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>" 133 134/** rule^ */ 135ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= << 136<super.ruleRef(...)> 137<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_0); 138>> 139 140/** x+=rule when output=AST */ 141ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= << 142<ruleRef(...)> 143<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 144>> 145 146/** x+=rule! when output=AST is a rule ref with list addition */ 147ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= << 148<ruleRefBang(...)> 149<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 150>> 151 152/** x+=rule^ */ 153ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= << 154<ruleRefRuleRoot(...)> 155<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 156>> 157 158// WILDCARD AST 159 160wildcard(token,label,elementIndex,terminalOptions) ::= << 161<super.wildcard(...)> 162<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 163<label>_tree = (<ASTLabelType>)adaptor.Create(<label>); 164adaptor.AddChild(root_0, <label>_tree); 165<if(backtracking)>}<endif> 166>> 167 168wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>" 169 170wildcardRuleRoot(token,label,elementIndex,terminalOptions) ::= << 171<super.wildcard(...)> 172<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 173<label>_tree = (<ASTLabelType>)adaptor.Create(<label>); 174root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0); 175<if(backtracking)>}<endif> 176>> 177 178createNodeFromToken(label,terminalOptions) ::= <% 179<if(terminalOptions.node)> 180new <terminalOptions.node>(<if(terminalOptions.type)><terminalOptions.type>,<endif><label><if(terminalOptions.text)>,<terminalOptions.text; format="string"><endif>) 181<else> 182(<ASTLabelType>)adaptor.Create(<if(terminalOptions.type)><terminalOptions.type>,<endif><label><if(terminalOptions.text)>,<terminalOptions.text; format="string"><endif>) 183<endif> 184%> 185 186ruleCleanUp() ::= << 187<super.ruleCleanUp()> 188<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 189retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0); 190adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); 191<if(backtracking)>}<endif> 192>> 193