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() ::= << 46 retval.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 */ 53 tokenRef(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) */ 64 tokenRefBang(token,label,elementIndex,terminalOptions) ::= "<super.tokenRef(...)>" 65 66 /** ID^ and output=AST */ 67 tokenRefRuleRoot(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 */ 78 tokenRefBangAndListLabel(token,label,elementIndex,terminalOptions) ::= << 79 <tokenRefBang(...)> 80 <listLabelElem(elem=label,elemType=labelType,...)> 81 >> 82 83 /** label+=TOKEN when output=AST but not rewrite alt */ 84 tokenRefAndListLabel(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 */ 90 tokenRefRuleRootAndListLabel(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 108 matchSet(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 112 matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= << 113 <matchSet(...)> 114 >> 115 116 matchSetBang(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 121 matchSetRuleRoot(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 */ 131 ruleRef(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 */ 139 ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>" 140 141 /** rule^ */ 142 ruleRefRuleRoot(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 */ 148 ruleRefAndListLabel(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 */ 154 ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= << 155 <ruleRefBang(...)> 156 <listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 157 >> 158 159 /** x+=rule^ */ 160 ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= << 161 <ruleRefRuleRoot(...)> 162 <listLabelElem(elem={<label>.Tree},elemType=ASTLabelType,...)> 163 >> 164 165 // WILDCARD AST 166 167 wildcard(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>); 172 adaptor.AddChild(root_0, <label>_tree); 173 <if(backtracking)>}<endif> 174 <endif> 175 >> 176 177 wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>" 178 179 wildcardRuleRoot(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>); 184 root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0); 185 <if(backtracking)>}<endif> 186 <endif> 187 >> 188 189 createNodeFromToken(label,terminalOptions) ::= <% 190 <if(terminalOptions.node)> 191 new <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 197 ruleCleanUp() ::= << 198 <super.ruleCleanUp()> 199 <if(backtracking)>if (<actions.(actionScope).synpredgate>) {<endif> 200 retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0); 201 adaptor.SetTokenBoundaries(retval.Tree, retval.Start, retval.Stop); 202 <if(backtracking)>}<endif> 203 >> 204