1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2010 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.tool; 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.DFA; 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.NFAState; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.grammar.v3.ANTLRParser; 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.misc.IntSet; 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.misc.Interval; 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.CommonToken; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.Token; 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.TokenSource; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.tree.CommonTree; 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.tree.Tree; 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.tree.TreeAdaptor; 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.ST; 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.omg.PortableInterceptor.ORBInitInfoPackage.DuplicateName; 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.*; 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Grammars are first converted to ASTs using this class and then are 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * converted to NFAs via a tree walker. 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The reader may notice that I have made a very non-OO decision in this 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * class to track variables for many different kinds of nodes. It wastes 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * space for nodes that don't need the values and OO principles cry out 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for a new class type for each kind of node in my tree. I am doing this 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * on purpose for a variety of reasons. I don't like using the type 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * system for different node types; it yields too many damn class files 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * which I hate. Perhaps if I put them all in one file. Most importantly 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * though I hate all the type casting that would have to go on. I would 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * have all sorts of extra work to do. Ick. Anyway, I'm doing all this 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * on purpose, not out of ignorance. ;) 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class GrammarAST extends CommonTree { 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver static int count = 0; 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int ID = ++count; 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private String textOverride; 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String enclosingRuleName; 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** If this is a decision node, what is the lookahead DFA? */ 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public DFA lookaheadDFA = null; 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** What NFA start state was built from this node? */ 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public NFAState NFAStartState = null; 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** This is used for TREE_BEGIN nodes to point into 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the NFA. TREE_BEGINs point at left edge of DOWN for LOOK computation 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * purposes (Nullable tree child list needs special code gen when matching). 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public NFAState NFATreeDownState = null; 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Rule ref nodes, token refs, set, and NOT set refs need to track their 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * location in the generated NFA so that local FOLLOW sets can be 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * computed during code gen for automatic error recovery. 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public NFAState followingNFAState = null; 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** If this is a SET node, what are the elements? */ 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected IntSet setValue = null; 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** If this is a BLOCK node, track options here */ 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected Map<String,Object> blockOptions; 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** If this is a BLOCK node for a rewrite rule, track referenced 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * elements here. Don't track elements in nested subrules. 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Set<GrammarAST> rewriteRefsShallow; 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* If REWRITE node, track EVERY element and label ref to right of -> 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * for this rewrite rule. There could be multiple of these per 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * rule: 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a : ( ... -> ... | ... -> ... ) -> ... ; 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * We may need a list of all refs to do definitions for whole rewrite 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * later. 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If BLOCK then tracks every element at that level and below. 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Set<GrammarAST> rewriteRefsDeep; 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Map<String,Object> terminalOptions; 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** if this is an ACTION node, this is the outermost enclosing 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * alt num in rule. For actions, define.g sets these (used to 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * be codegen.g). We need these set so we can examine actions 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * early, before code gen, for refs to rule predefined properties 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * and rule labels. For most part define.g sets outerAltNum, but 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * codegen.g does the ones for %foo(a={$ID.text}) type refs as 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * the {$ID...} is not seen as an action until code gen pulls apart. 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int outerAltNum; 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** if this is a TOKEN_REF or RULE_REF node, this is the code ST 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * generated for this node. We need to update it later to add 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a label if someone does $tokenref or $ruleref in an action. 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST code; 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * @return 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Map<String, Object> getBlockOptions() { 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return blockOptions; 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * @param blockOptions 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setBlockOptions(Map<String, Object> blockOptions) { 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.blockOptions = blockOptions; 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST() {;} 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST(int t, String txt) { 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initialize(t,txt); 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST(Token token) { 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver initialize(token); 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void initialize(int i, String s) { 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token = new CommonToken(i,s); 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.setTokenIndex(-1); 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void initialize(Tree ast) { 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST t = ((GrammarAST)ast); 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.startIndex = t.startIndex; 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.stopIndex = t.stopIndex; 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.token = t.token; 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.enclosingRuleName = t.enclosingRuleName; 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.setValue = t.setValue; 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.blockOptions = t.blockOptions; 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.outerAltNum = t.outerAltNum; 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void initialize(Token token) { 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.token = token; 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( token!=null ) { 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver startIndex = token.getTokenIndex(); 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver stopIndex = startIndex; 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public DFA getLookaheadDFA() { 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return lookaheadDFA; 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setLookaheadDFA(DFA lookaheadDFA) { 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.lookaheadDFA = lookaheadDFA; 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public NFAState getNFAStartState() { 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return NFAStartState; 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setNFAStartState(NFAState nfaStartState) { 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.NFAStartState = nfaStartState; 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Save the option key/value pair and process it; return the key 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * or null if invalid option. 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String setBlockOption(Grammar grammar, String key, Object value) { 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( blockOptions == null ) { 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver blockOptions = new HashMap(); 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return setOption(blockOptions, Grammar.legalBlockOptions, grammar, key, value); 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String setTerminalOption(Grammar grammar, String key, Object value) { 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( terminalOptions == null ) { 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver terminalOptions = new HashMap<String,Object>(); 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return setOption(terminalOptions, Grammar.legalTokenOptions, grammar, key, value); 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String setOption(Map options, Set legalOptions, Grammar grammar, String key, Object value) { 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !legalOptions.contains(key) ) { 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ErrorManager.grammarError(ErrorManager.MSG_ILLEGAL_OPTION, 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar, 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token, 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver key); 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( value instanceof String ) { 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String vs = (String)value; 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( vs.charAt(0)=='"' ) { 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver value = vs.substring(1,vs.length()-1); // strip quotes 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( key.equals("k") ) { 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.numberOfManualLookaheadOptions++; 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( key.equals("backtrack") && value.toString().equals("true") ) { 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.composite.getRootGrammar().atLeastOneBacktrackOption = true; 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options.put(key, value); 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return key; 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Object getBlockOption(String key) { 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Object value = null; 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( blockOptions != null ) { 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver value = blockOptions.get(key); 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return value; 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setOptions(Grammar grammar, Map options) { 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( options==null ) { 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.blockOptions = null; 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String[] keys = (String[])options.keySet().toArray(new String[options.size()]); 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (String optionName : keys) { 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String stored= setBlockOption(grammar, optionName, options.get(optionName)); 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( stored==null ) { 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver options.remove(optionName); 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String getText() { 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( textOverride!=null ) return textOverride; 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( token!=null ) { 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return token.getText(); 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ""; 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setType(int type) { 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.setType(type); 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setText(String text) { 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver textOverride = text; // don't alt tokens as others might see 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int getType() { 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( token!=null ) { 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return token.getType(); 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return -1; 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int getLine() { 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int line=0; 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( token!=null ) { 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = token.getLine(); 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( line==0 ) { 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Tree child = getChild(0); 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( child!=null ) { 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver line = child.getLine(); 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return line; 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int getCharPositionInLine(){ 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int col=0; 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( token!=null ) { 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver col = token.getCharPositionInLine(); 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( col==0 ) { 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Tree child = getChild(0); 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( child!=null ) { 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver col = child.getCharPositionInLine(); 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return col; 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setLine(int line) { 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.setLine(line); 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setCharPositionInLine(int value){ 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.setCharPositionInLine(value); 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public IntSet getSetValue() { 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return setValue; 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setSetValue(IntSet setValue) { 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.setValue = setValue; 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST getLastChild() { 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (getChildCount() == 0) 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST)getChild(getChildCount() - 1); 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST getNextSibling() { 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST)getParent().getChild(getChildIndex() + 1); 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST getLastSibling() { 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Tree parent = getParent(); 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( parent==null ) { 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST)parent.getChild(parent.getChildCount() - 1); 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST[] getChildrenAsArray() { 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST[])getChildren().toArray(new GrammarAST[getChildCount()]); 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private static final GrammarAST DescendantDownNode = new GrammarAST(Token.DOWN, "DOWN"); 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private static final GrammarAST DescendantUpNode = new GrammarAST(Token.UP, "UP"); 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static List<Tree> descendants(Tree root){ 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return descendants(root, false); 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static List<Tree> descendants(Tree root, boolean insertDownUpNodes){ 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<Tree> result = new ArrayList<Tree>(); 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int count = root.getChildCount(); 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (insertDownUpNodes){ 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(root); 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(DescendantDownNode); 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0 ; i < count ; i++){ 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Tree child = root.getChild(i); 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Tree subchild : descendants(child, true)) 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(subchild); 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(DescendantUpNode); 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver }else{ 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(root); 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0 ; i < count ; i++){ 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Tree child = root.getChild(i); 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Tree subchild : descendants(child, false)) 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(subchild); 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST findFirstType(int ttype) { 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check this node (the root) first 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( this.getType()==ttype ) { 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this; 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // else check children 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<Tree> descendants = descendants(this); 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Tree child : descendants) { 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( child.getType()==ttype ) { 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST)child; 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public List<GrammarAST> findAllType(int ttype) { 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<GrammarAST> nodes = new ArrayList<GrammarAST>(); 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver _findAllType(ttype, nodes); 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return nodes; 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void _findAllType(int ttype, List<GrammarAST> nodes) { 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check this node (the root) first 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( this.getType()==ttype ) nodes.add(this); 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check children 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; i < getChildCount(); i++){ 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST child = (GrammarAST)getChild(i); 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child._findAllType(ttype, nodes); 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Make nodes unique based upon Token so we can add them to a Set; if 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * not a GrammarAST, check type. 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean equals(Object ast) { 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( this == ast ) { 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !(ast instanceof GrammarAST) ) { 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.getType() == ((Tree)ast).getType(); 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST t = (GrammarAST)ast; 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return token.getLine() == t.getLine() && 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver token.getCharPositionInLine() == t.getCharPositionInLine(); 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Make nodes unique based upon Token so we can add them to a Set; if 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * not a GrammarAST, check type. 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int hashCode(){ 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (token == null) 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return token.hashCode(); 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** See if tree has exact token types and structure; no text */ 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasSameTreeStructure(Tree other) { 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check roots first. 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (this.getType() != other.getType()) return false; 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // if roots match, do full list match test on children. 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Iterator<Tree> thisDescendants = descendants(this, true).iterator(); 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Iterator<Tree> otherDescendants = descendants(other, true).iterator(); 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver while (thisDescendants.hasNext()) { 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!otherDescendants.hasNext()) 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (thisDescendants.next().getType() != otherDescendants.next().getType()) 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return !otherDescendants.hasNext(); 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static GrammarAST dup(Tree t) { 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t==null ) { 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST dup_t = new GrammarAST(); 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dup_t.initialize(t); 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return dup_t; 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Tree dupNode(){ 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return dup(this); 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /**Duplicate a tree, assuming this is a root node of a tree-- 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * duplicate that node and what's below; ignore siblings of root node. 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static GrammarAST dupTreeNoActions(GrammarAST t, GrammarAST parent) { 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t==null ) { 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST result = (GrammarAST)t.dupNode(); 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (GrammarAST subchild : getChildrenForDupTree(t)) { 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.addChild(dupTreeNoActions(subchild, result)); 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver private static List<GrammarAST> getChildrenForDupTree(GrammarAST t) { 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<GrammarAST> result = new ArrayList<GrammarAST>(); 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; i < t.getChildCount(); i++){ 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST child = (GrammarAST)t.getChild(i); 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int ttype = child.getType(); 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (ttype == ANTLRParser.REWRITES || ttype == ANTLRParser.REWRITE || ttype==ANTLRParser.ACTION) { 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver continue; 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (ttype == ANTLRParser.BANG || ttype == ANTLRParser.ROOT) { 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (GrammarAST subchild : getChildrenForDupTree(child)) 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(subchild); 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(child); 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( result.size()==1 && result.get(0).getType()==ANTLRParser.EOA && 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.getType()==ANTLRParser.ALT ) 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // can't have an empty alt, insert epsilon 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(0, new GrammarAST(ANTLRParser.EPSILON, "epsilon")); 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static GrammarAST dupTree(GrammarAST t) { 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t==null ) { 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST root = dup(t); // make copy of root 519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // copy all children of root. 520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i= 0; i < t.getChildCount(); i++) { 521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST child = (GrammarAST)t.getChild(i); 522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver root.addChild(dupTree(child)); 523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return root; 525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setTreeEnclosingRuleNameDeeply(String rname) { 528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver enclosingRuleName = rname; 529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (getChildCount() == 0) return; 530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (Object child : getChildren()) { 531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!(child instanceof GrammarAST)) { 532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver continue; 533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver GrammarAST grammarAST = (GrammarAST)child; 535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammarAST.setTreeEnclosingRuleNameDeeply(rname); 536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String toStringList() { 540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ""; 541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Track start/stop token for subtree root created for a rule. 544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Only works with Tree nodes. For rules that match nothing, 545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * seems like this will yield start=i and stop=i-1 in a nil node. 546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Might be useful info so I'll not force to be i..i. 547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void setTokenBoundaries(Token startToken, Token stopToken) { 549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( startToken!=null ) startIndex = startToken.getTokenIndex(); 550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( stopToken!=null ) stopIndex = stopToken.getTokenIndex(); 551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST getBlockALT(int i) { 554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( this.getType()!=ANTLRParser.BLOCK ) return null; 555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int alts = 0; 556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int j =0 ; j < getChildCount(); j++) { 557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (getChild(j).getType() == ANTLRParser.ALT) { 558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver alts++; 559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (alts == i) { 561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return (GrammarAST)getChild(j); 562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 567