/* * [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 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(); } 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 getPostOrderedGrammarList() { List grammars = new ArrayList(); _getPostOrderedGrammarList(grammars); return grammars; } /** work for getPostOrderedGrammarList */ protected void _getPostOrderedGrammarList(List 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 getPreOrderedGrammarList() { List grammars = new ArrayList(); _getPreOrderedGrammarList(grammars); return grammars; } protected void _getPreOrderedGrammarList(List 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(); } } }