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