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 java.util.ArrayList; 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.List; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** A tree of grammars */ 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class CompositeGrammarTree { 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected List<CompositeGrammarTree> children; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Grammar grammar; 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Who is the parent node of this node; if null, implies node is root */ 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CompositeGrammarTree parent; 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CompositeGrammarTree(Grammar g) { 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar = g; 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void addChild(CompositeGrammarTree t) { 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("add "+t.toStringTree()+" as child to "+this.toStringTree()); 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( t==null ) { 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return; // do nothing upon addChild(null) 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( children==null ) { 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver children = new ArrayList<CompositeGrammarTree>(); 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver children.add(t); 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver t.parent = this; 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Find a rule by looking in current grammar then down towards the 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * delegate grammars. 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Rule getRule(String ruleName) { 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Rule r = grammar.getLocallyDefinedRule(ruleName); 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; r==null && children!=null && i < children.size(); i++) { 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver r = child.getRule(ruleName); 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return r; 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Find an option by looking up towards the root grammar rather than down */ 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Object getOption(String key) { 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( grammar.tool!=null && key!=null && key.equals("language") && 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammar.tool.forcedLanguageOption!=null ) { 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammar.tool.forcedLanguageOption; 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Object o = grammar.getLocallyDefinedOption(key); 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( o!=null ) { 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return o; 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( parent!=null ) { 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return parent.getOption(key); 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; // not found 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CompositeGrammarTree findNode(Grammar g) { 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( g==null ) { 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( this.grammar == g ) { 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this; 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree n = null; 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; n==null && children!=null && i < children.size(); i++) { 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver n = child.findNode(g); 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return n; 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CompositeGrammarTree findNode(String grammarName) { 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( grammarName==null ) { 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( grammarName.equals(this.grammar.name) ) { 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree n = null; 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; n==null && children!=null && i < children.size(); i++) { 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver n = child.findNode(grammarName); 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return n; 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Return a postorder list of grammars; root is last in list */ 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public List<Grammar> getPostOrderedGrammarList() { 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<Grammar> grammars = new ArrayList<Grammar>(); 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver _getPostOrderedGrammarList(grammars); 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammars; 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** work for getPostOrderedGrammarList */ 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected void _getPostOrderedGrammarList(List<Grammar> grammars) { 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; children!=null && i < children.size(); i++) { 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child._getPostOrderedGrammarList(grammars); 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammars.add(this.grammar); 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Return a preorder list of grammars; root is first in list */ 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public List<Grammar> getPreOrderedGrammarList() { 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<Grammar> grammars = new ArrayList<Grammar>(); 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver _getPreOrderedGrammarList(grammars); 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return grammars; 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected void _getPreOrderedGrammarList(List<Grammar> grammars) { 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver grammars.add(this.grammar); 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; children!=null && i < children.size(); i++) { 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child._getPreOrderedGrammarList(grammars); 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void trimLexerImportsIntoCombined() { 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree p = this; 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( p.grammar.type == Grammar.LEXER && p.parent!=null && 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p.parent.grammar.type == Grammar.COMBINED ) 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("wacking "+p.grammar.name+" from "+p.parent.grammar.name); 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p.parent.children.remove(this); 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (int i = 0; children!=null && i < children.size(); i++) { 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CompositeGrammarTree child = children.get(i); 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver child.trimLexerImportsIntoCombined(); 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}