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