aboutsummaryrefslogtreecommitdiff
path: root/tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java
diff options
context:
space:
mode:
Diffstat (limited to 'tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java')
-rw-r--r--tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java159
1 files changed, 159 insertions, 0 deletions
diff --git a/tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java b/tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java
new file mode 100644
index 0000000..bfab382
--- /dev/null
+++ b/tool/src/main/java/org/antlr/tool/CompositeGrammarTree.java
@@ -0,0 +1,159 @@
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2010 Terence Parr
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.antlr.tool;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** A tree of grammars */
+public class CompositeGrammarTree {
+ protected List<CompositeGrammarTree> children;
+ public Grammar grammar;
+
+ /** Who is the parent node of this node; if null, implies node is root */
+ public CompositeGrammarTree parent;
+
+ public CompositeGrammarTree(Grammar g) {
+ grammar = g;
+ }
+
+ public void addChild(CompositeGrammarTree t) {
+ //System.out.println("add "+t.toStringTree()+" as child to "+this.toStringTree());
+ if ( t==null ) {
+ return; // do nothing upon addChild(null)
+ }
+ if ( children==null ) {
+ children = new ArrayList<CompositeGrammarTree>();
+ }
+ children.add(t);
+ t.parent = this;
+ }
+
+ /** Find a rule by looking in current grammar then down towards the
+ * delegate grammars.
+ */
+ public Rule getRule(String ruleName) {
+ Rule r = grammar.getLocallyDefinedRule(ruleName);
+ for (int i = 0; r==null && children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ r = child.getRule(ruleName);
+ }
+ return r;
+ }
+
+ /** Find an option by looking up towards the root grammar rather than down */
+ public Object getOption(String key) {
+ if ( grammar.tool!=null && key!=null && key.equals("language") &&
+ grammar.tool.forcedLanguageOption!=null ) {
+ return grammar.tool.forcedLanguageOption;
+ }
+ Object o = grammar.getLocallyDefinedOption(key);
+ if ( o!=null ) {
+ return o;
+ }
+ if ( parent!=null ) {
+ return parent.getOption(key);
+ }
+ return null; // not found
+ }
+
+ public CompositeGrammarTree findNode(Grammar g) {
+ if ( g==null ) {
+ return null;
+ }
+ if ( this.grammar == g ) {
+ return this;
+ }
+ CompositeGrammarTree n = null;
+ for (int i = 0; n==null && children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ n = child.findNode(g);
+ }
+ return n;
+ }
+
+ public CompositeGrammarTree findNode(String grammarName) {
+ if ( grammarName==null ) {
+ return null;
+ }
+ if ( grammarName.equals(this.grammar.name) ) {
+ return this;
+ }
+ CompositeGrammarTree n = null;
+ for (int i = 0; n==null && children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ n = child.findNode(grammarName);
+ }
+ return n;
+ }
+
+ /** Return a postorder list of grammars; root is last in list */
+ public List<Grammar> getPostOrderedGrammarList() {
+ List<Grammar> grammars = new ArrayList<Grammar>();
+ _getPostOrderedGrammarList(grammars);
+ return grammars;
+ }
+
+ /** work for getPostOrderedGrammarList */
+ protected void _getPostOrderedGrammarList(List<Grammar> grammars) {
+ for (int i = 0; children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ child._getPostOrderedGrammarList(grammars);
+ }
+ grammars.add(this.grammar);
+ }
+
+ /** Return a preorder list of grammars; root is first in list */
+ public List<Grammar> getPreOrderedGrammarList() {
+ List<Grammar> grammars = new ArrayList<Grammar>();
+ _getPreOrderedGrammarList(grammars);
+ return grammars;
+ }
+
+ protected void _getPreOrderedGrammarList(List<Grammar> grammars) {
+ grammars.add(this.grammar);
+ for (int i = 0; children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ child._getPreOrderedGrammarList(grammars);
+ }
+ }
+
+ public void trimLexerImportsIntoCombined() {
+ CompositeGrammarTree p = this;
+ if ( p.grammar.type == Grammar.LEXER && p.parent!=null &&
+ p.parent.grammar.type == Grammar.COMBINED )
+ {
+ //System.out.println("wacking "+p.grammar.name+" from "+p.parent.grammar.name);
+ p.parent.children.remove(this);
+ }
+ for (int i = 0; children!=null && i < children.size(); i++) {
+ CompositeGrammarTree child = children.get(i);
+ child.trimLexerImportsIntoCombined();
+ }
+ }
+} \ No newline at end of file