1/* 2 * [The "BSD license"] 3 * Copyright (c) 2011 Terence Parr 4 * All rights reserved. 5 * 6 * Conversion to C#: 7 * Copyright (c) 2011 Sam Harwell, Pixel Mine, Inc. 8 * All rights reserved. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33/** Templates for building ASTs during normal parsing. 34 * 35 * Deal with many combinations. Dimensions are: 36 * Auto build or rewrite 37 * no label, label, list label (label/no-label handled together) 38 * child, root 39 * token, set, rule, wildcard 40 * 41 * The situation is not too bad as rewrite (->) usage makes ^ and ! 42 * invalid. There is no huge explosion of combinations. 43 */ 44 45@rule.setErrorReturnValue() ::= << 46retval.Tree = (<ASTLabelType>)adaptor.ErrorNode(input, retval.Start, input.LT(-1), re); 47<! System.out.WriteLine("<ruleName> returns "+((CommonTree)retval.tree).toStringTree()); !> 48>> 49 50// TOKEN AST STUFF 51 52/** ID and output=AST */ 53tokenRef(token,label,elementIndex,terminalOptions) ::= <% 54<super.tokenRef(...)> 55<if(!ruleDescriptor.isSynPred)> 56<if(backtracking)><\n>if (state.backtracking == 0) {<endif> 57<\n><label>_tree = <createNodeFromToken(...)>; 58<\n>adaptor.AddChild(root_0, <label>_tree); 59<if(backtracking)><\n>}<endif> 60<endif> 61%> 62 63/** ID! and output=AST (same as plain tokenRef) */ 64tokenRefBang(token,label,elementIndex,terminalOptions) ::= "<super.tokenRef(...)>" 65 66/** ID^ and output=AST */ 67tokenRefRuleRoot(token,label,elementIndex,terminalOptions) ::= <% 68<super.tokenRef(...)> 69<if(!ruleDescriptor.isSynPred)> 70<if(backtracking)><\n>if (<actions.(actionScope).synpredgate>) {<endif> 71<\n><label>_tree = <createNodeFromToken(...)>; 72<\n>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0); 73<if(backtracking)><\n>}<endif> 74<endif> 75%> 76 77/** ids+=ID! and output=AST */ 78tokenRefBangAndListLabel(token,label,elementIndex,terminalOptions) ::= << 79<tokenRefBang(...)> 80<listLabelElem(elem=label,elemType=labelType,...)> 81>> 82 83/** label+=TOKEN when output=AST but not rewrite alt */ 84tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= << 85<tokenRef(...)> 86<listLabelElem(elem=label,elemType=labelType,...)> 87>> 88 89/** Match label+=TOKEN^ when output=AST but not rewrite alt */ 90tokenRefRuleRootAndListLabel(token,label,terminalOptions,elementIndex) ::= << 91<tokenRefRuleRoot(...)> 92<listLabelElem(elem=label,elemType=labelType,...)> 93>> 94 95// SET AST 96 97// the match set stuff is interesting in that it uses an argument list 98// to pass code to the default matchSet; another possible way to alter 99// inherited code. I don't use the region stuff because I need to pass 100// different chunks depending on the operator. I don't like making 101// the template name have the operator as the number of templates gets 102// large but this is the most flexible--this is as opposed to having 103// the code generator call matchSet then add root code or ruleroot code 104// plus list label plus ... The combinations might require complicated 105// rather than just added on code. Investigate that refactoring when 106// I have more time. 107 108matchSet(s,label,terminalOptions,elementIndex,postmatchCode) ::= << 109<super.matchSet(postmatchCode={<if(!ruleDescriptor.isSynPred)><if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>adaptor.AddChild(root_0, <createNodeFromToken(...)>);<endif>}, ...)> 110>> 111 112matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= << 113<matchSet(...)> 114>> 115 116matchSetBang(s,label,elementIndex,terminalOptions,postmatchCode) ::= "<super.matchSet(...)>" 117 118// note there is no matchSetTrack because -> rewrites force sets to be 119// plain old blocks of alts: (A|B|...|C) 120 121matchSetRuleRoot(s,label,terminalOptions,elementIndex,debug) ::= << 122<if(label)> 123<label>=(<labelType>)input.LT(1); 124<endif> 125<super.matchSet(postmatchCode={<if(!ruleDescriptor.isSynPred)><if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<createNodeFromToken(...)>, root_0);<endif>}, ...)> 126>> 127 128// RULE REF AST 129 130/** rule when output=AST */ 131ruleRef(rule,label,elementIndex,args,scope) ::= <% 132<super.ruleRef(...)> 133<if(!ruleDescriptor.isSynPred)> 134<\n><if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>adaptor.AddChild(root_0, <label>.Tree); 135<endif> 136%> 137 138/** rule! is same as normal rule ref */ 139ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>" 140 141/** rule^ */ 142ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= << 143<super.ruleRef(...)> 144<if(backtracking)>if (<actions.(actionScope).synpredgate>) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_0); 145>> 146 147/** x+=rule when output=AST */ 148ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= << 149<ruleRef(...)> 150<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 151>> 152 153/** x+=rule! when output=AST is a rule ref with list addition */ 154ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= << 155<ruleRefBang(...)> 156<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 157>> 158 159/** x+=rule^ */ 160ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= << 161<ruleRefRuleRoot(...)> 162<listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 163>> 164 165// WILDCARD AST 166 167wildcard(token,label,elementIndex,terminalOptions) ::= << 168<super.wildcard(...)> 169<if(!ruleDescriptor.isSynPred)> 170<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 171<label>_tree = (<ASTLabelType>)adaptor.Create(<label>); 172adaptor.AddChild(root_0, <label>_tree); 173<if(backtracking)>}<endif> 174<endif> 175>> 176 177wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>" 178 179wildcardRuleRoot(token,label,elementIndex,terminalOptions) ::= << 180<super.wildcard(...)> 181<if(!ruleDescriptor.isSynPred)> 182<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 183<label>_tree = (<ASTLabelType>)adaptor.Create(<label>); 184root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0); 185<if(backtracking)>}<endif> 186<endif> 187>> 188 189createNodeFromToken(label,terminalOptions) ::= <% 190<if(terminalOptions.node)> 191new <terminalOptions.node>(<if(terminalOptions.type)><terminalOptions.type>,<endif><label><if(terminalOptions.text)>,<terminalOptions.text; format="string"><endif>) 192<else> 193(<ASTLabelType>)adaptor.Create(<if(terminalOptions.type)><terminalOptions.type>,<endif><label><if(terminalOptions.text)>,<terminalOptions.text; format="string"><endif>) 194<endif> 195%> 196 197ruleCleanUp() ::= << 198<super.ruleCleanUp()> 199<if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 200retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0); 201adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); 202<if(backtracking)>}<endif> 203>> 204