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}