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.Tool;
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.*;
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.analysis.DFA;
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.codegen.CodeGenerator;
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.codegen.*;
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.grammar.v3.*;
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.misc.*;
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.misc.Utils;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.*;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.runtime.tree.CommonTreeNodeStream;
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.ST;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.STGroup;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.STGroupString;
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.io.*;
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.*;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** Represents a grammar in memory. */
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic class Grammar {
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String SYNPRED_RULE_PREFIX = "synpred";
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String GRAMMAR_FILE_EXTENSION = ".g";
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** used for generating lexer temp files */
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String LEXER_GRAMMAR_FILE_EXTENSION = ".g";
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int INITIAL_DECISION_LIST_SIZE = 300;
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int INVALID_RULE_INDEX = -1;
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// the various kinds of labels. t=type, id=ID, types+=type ids+=ID
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int RULE_LABEL = 1;
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int TOKEN_LABEL = 2;
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int RULE_LIST_LABEL = 3;
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int TOKEN_LIST_LABEL = 4;
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public static final int CHAR_LABEL = 5; // used in lexer for x='a'
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public static final int WILDCARD_TREE_LABEL = 6; // Used in tree grammar x=.
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public static final int WILDCARD_TREE_LIST_LABEL = 7; // Used in tree grammar x+=.
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public static String[] LabelTypeToString =
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{"<invalid>", "rule", "token", "rule-list", "token-list", "wildcard-tree", "wildcard-tree-list"};
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String ARTIFICIAL_TOKENS_RULENAME = "Tokens";
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String FRAGMENT_RULE_MODIFIER = "fragment";
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String SYNPREDGATE_ACTION_NAME = "synpredgate";
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** When converting ANTLR char and string literals, here is the
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  value set of escape chars.
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static int ANTLRLiteralEscapedCharValue[] = new int[255];
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given a char, we need to be able to show as an ANTLR literal.
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static String ANTLRLiteralCharValueEscape[] = new String[255];
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	static {
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['n'] = '\n';
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['r'] = '\r';
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['t'] = '\t';
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['b'] = '\b';
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['f'] = '\f';
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['\\'] = '\\';
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['\''] = '\'';
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralEscapedCharValue['"'] = '"';
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\n'] = "\\n";
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\r'] = "\\r";
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\t'] = "\\t";
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\b'] = "\\b";
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\f'] = "\\f";
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\\'] = "\\\\";
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLiteralCharValueEscape['\''] = "\\'";
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int LEXER = 1;
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int PARSER = 2;
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int TREE_PARSER = 3;
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final int COMBINED = 4;
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String[] grammarTypeToString = new String[] {
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"<invalid>",
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"lexer",
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"parser",
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"tree",
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"combined"
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	};
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String[] grammarTypeToFileNameSuffix = new String[] {
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"<invalid>",
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"Lexer",
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"Parser",
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"", // no suffix for tree grammars
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		"Parser" // if combined grammar, gen Parser and Lexer will be done later
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	};
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Set of valid imports.  E.g., can only import a tree parser into
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  another tree parser.  Maps delegate to set of delegator grammar types.
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  validDelegations.get(LEXER) gives list of the kinds of delegators
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  that can import lexers.
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static MultiMap<Integer,Integer> validDelegations =
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new MultiMap<Integer,Integer>() {
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(LEXER, LEXER);
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(LEXER, PARSER);
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(LEXER, COMBINED);
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(PARSER, PARSER);
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(PARSER, COMBINED);
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				map(TREE_PARSER, TREE_PARSER);
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// TODO: allow COMBINED
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// map(COMBINED, COMBINED);
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		};
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** This is the buffer of *all* tokens found in the grammar file
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  including whitespace tokens etc...  I use this to extract
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  lexer rules from combined grammars.
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public CommonTokenStream tokenBuffer;
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String IGNORE_STRING_IN_GRAMMAR_FILE_NAME = "__";
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String AUTO_GENERATED_TOKEN_NAME_PREFIX = "T__";
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static class Decision {
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public Grammar grammar;
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public int decision;
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public NFAState startState;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public GrammarAST blockAST;
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public DFA dfa;
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public class LabelElementPair {
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public Token label;
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public GrammarAST elementRef;
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public String referencedRuleName;
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/** Has an action referenced the label?  Set by ActionAnalysis.g
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 *  Currently only set for rule labels.
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		 */
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public boolean actionReferencesLabel;
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public int type; // in {RULE_LABEL,TOKEN_LABEL,RULE_LIST_LABEL,TOKEN_LIST_LABEL}
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public LabelElementPair(Token label, GrammarAST elementRef) {
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.label = label;
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.elementRef = elementRef;
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.referencedRuleName = elementRef.getText();
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public Rule getReferencedRule() {
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return getRule(referencedRuleName);
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		public String toString() {
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return elementRef.toString();
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** What name did the user provide for this grammar? */
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String name;
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** What type of grammar is this: lexer, parser, tree walker */
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int type;
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** A list of options specified at the grammar level such as language=Java.
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  The value can be an AST for complicated values such as character sets.
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  There may be code generator specific options in here.  I do no
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  interpretation of the key/value pairs...they are simply available for
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  who wants them.
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Map options;
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Set legalLexerOptions =
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashSet() {
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("language"); add("tokenVocab");
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("TokenLabelType");
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("superClass");
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("filter");
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("k");
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("backtrack");
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("memoize");
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			};
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Set legalParserOptions =
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashSet() {
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("language"); add("tokenVocab");
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("output"); add("rewrite"); add("ASTLabelType");
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("TokenLabelType");
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("superClass");
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("k");
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("backtrack");
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("memoize");
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			};
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public static final Set legalTreeParserOptions =
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        new HashSet() {
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            {
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("language"); add("tokenVocab");
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("output"); add("rewrite"); add("ASTLabelType");
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("TokenLabelType");
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("superClass");
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("k");
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("backtrack");
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("memoize");
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                add("filter");
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        };
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Set doNotCopyOptionsToLexer =
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new HashSet() {
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("output"); add("ASTLabelType"); add("superClass");
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("k"); add("backtrack"); add("memoize"); add("rewrite");
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		};
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Map defaultOptions =
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashMap() {
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					put("language","Java");
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			};
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Set legalBlockOptions =
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashSet() {{add("k"); add("greedy"); add("backtrack"); add("memoize");}};
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** What are the default options for a subrule? */
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Map defaultBlockOptions =
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashMap() {{put("greedy","true");}};
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Map defaultLexerBlockOptions =
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new HashMap() {{put("greedy","true");}};
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	// Token options are here to avoid contaminating Token object in runtime
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Legal options for terminal refs like ID<node=MyVarNode> */
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final Set legalTokenOptions =
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new HashSet() {
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add(defaultTokenOption);
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("type");
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("text");
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				add("assoc");
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		};
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static final String defaultTokenOption = "node";
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Is there a global fixed lookahead set for this grammar?
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If 0, nothing specified.  -1 implies we have not looked at
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the options table yet to set k.
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected int global_k = -1;
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Map a scope to a map of name:action pairs.
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Map<String, Map<String,GrammarAST>>
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  The code generator will use this to fill holes in the output files.
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  I track the AST node for the action in case I need the line number
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  for errors.
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	private Map<String, Map<String, Object>> actions =
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new HashMap<String, Map<String, Object>>();
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The NFA that represents the grammar with edges labelled with tokens
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  or epsilon.  It is more suitable to analysis than an AST representation.
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFA nfa;
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected NFAFactory factory;
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If this grammar is part of a larger composite grammar via delegate
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  statement, then this points at the composite.  The composite holds
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  a global list of rules, token types, decision numbers, etc...
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public CompositeGrammar composite;
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** A pointer back into grammar tree.  Needed so we can add delegates. */
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public CompositeGrammarTree compositeTreeNode;
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If this is a delegate of another grammar, this is the label used
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as an instance var by that grammar to point at this grammar. null
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  if no label was specified in the delegate statement.
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String label;
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** TODO: hook this to the charVocabulary option */
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected IntSet charVocabulary = null;
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** For ANTLRWorks, we want to be able to map a line:col to a specific
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  decision DFA so it can display DFA.
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	Map lineColumnToLookaheadDFAMap = new HashMap();
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Tool tool;
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The unique set of all rule references in any rule; set of tree node
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  objects so two refs to same rule can exist but at different line/position.
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Set<GrammarAST> ruleRefs = new HashSet<GrammarAST>();
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Set<GrammarAST> scopedRuleRefs = new HashSet();
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The unique set of all token ID references in any rule */
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Set<Token> tokenIDRefs = new HashSet<Token>();
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Be able to assign a number to every decision in grammar;
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  decisions in 1..n
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected int decisionCount = 0;
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** A list of all rules that are in any left-recursive cycle.  There
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  could be multiple cycles, but this is a flat list of all problematic
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  rules. This is stuff we couldn't refactor to precedence rule.
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Set<Rule> leftRecursiveRules;
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** An external tool requests that DFA analysis abort prematurely.  Stops
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  at DFA granularity, which are limited to a DFA size and time computation
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as failsafe.
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected boolean externalAnalysisAbort;
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int numNonLLStar = 0; // hack to track for -report
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** When we read in a grammar, we track the list of syntactic predicates
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and build faux rules for them later.  See my blog entry Dec 2, 2005:
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  http://www.antlr.org/blog/antlr3/lookahead.tml
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This maps the name (we make up) for a pred to the AST grammar fragment.
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected LinkedHashMap<String, GrammarAST> nameToSynpredASTMap;
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Each left-recursive precedence rule must define precedence array
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  for binary operators like:
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  	static int[] e_prec = new int[tokenNames.length];
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  	static {
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver   	 *  		e_prec[75] = 1;
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  	}
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Track and we push into parser later; this is computed
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  early when we look for prec rules.
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<String> precRuleInitCodeBlocks = new ArrayList<String>();
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** At least one rule has memoize=true */
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public boolean atLeastOneRuleMemoizes;
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** At least one backtrack=true in rule or decision or grammar. */
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public boolean atLeastOneBacktrackOption;
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Was this created from a COMBINED grammar? */
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean implicitLexer;
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Map a rule to it's Rule object */
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected LinkedHashMap<String,Rule> nameToRuleMap = new LinkedHashMap<String,Rule>();
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If this rule is a delegate, some rules might be overridden; don't
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  want to gen code for them.
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<String> overriddenRules = new HashSet<String>();
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The list of all rules referenced in this grammar, not defined here,
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and defined in a delegate grammar.  Not all of these will be generated
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  in the recognizer for this file; only those that are affected by rule
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  definitions in this grammar.  I am not sure the Java target will need
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  this but I'm leaving in case other targets need it.
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  see NameSpaceChecker.lookForReferencesToUndefinedSymbols()
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Set<Rule> delegatedRuleReferences = new HashSet();
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** The ANTLRParser tracks lexer rules when reading combined grammars
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  so we can build the Tokens rule.
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<String> lexerRuleNamesInCombined = new ArrayList<String>();
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track the scopes defined outside of rules and the scopes associated
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  with all rules (even if empty).
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Map scopes = new HashMap();
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** An AST that records entire input grammar with all rules.  A simple
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  grammar with one rule, "grammar t; a : A | B ;", looks like:
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 * ( grammar t ( rule a ( BLOCK ( ALT A ) ( ALT B ) ) <end-of-rule> ) )
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected GrammarAST grammarTree = null;
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Each subrule/rule is a decision point and we must track them so we
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  can go back later and build DFA predictors for them.  This includes
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  all the rules, subrules, optional blocks, ()+, ()* etc...
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Vector<Decision> indexToDecision =
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new Vector<Decision>(INITIAL_DECISION_LIST_SIZE);
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If non-null, this is the code generator we will use to generate
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  recognizers in the target language.
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected CodeGenerator generator;
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NameSpaceChecker nameSpaceChecker = new NameSpaceChecker(this);
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public LL1Analyzer ll1Analyzer = new LL1Analyzer(this);
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** For merged lexer/parsers, we must construct a separate lexer spec.
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is the template for lexer; put the literals first then the
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  regular rules.  We don't need to specify a token vocab import as
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  I make the new grammar import from the old all in memory; don't want
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to force it to read from the disk.  Lexer grammar will have same
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  name as original grammar but will be in different filename.  Foo.g
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  with combined grammar will have FooParser.java generated and
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Foo__.g with again Foo inside.  It will however generate FooLexer.java
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as it's a lexer grammar.  A bit odd, but autogenerated.  Can tweak
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  later if we want.
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected String lexerGrammarTemplate =
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"grammar(name, options, imports, actionNames, actions, literals, rules) ::= <<\n" +
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"lexer grammar <name>;\n" +
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<if(options)>" +
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"options {\n" +
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"  <options:{it | <it.name>=<it.value>;<\\n>}>\n" +
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"}<\\n>\n" +
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<endif>\n" +
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<if(imports)>import <imports; separator=\", \">;<endif>\n" +
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<actionNames,actions:{n,a|@<n> {<a>\\}\n}>\n" +
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<literals:{it | <it.ruleName> : <it.literal> ;\n}>\n" +
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			"<rules>\n" +
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			">>\n";
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected ST lexerGrammarST;
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** What file name holds this grammar? */
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected String fileName;
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** How long in ms did it take to build DFAs for this grammar?
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If this grammar is a combined grammar, it only records time for
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the parser grammar component.  This only records the time to
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  do the LL(*) work; NFA->DFA conversion.
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public long DFACreationWallClockTimeInMS;
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int numberOfSemanticPredicates = 0;
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int numberOfManualLookaheadOptions = 0;
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Integer> setOfNondeterministicDecisionNumbers = new HashSet<Integer>();
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Integer> setOfNondeterministicDecisionNumbersResolvedWithPredicates =
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		new HashSet<Integer>();
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track decisions with syn preds specified for reporting.
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is the a set of BLOCK type AST nodes.
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<GrammarAST> blocksWithSynPreds = new HashSet();
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track decisions that actually use the syn preds in the DFA.
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Computed during NFA to DFA conversion.
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<DFA> decisionsWhoseDFAsUsesSynPreds = new HashSet<DFA>();
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track names of preds so we can avoid generating preds that aren't used
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Computed during NFA to DFA conversion.  Just walk accept states
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and look for synpreds because that is the only state target whose
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  incident edges can have synpreds.  Same is try for
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  decisionsWhoseDFAsUsesSynPreds.
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<String> synPredNamesUsedInDFA = new HashSet();
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track decisions with syn preds specified for reporting.
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is the a set of BLOCK type AST nodes.
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<GrammarAST> blocksWithSemPreds = new HashSet();
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track decisions that actually use the syn preds in the DFA. */
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<DFA> decisionsWhoseDFAsUsesSemPreds = new HashSet();
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected boolean allDecisionDFACreated = false;
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** We need a way to detect when a lexer grammar is autogenerated from
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  another grammar or we are just sending in a string representing a
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  grammar.  We don't want to generate a .tokens file, for example,
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  in such cases.
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected boolean builtFromString = false;
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Factored out the sanity checking code; delegate to it. */
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	GrammarSanity sanity = new GrammarSanity(this);
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Useful for asking questions about target during analysis */
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	Target target;
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Create a grammar from file name.  */
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar(Tool tool, String fileName, CompositeGrammar composite) {
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.composite = composite;
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setTool(tool);
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setFileName(fileName);
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// ensure we have the composite set to something
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( composite.delegateGrammarTreeRoot==null ) {
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.setDelegationRoot(this);
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		STGroup lexerGrammarSTG = new STGroupString(lexerGrammarTemplate);
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lexerGrammarST = lexerGrammarSTG.getInstanceOf("grammar");
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		target = CodeGenerator.loadLanguageTarget((String) getOption("language"));
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Useful for when you are sure that you are not part of a composite
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  already.  Used in Interp/RandomPhrase and testing.
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar() { this((Tool)null); }
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar(Tool tool) {
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setTool(tool);
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		builtFromString = true;
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite = new CompositeGrammar(this);
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		STGroup lexerGrammarSTG = new STGroupString(lexerGrammarTemplate);
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lexerGrammarST = lexerGrammarSTG.getInstanceOf("grammar");
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		target = CodeGenerator.loadLanguageTarget((String)getOption("language"));
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Used for testing; only useful on noncomposite grammars.*/
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar(String grammarString)
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			throws RecognitionException
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this(null, grammarString);
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Used for testing and Interp/RandomPhrase.  Only useful on
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  noncomposite grammars.
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar(Tool tool, String grammarString)
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		throws RecognitionException
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this(tool);
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setFileName("<string>");
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		StringReader r = new StringReader(grammarString);
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parseAndBuildAST(r);
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.assignTokenTypes();
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//composite.translateLeftRecursiveRules();
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		addRulesForSyntacticPredicates();
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.defineGrammarSymbols();
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//composite.createNFAs();
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkNameSpaceAndActions();
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setFileName(String fileName) {
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.fileName = fileName;
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getFileName() {
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return fileName;
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setName(String name) {
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( name==null ) {
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// don't error check autogenerated files (those with '__' in them)
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String saneFile = fileName.replace('\\', '/');
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int lastSlash = saneFile.lastIndexOf('/');
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String onlyFileName = saneFile.substring(lastSlash+1, fileName.length());
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !builtFromString ) {
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int lastDot = onlyFileName.lastIndexOf('.');
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String onlyFileNameNoSuffix = null;
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( lastDot < 0 ) {
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.error(ErrorManager.MSG_FILENAME_EXTENSION_ERROR, fileName);
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				onlyFileNameNoSuffix = onlyFileName+GRAMMAR_FILE_EXTENSION;
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				onlyFileNameNoSuffix = onlyFileName.substring(0,lastDot);
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !name.equals(onlyFileNameNoSuffix) ) {
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.error(ErrorManager.MSG_FILE_AND_GRAMMAR_NAME_DIFFER,
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   name,
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   fileName);
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.name = name;
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setGrammarContent(String grammarString) throws RecognitionException {
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		StringReader r = new StringReader(grammarString);
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parseAndBuildAST(r);
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.assignTokenTypes();
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.defineGrammarSymbols();
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void parseAndBuildAST()
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		throws IOException
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		FileReader fr = null;
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		BufferedReader br = null;
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			fr = new FileReader(fileName);
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			br = new BufferedReader(fr);
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			parseAndBuildAST(br);
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			br.close();
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			br = null;
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		finally {
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( br!=null ) {
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				br.close();
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void parseAndBuildAST(Reader r) {
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// BUILD AST FROM GRAMMAR
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLexer lexer;
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexer = new ANTLRLexer(new ANTLRReaderStream(r));
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		} catch (IOException e) {
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.internalError("unexpected stream error from parsing "+fileName, e);
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lexer.setFileName(this.getFileName());
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		tokenBuffer = new CommonTokenStream(lexer);
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRParser parser = ANTLRParser.createParser(tokenBuffer);
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser.setFileName(this.getFileName());
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRParser.grammar__return result = null;
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			result = parser.grammar_(this);
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.internalError("unexpected parser recognition error from "+fileName, re);
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        dealWithTreeFilterMode(); // tree grammar and filter=true?
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( lexer.hasASTOperator && !buildAST() ) {
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Object value = getOption("output");
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( value == null ) {
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarWarning(ErrorManager.MSG_REWRITE_OR_OP_WITH_NO_OUTPUT_OPTION,
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										    this, null);
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				setOption("output", "AST", null);
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(ErrorManager.MSG_AST_OP_WITH_NON_AST_OUTPUT_OPTION,
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  this, null, value);
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setGrammarTree((GrammarAST)result.getTree());
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//if ( grammarTree!=null ) System.out.println("grammar tree: "+grammarTree.toStringTree());
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		grammarTree.setUnknownTokenBoundaries();
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setFileName(lexer.getFileName()); // the lexer #src might change name
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( grammarTree==null || grammarTree.findFirstType(ANTLRParser.RULE)==null ) {
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_NO_RULES, getFileName());
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    protected void dealWithTreeFilterMode() {
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Object filterMode = (String)getOption("filter");
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( type==TREE_PARSER && filterMode!=null && filterMode.toString().equals("true") ) {
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // check for conflicting options
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // filter => backtrack=true
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // filter&&output=AST => rewrite=true
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // filter&&output!=AST => error
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // any deviation from valid option set is an error
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Object backtrack = (String)getOption("backtrack");
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Object output = getOption("output");
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Object rewrite = getOption("rewrite");
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( backtrack!=null && !backtrack.toString().equals("true") ) {
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ErrorManager.error(ErrorManager.MSG_CONFLICTING_OPTION_IN_TREE_FILTER,
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   "backtrack", backtrack);
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( output!=null && !output.toString().equals("AST") ) {
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ErrorManager.error(ErrorManager.MSG_CONFLICTING_OPTION_IN_TREE_FILTER,
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   "output", output);
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                setOption("output", "", null);
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( rewrite!=null && !rewrite.toString().equals("true") ) {
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                ErrorManager.error(ErrorManager.MSG_CONFLICTING_OPTION_IN_TREE_FILTER,
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   "rewrite", rewrite);
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // set options properly
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            setOption("backtrack", "true", null);
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( output!=null && output.toString().equals("AST") ) {
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                setOption("rewrite", "true", null);
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // @synpredgate set to state.backtracking==1 by code gen when filter=true
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // superClass set in template target::treeParser
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void translateLeftRecursiveRule(GrammarAST ruleAST) {
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println(ruleAST.toStringTree());
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CommonTreeNodeStream input = new CommonTreeNodeStream(ruleAST);
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		LeftRecursiveRuleAnalyzer leftRecursiveRuleWalker =
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new LeftRecursiveRuleAnalyzer(input, this, ruleAST.enclosingRuleName);
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean isLeftRec = false;
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("TESTING "+ruleAST.enclosingRuleName);
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			isLeftRec = leftRecursiveRuleWalker.rec_rule(this);
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_BAD_AST_STRUCTURE, re);
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !isLeftRec ) return;
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<String> rules = new ArrayList<String>();
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		rules.add( leftRecursiveRuleWalker.getArtificialPrecStartRule() ) ;
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		rules.add( leftRecursiveRuleWalker.getArtificialOpPrecRule() );
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		rules.add( leftRecursiveRuleWalker.getArtificialPrimaryRule() );
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (String r : rules) {
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST t = parseArtificialRule(r);
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			addRule(grammarTree, t);
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println(t.toStringTree());
734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//precRuleInitCodeBlocks.add( precRuleWalker.getOpPrecJavaCode() );
737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineGrammarSymbols() {
740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( Tool.internalOption_PrintGrammarTree ) {
741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println(grammarTree.toStringList());
742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// DEFINE RULES
745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("### define "+name+" rules");
746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DefineGrammarItemsWalker defineItemsWalker = new DefineGrammarItemsWalker(new CommonTreeNodeStream(getGrammarTree()));
747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			defineItemsWalker.grammar_(this);
749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_BAD_AST_STRUCTURE,
752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   re);
753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** ANALYZE ACTIONS, LOOKING FOR LABEL AND ATTR REFS, sanity check */
757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void checkNameSpaceAndActions() {
758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		examineAllExecutableActions();
759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkAllRulesForUselessLabels();
760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		nameSpaceChecker.checkConflicts();
762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Many imports are illegal such as lexer into a tree grammar */
765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean validImport(Grammar delegate) {
766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<Integer> validDelegators = validDelegations.get(delegate.type);
767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return validDelegators!=null && validDelegators.contains(this.type);
768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If the grammar is a combined grammar, return the text of the implicit
771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  lexer grammar.
772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getLexerGrammar() {
774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( lexerGrammarST.getAttribute("literals")==null &&
775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 lexerGrammarST.getAttribute("rules")==null )
776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// if no rules, return nothing
778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lexerGrammarST.add("name", name);
781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// if there are any actions set for lexer, pass them in
782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getActions().get("lexer")!=null ) {
783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexerGrammarST.add("actionNames",
784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										getActions().get("lexer").keySet());
785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexerGrammarST.add("actions",
786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										getActions().get("lexer").values());
787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// make sure generated grammar has the same options
789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( options!=null ) {
790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Iterator optionNames = options.keySet().iterator();
791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			while (optionNames.hasNext()) {
792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String optionName = (String) optionNames.next();
793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !doNotCopyOptionsToLexer.contains(optionName) ) {
794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Object value = options.get(optionName);
795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					lexerGrammarST.addAggr("options.{name,value}", optionName, value);
796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return lexerGrammarST.render();
800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getImplicitlyGeneratedLexerFileName() {
803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return name+
804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   IGNORE_STRING_IN_GRAMMAR_FILE_NAME +
805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   LEXER_GRAMMAR_FILE_EXTENSION;
806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the name of the generated recognizer; may or may not be same
809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as grammar name.
810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Recognizer is TParser and TLexer from T if combined, else
811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  just use T regardless of grammar type.
812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getRecognizerName() {
814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String suffix = "";
815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<Grammar> grammarsFromRootToMe = composite.getDelegators(this);
816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("grammarsFromRootToMe="+grammarsFromRootToMe);
817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String qualifiedName = name;
818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( grammarsFromRootToMe!=null ) {
819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			StringBuffer buf = new StringBuffer();
820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (Grammar g : grammarsFromRootToMe) {
821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(g.name);
822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append('_');
823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			buf.append(name);
825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			qualifiedName = buf.toString();
826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( type==Grammar.COMBINED ||
828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 (type==Grammar.LEXER && implicitLexer) )
829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			suffix = Grammar.grammarTypeToFileNameSuffix[type];
831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return qualifiedName+suffix;
833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Parse a rule we add artificially that is a list of the other lexer
836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  rules like this: "Tokens : ID | INT | SEMI ;"  nextToken() will invoke
837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  this to set the current token.  Add char literals before
838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the rule references.
839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If in filter mode, we want every alt to backtrack and we need to
841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  do k=1 to force the "first token def wins" rule.  Otherwise, the
842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  longest-match rule comes into play with LL(*).
843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  The ANTLRParser antlr.g file now invokes this when parsing a lexer
845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  grammar, which I think is proper even though it peeks at the info
846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  that later phases will (re)compute.  It gets a list of lexer rules
847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and builds a string representing the rule; then it creates a parser
848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and adds the resulting tree to the grammar's tree.
849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public GrammarAST addArtificialMatchTokensRule(GrammarAST grammarAST,
851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												   List<String> ruleNames,
852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												   List<String> delegateNames,
853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												   boolean filterMode) {
854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ST matchTokenRuleST = null;
855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( filterMode ) {
856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			matchTokenRuleST = new ST(
857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ARTIFICIAL_TOKENS_RULENAME+
858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					" options {k=1; backtrack=true;} : <rules; separator=\"|\">;");
859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			matchTokenRuleST = new ST(
862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ARTIFICIAL_TOKENS_RULENAME+" : <rules; separator=\"|\">;");
863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Now add token rule references
866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < ruleNames.size(); i++) {
867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String rname = (String) ruleNames.get(i);
868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			matchTokenRuleST.add("rules", rname);
869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < delegateNames.size(); i++) {
871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String dname = (String) delegateNames.get(i);
872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			matchTokenRuleST.add("rules", dname+".Tokens");
873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("tokens rule: "+matchTokenRuleST.toString());
875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST r = parseArtificialRule(matchTokenRuleST.render());
876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		addRule(grammarAST, r);
877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//addRule((GrammarAST)parser.getAST());
878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//return (GrammarAST)parser.getAST();
879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return r;
880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public GrammarAST parseArtificialRule(String ruleText) {
883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRLexer lexer = new ANTLRLexer(new ANTLRStringStream(ruleText));
884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRParser parser = ANTLRParser.createParser(new CommonTokenStream(lexer));
885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser.setGrammar(this);
886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		parser.setGrammarType(this.type);
887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ANTLRParser.rule_return result = parser.rule();
889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return (GrammarAST)result.getTree();
890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (Exception e) {
892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_ERROR_CREATING_ARTIFICIAL_RULE,
893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   e);
894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void addRule(GrammarAST grammarTree, GrammarAST t) {
899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST p = null;
900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < grammarTree.getChildCount(); i++ ) {
901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = (GrammarAST)grammarTree.getChild(i);
902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if (p == null || p.getType() == ANTLRParser.RULE || p.getType() == ANTLRParser.PREC_RULE) {
903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				break;
904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if (p != null) {
908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			grammarTree.addChild(t);
909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** for any syntactic predicates, we need to define rules for them; they will get
913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  defined automatically like any other rule. :)
914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected List getArtificialRulesForSyntacticPredicates(LinkedHashMap<String,GrammarAST> nameToSynpredASTMap)
916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<GrammarAST> rules = new ArrayList<GrammarAST>();
918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nameToSynpredASTMap==null ) {
919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return rules;
920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean isLexer = grammarTree.getType()==ANTLRParser.LEXER_GRAMMAR;
922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (String synpredName : nameToSynpredASTMap.keySet()) {
923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST fragmentAST = nameToSynpredASTMap.get(synpredName);
924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST ruleAST =
925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ANTLRParser.createSimpleRuleAST(synpredName,
926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												fragmentAST,
927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver												isLexer);
928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			rules.add(ruleAST);
929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return rules;
931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void addRulesForSyntacticPredicates() {
934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Get syn pred rules and add to existing tree
935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List synpredRules =
936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			getArtificialRulesForSyntacticPredicates(nameToSynpredASTMap);
937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < synpredRules.size(); i++) {
938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			GrammarAST rAST = (GrammarAST) synpredRules.get(i);
939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			grammarTree.addChild(rAST);
940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Walk the list of options, altering this Grammar object according
944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to any I recognize.
945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void processOptions() {
946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Iterator optionNames = options.keySet().iterator();
947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		while (optionNames.hasNext()) {
948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String optionName = (String) optionNames.next();
949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Object value = options.get(optionName);
950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( optionName.equals("tokenVocab") ) {
951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Define all the rule begin/end NFAStates to solve forward reference
958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  issues.  Critical for composite grammars too.
959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is normally called on all root/delegates manually and then
960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  buildNFA() is called afterwards because the NFA construction needs
961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to see rule start/stop states from potentially every grammar. Has
962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to be have these created a priori.  Testing routines will often
963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  just call buildNFA(), which forces a call to this method if not
964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  done already. Works ONLY for single noncomposite grammars.
965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void createRuleStartAndStopNFAStates() {
967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("### createRuleStartAndStopNFAStates "+getGrammarTypeString()+" grammar "+name+" NFAs");
968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nfa!=null ) {
969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		nfa = new NFA(this);
972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		factory = new NFAFactory(nfa);
973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Collection rules = getRules();
975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator itr = rules.iterator(); itr.hasNext();) {
976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule r = (Rule) itr.next();
977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String ruleName = r.name;
978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAState ruleBeginState = factory.newState();
979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleBeginState.setDescription("rule "+ruleName+" start");
980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleBeginState.enclosingRule = r;
981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.startState = ruleBeginState;
982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAState ruleEndState = factory.newState();
983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleEndState.setDescription("rule "+ruleName+" end");
984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleEndState.setAcceptState(true);
985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleEndState.enclosingRule = r;
986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.stopState = ruleEndState;
987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void buildNFA() {
991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nfa==null ) {
992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			createRuleStartAndStopNFAStates();
993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nfa.complete ) {
995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// don't let it create more than once; has side-effects
996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("### build "+getGrammarTypeString()+" grammar "+name+" NFAs");
999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getRules().size()==0 ) {
1000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CommonTreeNodeStream input = new CommonTreeNodeStream(getGrammarTree());
1004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		TreeToNFAConverter nfaBuilder = new TreeToNFAConverter(input, this, nfa, factory);
1005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
1006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			nfaBuilder.grammar_();
1007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
1009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_BAD_AST_STRUCTURE,
1010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   name,
1011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   re);
1012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		nfa.complete = true;
1014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** For each decision in this grammar, compute a single DFA using the
1017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  NFA states associated with the decision.  The DFA construction
1018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  determines whether or not the alternatives in the decision are
1019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  separable using a regular lookahead language.
1020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
1021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Store the lookahead DFAs in the AST created from the user's grammar
1022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  so the code generator or whoever can easily access it.
1023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
1024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is a separate method because you might want to create a
1025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Grammar without doing the expensive analysis.
1026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void createLookaheadDFAs() {
1028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		createLookaheadDFAs(true);
1029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void createLookaheadDFAs(boolean wackTempStructures) {
1032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nfa==null ) {
1033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			buildNFA();
1034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// CHECK FOR LEFT RECURSION; Make sure we can actually do analysis
1037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		checkAllRulesForLeftRecursion();
1038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
1040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// was there a severe problem while sniffing the grammar?
1041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( ErrorManager.doNotAttemptAnalysis() ) {
1042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
1045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		long start = System.currentTimeMillis();
1047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("### create DFAs");
1049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numDecisions = getNumberOfDecisions();
1050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( NFAToDFAConverter.SINGLE_THREADED_NFA_CONVERSION ) {
1051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (int decision=1; decision<=numDecisions; decision++) {
1052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				NFAState decisionStartState = getDecisionNFAStartState(decision);
1053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( leftRecursiveRules.contains(decisionStartState.enclosingRule) ) {
1054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// don't bother to process decisions within left recursive rules.
1055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( composite.watchNFAConversion ) {
1056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						System.out.println("ignoring decision "+decision+
1057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										   " within left-recursive rule "+decisionStartState.enclosingRule.name);
1058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
1060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !externalAnalysisAbort && decisionStartState.getNumberOfTransitions()>1 ) {
1062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					Rule r = decisionStartState.enclosingRule;
1063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( r.isSynPred && !synPredNamesUsedInDFA.contains(r.name) ) {
1064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						continue;
1065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					DFA dfa = null;
1067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// if k=* or k=1, try LL(1)
1068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( getUserMaxLookahead(decision)==0 ||
1069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						 getUserMaxLookahead(decision)==1 )
1070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					{
1071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						dfa = createLL_1_LookaheadDFA(decision);
1072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( dfa==null ) {
1074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						if ( composite.watchNFAConversion ) {
1075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							System.out.println("decision "+decision+
1076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											   " not suitable for LL(1)-optimized DFA analysis");
1077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						}
1078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						dfa = createLookaheadDFA(decision, wackTempStructures);
1079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( dfa.startState==null ) {
1081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						// something went wrong; wipe out DFA
1082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						setLookaheadDFA(decision, null);
1083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					if ( Tool.internalOption_PrintDFA ) {
1085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						System.out.println("DFA d="+decision);
1086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						FASerializer serializer = new FASerializer(nfa.grammar);
1087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						String result = serializer.serialize(dfa.startState);
1088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						System.out.println(result);
1089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					}
1090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
1094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.info("two-threaded DFA conversion");
1095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// create a barrier expecting n DFA and this main creation thread
1096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Barrier barrier = new Barrier(3);
1097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// assume 2 CPU for now
1098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int midpoint = numDecisions/2;
1099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAConversionThread t1 =
1100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				new NFAConversionThread(this, barrier, 1, midpoint);
1101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new Thread(t1).start();
1102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( midpoint == (numDecisions/2) ) {
1103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				midpoint++;
1104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAConversionThread t2 =
1106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				new NFAConversionThread(this, barrier, midpoint, numDecisions);
1107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new Thread(t2).start();
1108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// wait for these two threads to finish
1109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			try {
1110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				barrier.waitForRelease();
1111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			catch(InterruptedException e) {
1113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.internalError("what the hell? DFA interruptus", e);
1114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		long stop = System.currentTimeMillis();
1118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DFACreationWallClockTimeInMS = stop - start;
1119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// indicate that we've finished building DFA (even if #decisions==0)
1121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		allDecisionDFACreated = true;
1122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public DFA createLL_1_LookaheadDFA(int decision) {
1125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
1126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String enclosingRule = d.startState.enclosingRule.name;
1127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = d.startState.enclosingRule;
1128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NFAState decisionStartState = getDecisionNFAStartState(decision);
1129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( composite.watchNFAConversion ) {
1131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println("--------------------\nattempting LL(1) DFA (d="
1132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   +decisionStartState.getDecisionNumber()+") for "+
1133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   decisionStartState.getDescription());
1134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r.isSynPred && !synPredNamesUsedInDFA.contains(enclosingRule) ) {
1137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
1138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// compute lookahead for each alt
1141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numAlts = getNumberOfAltsForDecisionNFA(decisionStartState);
1142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		LookaheadSet[] altLook = new LookaheadSet[numAlts+1];
1143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int alt = 1; alt <= numAlts; alt++) {
1144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int walkAlt =
1145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				decisionStartState.translateDisplayAltToWalkAlt(alt);
1146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAState altLeftEdge = getNFAStateForAltOfDecision(decisionStartState, walkAlt);
1147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
1148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("alt "+alt+" start state = "+altStartState.stateNumber);
1149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			altLook[alt] = ll1Analyzer.LOOK(altStartState);
1150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("alt "+alt+": "+altLook[alt].toString(this));
1151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// compare alt i with alt j for disjointness
1154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean decisionIsLL_1 = true;
1155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverouter:
1156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 1; i <= numAlts; i++) {
1157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (int j = i+1; j <= numAlts; j++) {
1158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				/*
1159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				System.out.println("compare "+i+", "+j+": "+
1160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   altLook[i].toString(this)+" with "+
1161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   altLook[j].toString(this));
1162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				*/
1163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				LookaheadSet collision = altLook[i].intersection(altLook[j]);
1164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !collision.isNil() ) {
1165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					//System.out.println("collision (non-LL(1)): "+collision.toString(this));
1166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					decisionIsLL_1 = false;
1167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break outer;
1168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean foundConfoundingPredicate =
1173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ll1Analyzer.detectConfoundingPredicates(decisionStartState);
1174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( decisionIsLL_1 && !foundConfoundingPredicate ) {
1175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// build an LL(1) optimized DFA with edge for each altLook[i]
1176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( NFAToDFAConverter.debug ) {
1177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				System.out.println("decision "+decision+" is simple LL(1)");
1178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			DFA lookaheadDFA = new LL1DFA(decision, decisionStartState, altLook);
1180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			setLookaheadDFA(decision, lookaheadDFA);
1181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			updateLineColumnToLookaheadDFAMap(lookaheadDFA);
1182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return lookaheadDFA;
1183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// not LL(1) but perhaps we can solve with simplified predicate search
1186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// even if k=1 set manually, only resolve here if we have preds; i.e.,
1187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// don't resolve etc...
1188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
1190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		SemanticContext visiblePredicates =
1191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ll1Analyzer.getPredicates(decisionStartState);
1192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean foundConfoundingPredicate =
1193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ll1Analyzer.detectConfoundingPredicates(decisionStartState);
1194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			*/
1195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// exit if not forced k=1 or we found a predicate situation we
1197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// can't handle: predicates in rules invoked from this decision.
1198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getUserMaxLookahead(decision)!=1 || // not manually set to k=1
1199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 !getAutoBacktrackMode(decision) ||
1200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 foundConfoundingPredicate )
1201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("trying LL(*)");
1203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
1204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<IntervalSet> edges = new ArrayList<IntervalSet>();
1207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 1; i < altLook.length; i++) {
1208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			LookaheadSet s = altLook[i];
1209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			edges.add((IntervalSet)s.tokenTypeSet);
1210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<IntervalSet> disjoint = makeEdgeSetsDisjoint(edges);
1212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("disjoint="+disjoint);
1213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		MultiMap<IntervalSet, Integer> edgeMap = new MultiMap<IntervalSet, Integer>();
1215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < disjoint.size(); i++) {
1216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			IntervalSet ds = (IntervalSet) disjoint.get(i);
1217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (int alt = 1; alt < altLook.length; alt++) {
1218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				LookaheadSet look = altLook[alt];
1219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !ds.and(look.tokenTypeSet).isNil() ) {
1220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					edgeMap.map(ds, alt);
1221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("edge map: "+edgeMap);
1225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// TODO: how do we know we covered stuff?
1227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// build an LL(1) optimized DFA with edge for each altLook[i]
1229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DFA lookaheadDFA = new LL1DFA(decision, decisionStartState, edgeMap);
1230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setLookaheadDFA(decision, lookaheadDFA);
1231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// create map from line:col to decision DFA (for ANTLRWorks)
1233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		updateLineColumnToLookaheadDFAMap(lookaheadDFA);
1234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return lookaheadDFA;
1236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	private void updateLineColumnToLookaheadDFAMap(DFA lookaheadDFA) {
1239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST decisionAST = nfa.grammar.getDecisionBlockAST(lookaheadDFA.decisionNumber);
1240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int line = decisionAST.getLine();
1241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int col = decisionAST.getCharPositionInLine();
1242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		lineColumnToLookaheadDFAMap.put(new StringBuffer().append(line + ":")
1243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										.append(col).toString(), lookaheadDFA);
1244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected List<IntervalSet> makeEdgeSetsDisjoint(List<IntervalSet> edges) {
1247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		OrderedHashSet<IntervalSet> disjointSets = new OrderedHashSet<IntervalSet>();
1248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// walk each incoming edge label/set and add to disjoint set
1249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int numEdges = edges.size();
1250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int e = 0; e < numEdges; e++) {
1251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			IntervalSet t = (IntervalSet) edges.get(e);
1252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( disjointSets.contains(t) ) { // exact set present
1253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				continue;
1254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// compare t with set i for disjointness
1257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			IntervalSet remainder = t; // remainder starts out as whole set to add
1258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int numDisjointElements = disjointSets.size();
1259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (int i = 0; i < numDisjointElements; i++) {
1260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				IntervalSet s_i = (IntervalSet)disjointSets.get(i);
1261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( t.and(s_i).isNil() ) { // nothing in common
1263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
1264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//System.out.println(label+" collides with "+rl);
1266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// For any (s_i, t) with s_i&t!=nil replace with (s_i-t, s_i&t)
1268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// (ignoring s_i-t if nil; don't put in list)
1269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// Replace existing s_i with intersection since we
1271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// know that will always be a non nil character class
1272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				IntervalSet intersection = (IntervalSet)s_i.and(t);
1273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				disjointSets.set(i, intersection);
1274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// Compute s_i-t to see what is in current set and not in incoming
1276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				IntSet existingMinusNewElements = s_i.subtract(t);
1277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//System.out.println(s_i+"-"+t+"="+existingMinusNewElements);
1278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( !existingMinusNewElements.isNil() ) {
1279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// found a new character class, add to the end (doesn't affect
1280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// outer loop duration due to n computation a priori.
1281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					disjointSets.add(existingMinusNewElements);
1282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// anything left to add to the reachableLabels?
1285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				remainder = (IntervalSet)t.subtract(s_i);
1286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( remainder.isNil() ) {
1287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					break; // nothing left to add to set.  done!
1288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				t = remainder;
1291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !remainder.isNil() ) {
1293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				disjointSets.add(remainder);
1294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return disjointSets.elements();
1297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public DFA createLookaheadDFA(int decision, boolean wackTempStructures) {
1300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
1301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String enclosingRule = d.startState.enclosingRule.name;
1302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = d.startState.enclosingRule;
1303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("createLookaheadDFA(): "+enclosingRule+" dec "+decision+"; synprednames prev used "+synPredNamesUsedInDFA);
1305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NFAState decisionStartState = getDecisionNFAStartState(decision);
1306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		long startDFA=0,stopDFA=0;
1307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( composite.watchNFAConversion ) {
1308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println("--------------------\nbuilding lookahead DFA (d="
1309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   +decisionStartState.getDecisionNumber()+") for "+
1310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   decisionStartState.getDescription());
1311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			startDFA = System.currentTimeMillis();
1312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		DFA lookaheadDFA = new DFA(decision, decisionStartState);
1315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// Retry to create a simpler DFA if analysis failed (non-LL(*),
1316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// recursion overflow, or time out).
1317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean failed =
1318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lookaheadDFA.probe.isNonLLStarDecision() ||
1319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lookaheadDFA.probe.analysisOverflowed();
1320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( failed && lookaheadDFA.okToRetryDFAWithK1() ) {
1321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// set k=1 option and try again.
1322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// First, clean up tracking stuff
1323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			decisionsWhoseDFAsUsesSynPreds.remove(lookaheadDFA);
1324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// TODO: clean up synPredNamesUsedInDFA also (harder)
1325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			d.blockAST.setBlockOption(this, "k", Utils.integer(1));
1326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( composite.watchNFAConversion ) {
1327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				System.out.print("trying decision "+decision+
1328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 " again with k=1; reason: "+
1329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								 lookaheadDFA.getReasonForFailure());
1330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lookaheadDFA = null; // make sure other memory is "free" before redoing
1332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lookaheadDFA = new DFA(decision, decisionStartState);
1333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setLookaheadDFA(decision, lookaheadDFA);
1336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( wackTempStructures ) {
1338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (DFAState s : lookaheadDFA.getUniqueStates().values()) {
1339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				s.reset();
1340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// create map from line:col to decision DFA (for ANTLRWorks)
1344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		updateLineColumnToLookaheadDFAMap(lookaheadDFA);
1345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( composite.watchNFAConversion ) {
1347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			stopDFA = System.currentTimeMillis();
1348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println("cost: "+lookaheadDFA.getNumberOfStates()+
1349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   " states, "+(int)(stopDFA-startDFA)+" ms");
1350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("after create DFA; synPredNamesUsedInDFA="+synPredNamesUsedInDFA);
1352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return lookaheadDFA;
1353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Terminate DFA creation (grammar analysis).
1356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void externallyAbortNFAToDFAConversion() {
1358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		externalAnalysisAbort = true;
1359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean NFAToDFAConversionExternallyAborted() {
1362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return externalAnalysisAbort;
1363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Return a new unique integer in the token type space */
1366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getNewTokenType() {
1367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.maxTokenType++;
1368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.maxTokenType;
1369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Define a token at a particular token type value.  Blast an
1372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  old value with a new one.  This is called normal grammar processsing
1373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and during import vocab operations to set tokens with specific values.
1374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineToken(String text, int tokenType) {
1376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("defineToken("+text+", "+tokenType+")");
1377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( composite.tokenIDToTypeMap.get(text)!=null ) {
1378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// already defined?  Must be predefined one like EOF;
1379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// do nothing
1380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// the index in the typeToTokenList table is actually shifted to
1383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// hold faux labels as you cannot have negative indices.
1384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( text.charAt(0)=='\'' ) {
1385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.stringLiteralToTypeMap.put(text, Utils.integer(tokenType));
1386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// track in reverse index too
1387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( tokenType>=composite.typeToStringLiteralList.size() ) {
1388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				composite.typeToStringLiteralList.setSize(tokenType+1);
1389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.typeToStringLiteralList.set(tokenType, text);
1391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else { // must be a label like ID
1393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.tokenIDToTypeMap.put(text, Utils.integer(tokenType));
1394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int index = Label.NUM_FAUX_LABELS+tokenType-1;
1396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("defining "+name+" token "+text+" at type="+tokenType+", index="+index);
1397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.maxTokenType = Math.max(composite.maxTokenType, tokenType);
1398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( index>=composite.typeToTokenList.size() ) {
1399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.typeToTokenList.setSize(index+1);
1400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String prevToken = (String)composite.typeToTokenList.get(index);
1402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( prevToken==null || prevToken.charAt(0)=='\'' ) {
1403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// only record if nothing there before or if thing before was a literal
1404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.typeToTokenList.set(index, text);
1405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Define a new rule.  A new rule index is created by incrementing
1409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  ruleIndex.
1410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineRule(Token ruleToken,
1412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   String modifier,
1413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   Map options,
1414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   GrammarAST tree,
1415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   GrammarAST argActionAST,
1416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   int numAlts)
1417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ruleName = ruleToken.getText();
1419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getLocallyDefinedRule(ruleName)!=null ) {
1420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(ErrorManager.MSG_RULE_REDEFINITION,
1421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  this, ruleToken, ruleName);
1422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( (type==Grammar.PARSER||type==Grammar.TREE_PARSER) &&
1426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 Character.isUpperCase(ruleName.charAt(0)) )
1427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(ErrorManager.MSG_LEXER_RULES_NOT_ALLOWED,
1429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  this, ruleToken, ruleName);
1430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = new Rule(this, ruleName, composite.ruleIndex, numAlts);
1434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
1435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		System.out.println("defineRule("+ruleName+",modifier="+modifier+
1436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver						   "): index="+r.index+", nalts="+numAlts);
1437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
1438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.modifier = modifier;
1439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		nameToRuleMap.put(ruleName, r);
1440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		setRuleAST(ruleName, tree);
1441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.setOptions(options, ruleToken);
1442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.argActionAST = argActionAST;
1443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.ruleIndexToRuleList.setSize(composite.ruleIndex+1);
1444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.ruleIndexToRuleList.set(composite.ruleIndex, r);
1445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.ruleIndex++;
1446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( ruleName.startsWith(SYNPRED_RULE_PREFIX) ) {
1447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.isSynPred = true;
1448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Define a new predicate and get back its name for use in building
1452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  a semantic predicate reference to the syn pred.
1453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String defineSyntacticPredicate(GrammarAST blockAST,
1455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										   String currentRuleName)
1456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nameToSynpredASTMap==null ) {
1458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			nameToSynpredASTMap = new LinkedHashMap();
1459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String predName =
1461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			SYNPRED_RULE_PREFIX+(nameToSynpredASTMap.size() + 1)+"_"+name;
1462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		blockAST.setTreeEnclosingRuleNameDeeply(predName);
1463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		nameToSynpredASTMap.put(predName, blockAST);
1464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return predName;
1465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public LinkedHashMap getSyntacticPredicates() {
1468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return nameToSynpredASTMap;
1469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public GrammarAST getSyntacticPredicate(String name) {
1472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nameToSynpredASTMap==null ) {
1473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
1474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return (GrammarAST)nameToSynpredASTMap.get(name);
1476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void synPredUsedInDFA(DFA dfa, SemanticContext semCtx) {
1479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		decisionsWhoseDFAsUsesSynPreds.add(dfa);
1480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		semCtx.trackUseOfSyntacticPredicates(this); // walk ctx looking for preds
1481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/*
1484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Rule> getRuleNamesVisitedDuringLOOK() {
1485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return rulesSensitiveToOtherRules;
1486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	*/
1488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given @scope::name {action} define it for this grammar.  Later,
1490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the code generator will ask for the actions table.  For composite
1491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  grammars, make sure header action propogates down to all delegates.
1492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineNamedAction(GrammarAST ampersandAST,
1494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  String scope,
1495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  GrammarAST nameAST,
1496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  GrammarAST actionAST)
1497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( scope==null ) {
1499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			scope = getDefaultActionScope(type);
1500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("Grammar "+name+" define @"+scope+"::"+nameAST.getText()+"{"+actionAST.getText()+"}");
1502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String actionName = nameAST.getText();
1503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Map<String, Object> scopeActions = getActions().get(scope);
1504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( scopeActions==null ) {
1505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			scopeActions = new HashMap<String, Object>();
1506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			getActions().put(scope, scopeActions);
1507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object a = scopeActions.get(actionName);
1509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( a!=null ) {
1510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(
1511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.MSG_ACTION_REDEFINITION,this,
1512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				nameAST.getToken(),nameAST.getText());
1513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
1515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			scopeActions.put(actionName,actionAST);
1516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // propogate header (regardless of scope (lexer, parser, ...) ?
1518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( this==composite.getRootGrammar() && actionName.equals("header") ) {
1519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            List<Grammar> allgrammars = composite.getRootGrammar().getDelegates();
1520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (Grammar delegate : allgrammars) {
1521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( target.isValidActionScope(delegate.type, scope) ) {
1522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					//System.out.println("propogate to "+delegate.name);
1523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                	delegate.defineNamedAction(ampersandAST, scope, nameAST, actionAST);
1524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
1526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
1527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void setSynPredGateIfNotAlready(ST gateST) {
1530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        String scope = getDefaultActionScope(type);
1531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Map<String, Object> actionsForGrammarScope = getActions().get(scope);
1532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // if no synpredgate action set by user then set
1533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( (actionsForGrammarScope==null ||
1534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver             !actionsForGrammarScope.containsKey(Grammar.SYNPREDGATE_ACTION_NAME)) )
1535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        {
1536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if ( actionsForGrammarScope==null ) {
1537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                actionsForGrammarScope=new HashMap<String, Object>();
1538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                getActions().put(scope, actionsForGrammarScope);
1539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
1540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            actionsForGrammarScope.put(Grammar.SYNPREDGATE_ACTION_NAME,
1541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                       gateST);
1542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
1543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Map<String, Map<String, Object>> getActions() {
1546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return actions;
1547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given a grammar type, what should be the default action scope?
1550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If I say @members in a COMBINED grammar, for example, the
1551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  default scope should be "parser".
1552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getDefaultActionScope(int grammarType) {
1554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		switch (grammarType) {
1555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case Grammar.LEXER :
1556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return "lexer";
1557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case Grammar.PARSER :
1558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case Grammar.COMBINED :
1559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return "parser";
1560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case Grammar.TREE_PARSER :
1561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return "treeparser";
1562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
1564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineLexerRuleFoundInParser(Token ruleToken,
1567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											 GrammarAST ruleAST)
1568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver//		System.out.println("rule tree is:\n"+ruleAST.toStringTree());
1570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
1571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ruleText = tokenBuffer.toOriginalString(ruleAST.ruleStartTokenIndex,
1572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver											   ruleAST.ruleStopTokenIndex);
1573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
1574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// first, create the text of the rule
1575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		StringBuffer buf = new StringBuffer();
1576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		buf.append("// $ANTLR src \"");
1577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		buf.append(getFileName());
1578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		buf.append("\" ");
1579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		buf.append(ruleAST.getLine());
1580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		buf.append("\n");
1581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i=ruleAST.getTokenStartIndex();
1582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 i<=ruleAST.getTokenStopIndex() && i<tokenBuffer.size();
1583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 i++)
1584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
1585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			CommonToken t = (CommonToken)tokenBuffer.get(i);
1586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// undo the text deletions done by the lexer (ugh)
1587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( t.getType()==ANTLRParser.BLOCK ) {
1588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("(");
1589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( t.getType()==ANTLRParser.ACTION ) {
1591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("{");
1592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(t.getText());
1593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("}");
1594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( t.getType()==ANTLRParser.SEMPRED ||
1596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  t.getType()==ANTLRParser.SYN_SEMPRED ||
1597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  t.getType()==ANTLRParser.GATED_SEMPRED ||
1598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					  t.getType()==ANTLRParser.BACKTRACK_SEMPRED )
1599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("{");
1601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(t.getText());
1602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("}?");
1603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else if ( t.getType()==ANTLRParser.ARG_ACTION ) {
1605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("[");
1606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(t.getText());
1607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append("]");
1608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
1610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(t.getText());
1611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String ruleText = buf.toString();
1614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("[["+ruleText+"]]");
1615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// now put the rule into the lexer grammar template
1616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getGrammarIsRoot() ) { // don't build lexers for delegates
1617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexerGrammarST.add("rules", ruleText);
1618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// track this lexer rule's name
1620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.lexerRules.add(ruleToken.getText());
1621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If someone does PLUS='+' in the parser, must make sure we get
1624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  "PLUS : '+' ;" in lexer not "T73 : '+';"
1625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineLexerRuleForAliasedStringLiteral(String tokenID,
1627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver													   String literal,
1628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver													   int tokenType)
1629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getGrammarIsRoot() ) { // don't build lexers for delegates
1631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("defineLexerRuleForAliasedStringLiteral: "+literal+" "+tokenType);
1632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexerGrammarST.addAggr("literals.{ruleName,type,literal}",
1633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										tokenID,
1634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										Utils.integer(tokenType),
1635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										literal);
1636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// track this lexer rule's name
1638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		composite.lexerRules.add(tokenID);
1639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineLexerRuleForStringLiteral(String literal, int tokenType) {
1642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("defineLexerRuleForStringLiteral: "+literal+" "+tokenType);
1643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// compute new token name like T237 and define it as having tokenType
1644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String tokenID = computeTokenNameFromLiteral(tokenType,literal);
1645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		defineToken(tokenID, tokenType);
1646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// tell implicit lexer to define a rule to match the literal
1647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getGrammarIsRoot() ) { // don't build lexers for delegates
1648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			lexerGrammarST.addAggr("literals.{ruleName,type,literal}",
1649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										tokenID,
1650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										Utils.integer(tokenType),
1651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										literal);
1652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Rule getLocallyDefinedRule(String ruleName) {
1656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = nameToRuleMap.get(ruleName);
1657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return r;
1658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Rule getRule(String ruleName) {
1661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = composite.getRule(ruleName);
1662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/*
1663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null && r.grammar != this ) {
1664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println(name+".getRule("+ruleName+")="+r);
1665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
1667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return r;
1668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Rule getRule(String scopeName, String ruleName) {
1671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( scopeName!=null ) { // scope override
1672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Grammar scope = composite.getGrammar(scopeName);
1673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( scope==null ) {
1674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return null;
1675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return scope.getLocallyDefinedRule(ruleName);
1677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return getRule(ruleName);
1679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getRuleIndex(String scopeName, String ruleName) {
1682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(scopeName, ruleName);
1683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return r.index;
1685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return INVALID_RULE_INDEX;
1687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getRuleIndex(String ruleName) {
1690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return getRuleIndex(null, ruleName);
1691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getRuleName(int ruleIndex) {
1694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = composite.ruleIndexToRuleList.get(ruleIndex);
1695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return r.name;
1697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
1699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Should codegen.g gen rule for ruleName?
1702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 * 	If synpred, only gen if used in a DFA.
1703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If regular rule, only gen if not overridden in delegator
1704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Always gen Tokens rule though.
1705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean generateMethodForRule(String ruleName) {
1707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( ruleName.equals(ARTIFICIAL_TOKENS_RULENAME) ) {
1708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// always generate Tokens rule to satisfy lexer interface
1709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// but it may have no alternatives.
1710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return true;
1711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( overriddenRules.contains(ruleName) ) {
1713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// don't generate any overridden rules
1714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return false;
1715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// generate if non-synpred or synpred used in a DFA
1717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return !r.isSynPred ||
1719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   (r.isSynPred&&synPredNamesUsedInDFA.contains(ruleName));
1720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public AttributeScope defineGlobalScope(String name, Token scopeAction) {
1723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		AttributeScope scope = new AttributeScope(this, name, scopeAction);
1724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		scopes.put(name,scope);
1725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return scope;
1726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public AttributeScope createReturnScope(String ruleName, Token retAction) {
1729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		AttributeScope scope = new AttributeScope(this, ruleName, retAction);
1730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		scope.isReturnScope = true;
1731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return scope;
1732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public AttributeScope createRuleScope(String ruleName, Token scopeAction) {
1735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		AttributeScope scope = new AttributeScope(this, ruleName, scopeAction);
1736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		scope.isDynamicRuleScope = true;
1737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return scope;
1738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public AttributeScope createParameterScope(String ruleName, Token argAction) {
1741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		AttributeScope scope = new AttributeScope(this, ruleName, argAction);
1742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		scope.isParameterScope = true;
1743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return scope;
1744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get a global scope */
1747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public AttributeScope getGlobalScope(String name) {
1748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return (AttributeScope)scopes.get(name);
1749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Map getGlobalScopes() {
1752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return scopes;
1753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Define a label defined in a rule r; check the validity then ask the
1756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Rule object to actually define it.
1757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void defineLabel(Rule r, Token label, GrammarAST element, int type) {
1759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean err = nameSpaceChecker.checkForLabelTypeMismatch(r, label, type);
1760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( err ) {
1761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.defineLabel(label, element, type);
1764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineTokenRefLabel(String ruleName,
1767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									Token label,
1768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									GrammarAST tokenRef)
1769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( type==LEXER &&
1773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				 (tokenRef.getType()==ANTLRParser.CHAR_LITERAL||
1774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  tokenRef.getType()==ANTLRParser.BLOCK||
1775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  tokenRef.getType()==ANTLRParser.NOT||
1776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  tokenRef.getType()==ANTLRParser.CHAR_RANGE||
1777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  tokenRef.getType()==ANTLRParser.WILDCARD))
1778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
1779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				defineLabel(r, label, tokenRef, CHAR_LABEL);
1780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            else {
1782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				defineLabel(r, label, tokenRef, TOKEN_LABEL);
1783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void defineWildcardTreeLabel(String ruleName,
1788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           Token label,
1789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           GrammarAST tokenRef)
1790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Rule r = getLocallyDefinedRule(ruleName);
1792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( r!=null ) {
1793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            defineLabel(r, label, tokenRef, WILDCARD_TREE_LABEL);
1794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
1795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void defineWildcardTreeListLabel(String ruleName,
1798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           Token label,
1799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           GrammarAST tokenRef)
1800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    {
1801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        Rule r = getLocallyDefinedRule(ruleName);
1802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( r!=null ) {
1803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            defineLabel(r, label, tokenRef, WILDCARD_TREE_LIST_LABEL);
1804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
1805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
1806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public void defineRuleRefLabel(String ruleName,
1808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   Token label,
1809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   GrammarAST ruleRef)
1810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			defineLabel(r, label, ruleRef, RULE_LABEL);
1814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineTokenListLabel(String ruleName,
1818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									 Token label,
1819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									 GrammarAST element)
1820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			defineLabel(r, label, element, TOKEN_LIST_LABEL);
1824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void defineRuleListLabel(String ruleName,
1828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									Token label,
1829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									GrammarAST element)
1830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
1833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !r.getHasMultipleReturnValues() ) {
1834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(
1835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.MSG_LIST_LABEL_INVALID_UNLESS_RETVAL_STRUCT,this,
1836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					label,label.getText());
1837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			defineLabel(r, label, element, RULE_LIST_LABEL);
1839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given a set of all rewrite elements on right of ->, filter for
1843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  label types such as Grammar.TOKEN_LABEL, Grammar.TOKEN_LIST_LABEL, ...
1844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Return a displayable token type name computed from the GrammarAST.
1845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<String> getLabels(Set<GrammarAST> rewriteElements, int labelType) {
1847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Set<String> labels = new HashSet<String>();
1848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (GrammarAST el : rewriteElements) {
1849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( el.getType()==ANTLRParser.LABEL ) {
1850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String labelName = el.getText();
1851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				Rule enclosingRule = getLocallyDefinedRule(el.enclosingRuleName);
1852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( enclosingRule==null ) continue;
1853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				LabelElementPair pair = enclosingRule.getLabel(labelName);
1854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                /*
1855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // if tree grammar and we have a wildcard, only notice it
1856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // when looking for rule labels not token label. x=. should
1857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // look like a rule ref since could be subtree.
1858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if ( type==TREE_PARSER && pair!=null &&
1859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     pair.elementRef.getType()==ANTLRParser.WILDCARD )
1860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                {
1861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if ( labelType==WILDCARD_TREE_LABEL ) {
1862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        labels.add(labelName);
1863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        continue;
1864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    }
1865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    else continue;
1866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
1867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 */
1868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // if valid label and type is what we're looking for
1869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// and not ref to old value val $rule, add to list
1870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( pair!=null && pair.type==labelType &&
1871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					 !labelName.equals(el.enclosingRuleName) )
1872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
1873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					labels.add(labelName);
1874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
1875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return labels;
1878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Before generating code, we examine all actions that can have
1881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  $x.y and $y stuff in them because some code generation depends on
1882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Rule.referencedPredefinedRuleAttributes.  I need to remove unused
1883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  rule labels for example.
1884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void examineAllExecutableActions() {
1886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Collection rules = getRules();
1887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = rules.iterator(); it.hasNext();) {
1888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule r = (Rule) it.next();
1889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// walk all actions within the rule elements, args, and exceptions
1890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			List<GrammarAST> actions = r.getInlineActions();
1891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (int i = 0; i < actions.size(); i++) {
1892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				GrammarAST actionAST = (GrammarAST) actions.get(i);
1893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ActionAnalysis sniffer =
1894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					new ActionAnalysis(this, r.name, actionAST);
1895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				sniffer.analyze();
1896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// walk any named actions like @init, @after
1898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Collection<GrammarAST> namedActions = r.getActions().values();
1899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (Iterator it2 = namedActions.iterator(); it2.hasNext();) {
1900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				GrammarAST actionAST = (GrammarAST) it2.next();
1901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ActionAnalysis sniffer =
1902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					new ActionAnalysis(this, r.name, actionAST);
1903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				sniffer.analyze();
1904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Remove all labels on rule refs whose target rules have no return value.
1909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Do this for all rules in grammar.
1910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void checkAllRulesForUselessLabels() {
1912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( type==LEXER ) {
1913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Set rules = nameToRuleMap.keySet();
1916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = rules.iterator(); it.hasNext();) {
1917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String ruleName = (String) it.next();
1918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule r = getRule(ruleName);
1919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			removeUselessLabels(r.getRuleLabels());
1920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			removeUselessLabels(r.getRuleListLabels());
1921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** A label on a rule is useless if the rule has no return value, no
1925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  tree or template output, and it is not referenced in an action.
1926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void removeUselessLabels(Map ruleToElementLabelPairMap) {
1928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( ruleToElementLabelPairMap==null ) {
1929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Collection labels = ruleToElementLabelPairMap.values();
1932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List kill = new ArrayList();
1933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator labelit = labels.iterator(); labelit.hasNext();) {
1934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			LabelElementPair pair = (LabelElementPair) labelit.next();
1935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule refdRule = getRule(pair.elementRef.getText());
1936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( refdRule!=null && !refdRule.getHasReturnValue() && !pair.actionReferencesLabel ) {
1937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//System.out.println(pair.label.getText()+" is useless");
1938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				kill.add(pair.label.getText());
1939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i = 0; i < kill.size(); i++) {
1942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String labelToKill = (String) kill.get(i);
1943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// System.out.println("kill "+labelToKill);
1944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleToElementLabelPairMap.remove(labelToKill);
1945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track a rule reference within an outermost alt of a rule.  Used
1949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  at the moment to decide if $ruleref refers to a unique rule ref in
1950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the alt.  Rewrite rules force tracking of all rule AST results.
1951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
1952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This data is also used to verify that all rules have been defined.
1953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void altReferencesRule(String enclosingRuleName,
1955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  GrammarAST refScopeAST,
1956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  GrammarAST refAST,
1957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								  int outerAltNum)
1958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
1959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		/* Do nothing for now; not sure need; track S.x as x
1960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String scope = null;
1961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Grammar scopeG = null;
1962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( refScopeAST!=null ) {
1963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !scopedRuleRefs.contains(refScopeAST) ) {
1964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				scopedRuleRefs.add(refScopeAST);
1965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
1966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			scope = refScopeAST.getText();
1967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		*/
1969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(enclosingRuleName);
1970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r==null ) {
1971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return; // no error here; see NameSpaceChecker
1972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.trackRuleReferenceInAlt(refAST, outerAltNum);
1974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Token refToken = refAST.getToken();
1975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !ruleRefs.contains(refAST) ) {
1976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ruleRefs.add(refAST);
1977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Track a token reference within an outermost alt of a rule.  Used
1981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to decide if $tokenref refers to a unique token ref in
1982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the alt. Does not track literals!
1983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
1984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Rewrite rules force tracking of all tokens.
1985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
1986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void altReferencesTokenID(String ruleName, GrammarAST refAST, int outerAltNum) {
1987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
1988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r==null ) {
1989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
1990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		r.trackTokenReferenceInAlt(refAST, outerAltNum);
1992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !tokenIDRefs.contains(refAST.getToken()) ) {
1993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenIDRefs.add(refAST.getToken());
1994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
1995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
1996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
1997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** To yield smaller, more readable code, track which rules have their
1998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  predefined attributes accessed.  If the rule has no user-defined
1999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  return values, then don't generate the return value scope classes
2000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  etc...  Make the rule have void return value.  Don't track for lexer
2001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  rules.
2002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void referenceRuleLabelPredefinedAttribute(String ruleName) {
2004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(ruleName);
2005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null && type!=LEXER ) {
2006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// indicate that an action ref'd an attr unless it's in a lexer
2007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// so that $ID.text refs don't force lexer rules to define
2008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// return values...Token objects are created by the caller instead.
2009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.referencedPredefinedRuleAttributes = true;
2010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List checkAllRulesForLeftRecursion() {
2014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return sanity.checkAllRulesForLeftRecursion();
2015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Return a list of left-recursive rules; no analysis can be done
2018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  successfully on these.  Useful to skip these rules then and also
2019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  for ANTLRWorks to highlight them.
2020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Rule> getLeftRecursiveRules() {
2022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( nfa==null ) {
2023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			buildNFA();
2024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( leftRecursiveRules!=null ) {
2026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return leftRecursiveRules;
2027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		sanity.checkAllRulesForLeftRecursion();
2029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return leftRecursiveRules;
2030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void checkRuleReference(GrammarAST scopeAST,
2033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   GrammarAST refAST,
2034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   GrammarAST argsAST,
2035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   String currentRuleName)
2036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		sanity.checkRuleReference(scopeAST, refAST, argsAST, currentRuleName);
2038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Rules like "a : ;" and "a : {...} ;" should not generate
2041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  try/catch blocks for RecognitionException.  To detect this
2042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  it's probably ok to just look for any reference to an atom
2043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  that can match some input.  W/o that, the rule is unlikey to have
2044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  any else.
2045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean isEmptyRule(GrammarAST block) {
2047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST aTokenRefNode =
2048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			block.findFirstType(ANTLRParser.TOKEN_REF);
2049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST aStringLiteralRefNode =
2050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			block.findFirstType(ANTLRParser.STRING_LITERAL);
2051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST aCharLiteralRefNode =
2052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			block.findFirstType(ANTLRParser.CHAR_LITERAL);
2053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST aWildcardRefNode =
2054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			block.findFirstType(ANTLRParser.WILDCARD);
2055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST aRuleRefNode =
2056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			block.findFirstType(ANTLRParser.RULE_REF);
2057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( aTokenRefNode==null&&
2058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 aStringLiteralRefNode==null&&
2059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 aCharLiteralRefNode==null&&
2060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 aWildcardRefNode==null&&
2061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 aRuleRefNode==null )
2062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
2063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return true;
2064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return false;
2066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean isAtomTokenType(int ttype) {
2069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ttype == ANTLRParser.WILDCARD||
2070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   ttype == ANTLRParser.CHAR_LITERAL||
2071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   ttype == ANTLRParser.CHAR_RANGE||
2072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   ttype == ANTLRParser.STRING_LITERAL||
2073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   ttype == ANTLRParser.NOT||
2074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			   (type != LEXER && ttype == ANTLRParser.TOKEN_REF);
2075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getTokenType(String tokenName) {
2078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Integer I = null;
2079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( tokenName.charAt(0)=='\'') {
2080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			I = (Integer)composite.stringLiteralToTypeMap.get(tokenName);
2081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else { // must be a label like ID
2083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			I = (Integer)composite.tokenIDToTypeMap.get(tokenName);
2084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int i = (I!=null)?I.intValue():Label.INVALID;
2086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("grammar type "+type+" "+tokenName+"->"+i);
2087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return i;
2088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the list of tokens that are IDs like BLOCK and LPAREN */
2091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set getTokenIDs() {
2092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.tokenIDToTypeMap.keySet();
2093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Return an ordered integer list of token types that have no
2096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  corresponding token ID like INT or KEYWORD_BEGIN; for stuff
2097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  like 'begin'.
2098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Collection getTokenTypesWithoutID() {
2100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List types = new ArrayList();
2101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int t =Label.MIN_TOKEN_TYPE; t<=getMaxTokenType(); t++) {
2102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String name = getTokenDisplayName(t);
2103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( name.charAt(0)=='\'' ) {
2104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				types.add(Utils.integer(t));
2105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return types;
2108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get a list of all token IDs and literals that have an associated
2111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  token type.
2112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<String> getTokenDisplayNames() {
2114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Set<String> names = new HashSet<String>();
2115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int t =Label.MIN_TOKEN_TYPE; t <=getMaxTokenType(); t++) {
2116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			names.add(getTokenDisplayName(t));
2117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return names;
2119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given a literal like (the 3 char sequence with single quotes) 'a',
2122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  return the int value of 'a'. Convert escape sequences here also.
2123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  ANTLR's antlr.g parser does not convert escape sequences.
2124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  11/26/2005: I changed literals to always be '...' even for strings.
2126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This routine still works though.
2127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static int getCharValueFromGrammarCharLiteral(String literal) {
2129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		switch ( literal.length() ) {
2130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case 3 :
2131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// 'x'
2132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return literal.charAt(1); // no escape char
2133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case 4 :
2134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// '\x'  (antlr lexer will catch invalid char)
2135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( Character.isDigit(literal.charAt(2)) ) {
2136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_SYNTAX_ERROR,
2137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   "invalid char literal: "+literal);
2138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return -1;
2139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				int escChar = literal.charAt(2);
2141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				int charVal = ANTLRLiteralEscapedCharValue[escChar];
2142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( charVal==0 ) {
2143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// Unnecessary escapes like '\{' should just yield {
2144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					return escChar;
2145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return charVal;
2147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case 8 :
2148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// '\u1234'
2149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String unicodeChars = literal.substring(3,literal.length()-1);
2150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return Integer.parseInt(unicodeChars, 16);
2151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			default :
2152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.error(ErrorManager.MSG_SYNTAX_ERROR,
2153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver								   "invalid char literal: "+literal);
2154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return -1;
2155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** ANTLR does not convert escape sequences during the parse phase because
2159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  it could not know how to print String/char literals back out when
2160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  printing grammars etc...  Someone in China might use the real unicode
2161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  char in a literal as it will display on their screen; when printing
2162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  back out, I could not know whether to display or use a unicode escape.
2163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This routine converts a string literal with possible escape sequences
2165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  into a pure string of 16-bit char values.  Escapes and unicode \u0000
2166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  specs are converted to pure chars.  return in a buffer; people may
2167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  want to walk/manipulate further.
2168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  The NFA construction routine must know the actual char values.
2170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static StringBuffer getUnescapedStringFromGrammarStringLiteral(String literal) {
2172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("escape: ["+literal+"]");
2173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		StringBuffer buf = new StringBuffer();
2174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int last = literal.length()-1; // skip quotes on outside
2175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i=1; i<last; i++) {
2176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			char c = literal.charAt(i);
2177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( c=='\\' ) {
2178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				i++;
2179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				c = literal.charAt(i);
2180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( Character.toUpperCase(c)=='U' ) {
2181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// \u0000
2182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					i++;
2183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					String unicodeChars = literal.substring(i,i+4);
2184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// parse the unicode 16 bit hex value
2185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					int val = Integer.parseInt(unicodeChars, 16);
2186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					i+=4-1; // loop will inc by 1; only jump 3 then
2187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					buf.append((char)val);
2188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else if ( Character.isDigit(c) ) {
2190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_SYNTAX_ERROR,
2191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   "invalid char literal: "+literal);
2192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					buf.append("\\"+(char)c);
2193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else {
2195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					buf.append((char)ANTLRLiteralEscapedCharValue[c]); // normal \x escape
2196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
2199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				buf.append(c); // simple char x
2200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("string: ["+buf.toString()+"]");
2203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return buf;
2204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Pull your token definitions from an existing grammar in memory.
2207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  You must use Grammar() ctor then this method then setGrammarContent()
2208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to make this work.  This was useful primarily for testing and
2209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  interpreting grammars until I added import grammar functionality.
2210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  When you import a grammar you implicitly import its vocabulary as well
2211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  and keep the same token type values.
2212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Returns the max token type found.
2214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int importTokenVocabulary(Grammar importFromGr) {
2216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Set importedTokenIDs = importFromGr.getTokenIDs();
2217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = importedTokenIDs.iterator(); it.hasNext();) {
2218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String tokenID = (String) it.next();
2219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int tokenType = importFromGr.getTokenType(tokenID);
2220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			composite.maxTokenType = Math.max(composite.maxTokenType,tokenType);
2221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( tokenType>=Label.MIN_TOKEN_TYPE ) {
2222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//System.out.println("import token from grammar "+tokenID+"="+tokenType);
2223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				defineToken(tokenID, tokenType);
2224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.maxTokenType; // return max found
2227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Import the rules/tokens of a delegate grammar. All delegate grammars are
2230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  read during the ctor of first Grammar created.
2231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Do not create NFA here because NFA construction needs to hook up with
2233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  overridden rules in delegation root grammar.
2234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void importGrammar(GrammarAST grammarNameAST, String label) {
2236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String grammarName = grammarNameAST.getText();
2237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("import "+gfile.getName());
2238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String gname = grammarName + GRAMMAR_FILE_EXTENSION;
2239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		BufferedReader br = null;
2240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
2241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String fullName = tool.getLibraryFile(gname);
2242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			FileReader fr = new FileReader(fullName);
2243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			br = new BufferedReader(fr);
2244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Grammar delegateGrammar = null;
2245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			delegateGrammar = new Grammar(tool, gname, composite);
2246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			delegateGrammar.label = label;
2247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			addDelegateGrammar(delegateGrammar);
2249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			delegateGrammar.parseAndBuildAST(br);
2251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			delegateGrammar.addRulesForSyntacticPredicates();
2252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( !validImport(delegateGrammar) ) {
2253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(ErrorManager.MSG_INVALID_IMPORT,
2254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  this,
2255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  grammarNameAST.token,
2256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  this,
2257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  delegateGrammar);
2258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return;
2259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( this.type==COMBINED &&
2261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				 (delegateGrammar.name.equals(this.name+grammarTypeToFileNameSuffix[LEXER])||
2262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				  delegateGrammar.name.equals(this.name+grammarTypeToFileNameSuffix[PARSER])) )
2263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			{
2264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				ErrorManager.grammarError(ErrorManager.MSG_IMPORT_NAME_CLASH,
2265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  this,
2266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  grammarNameAST.token,
2267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  this,
2268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										  delegateGrammar);
2269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return;
2270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( delegateGrammar.grammarTree!=null ) {
2272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// we have a valid grammar
2273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				// deal with combined grammars
2274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( delegateGrammar.type == LEXER && this.type == COMBINED ) {
2275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// ooops, we wasted some effort; tell lexer to read it in
2276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// later
2277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					lexerGrammarST.add("imports", grammarName);
2278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// but, this parser grammar will need the vocab
2279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					// so add to composite anyway so we suck in the tokens later
2280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("Got grammar:\n"+delegateGrammar);
2283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IOException ioe) {
2285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_CANNOT_OPEN_FILE,
2286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   gname,
2287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   ioe);
2288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		finally {
2290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( br!=null ) {
2291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				try {
2292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					br.close();
2293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				catch (IOException ioe) {
2295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_CANNOT_CLOSE_FILE,
2296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   gname,
2297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   ioe);
2298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** add new delegate to composite tree */
2304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected void addDelegateGrammar(Grammar delegateGrammar) {
2305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		CompositeGrammarTree t = composite.delegateGrammarTreeRoot.findNode(this);
2306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		t.addChild(new CompositeGrammarTree(delegateGrammar));
2307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// make sure new grammar shares this composite
2308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		delegateGrammar.composite = this.composite;
2309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Load a vocab file <vocabName>.tokens and return max token type found. */
2312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int importTokenVocabulary(GrammarAST tokenVocabOptionAST,
2313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									 String vocabName)
2314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
2315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !getGrammarIsRoot() ) {
2316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarWarning(ErrorManager.MSG_TOKEN_VOCAB_IN_DELEGATE,
2317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										this,
2318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										tokenVocabOptionAST.token,
2319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver										name);
2320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return composite.maxTokenType;
2321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		File fullFile = tool.getImportedVocabFile(vocabName);
2324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
2325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			FileReader fr = new FileReader(fullFile);
2326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			BufferedReader br = new BufferedReader(fr);
2327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			StreamTokenizer tokenizer = new StreamTokenizer(br);
2328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.parseNumbers();
2329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.wordChars('_', '_');
2330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.eolIsSignificant(true);
2331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.slashSlashComments(true);
2332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.slashStarComments(true);
2333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.ordinaryChar('=');
2334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.quoteChar('\'');
2335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.whitespaceChars(' ',' ');
2336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenizer.whitespaceChars('\t','\t');
2337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int lineNum = 1;
2338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int token = tokenizer.nextToken();
2339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			while (token != StreamTokenizer.TT_EOF) {
2340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				String tokenID;
2341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( token == StreamTokenizer.TT_WORD ) {
2342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					tokenID = tokenizer.sval;
2343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else if ( token == '\'' ) {
2345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					tokenID = "'"+tokenizer.sval+"'";
2346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				else {
2348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_TOKENS_FILE_SYNTAX_ERROR,
2349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
2350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   Utils.integer(lineNum));
2351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
2352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					token = tokenizer.nextToken();
2353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
2354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				token = tokenizer.nextToken();
2356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( token != '=' ) {
2357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_TOKENS_FILE_SYNTAX_ERROR,
2358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
2359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   Utils.integer(lineNum));
2360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
2361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					token = tokenizer.nextToken();
2362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
2363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				token = tokenizer.nextToken(); // skip '='
2365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( token != StreamTokenizer.TT_NUMBER ) {
2366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_TOKENS_FILE_SYNTAX_ERROR,
2367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
2368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   Utils.integer(lineNum));
2369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
2370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					token = tokenizer.nextToken();
2371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
2372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				int tokenType = (int)tokenizer.nval;
2374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				token = tokenizer.nextToken();
2375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				//System.out.println("import "+tokenID+"="+tokenType);
2376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				composite.maxTokenType = Math.max(composite.maxTokenType,tokenType);
2377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				defineToken(tokenID, tokenType);
2378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				lineNum++;
2379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( token != StreamTokenizer.TT_EOL ) {
2380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					ErrorManager.error(ErrorManager.MSG_TOKENS_FILE_SYNTAX_ERROR,
2381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   vocabName+CodeGenerator.VOCAB_FILE_EXTENSION,
2382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									   Utils.integer(lineNum));
2383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					while ( tokenizer.nextToken() != StreamTokenizer.TT_EOL ) {;}
2384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					token = tokenizer.nextToken();
2385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					continue;
2386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				token = tokenizer.nextToken(); // skip newline
2388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			br.close();
2390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (FileNotFoundException fnfe) {
2392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_CANNOT_FIND_TOKENS_FILE,
2393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   fullFile);
2394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (IOException ioe) {
2396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_ERROR_READING_TOKENS_FILE,
2397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   fullFile,
2398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   ioe);
2399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (Exception e) {
2401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_ERROR_READING_TOKENS_FILE,
2402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   fullFile,
2403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver							   e);
2404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.maxTokenType;
2406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given a token type, get a meaningful name for it such as the ID
2409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  or string literal.  If this is a lexer and the ttype is in the
2410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  char vocabulary, compute an ANTLR-valid (possibly escaped) char literal.
2411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getTokenDisplayName(int ttype) {
2413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String tokenName = null;
2414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int index=0;
2415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// inside any target's char range and is lexer grammar?
2416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( this.type==LEXER &&
2417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 ttype >= Label.MIN_CHAR_VALUE && ttype <= Label.MAX_CHAR_VALUE )
2418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		{
2419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return getANTLRCharLiteralForChar(ttype);
2420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// faux label?
2422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if ( ttype<0 ) {
2423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			tokenName = (String)composite.typeToTokenList.get(Label.NUM_FAUX_LABELS+ttype);
2424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
2426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// compute index in typeToTokenList for ttype
2427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			index = ttype-1; // normalize to 0..n-1
2428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			index += Label.NUM_FAUX_LABELS;     // jump over faux tokens
2429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( index<composite.typeToTokenList.size() ) {
2431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				tokenName = (String)composite.typeToTokenList.get(index);
2432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				if ( tokenName!=null &&
2433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					 tokenName.startsWith(AUTO_GENERATED_TOKEN_NAME_PREFIX) )
2434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				{
2435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver					tokenName = composite.typeToStringLiteralList.get(ttype);
2436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				}
2437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			else {
2439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				tokenName = String.valueOf(ttype);
2440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("getTokenDisplayName ttype="+ttype+", index="+index+", name="+tokenName);
2443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return tokenName;
2444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the list of ANTLR String literals */
2447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<String> getStringLiterals() {
2448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.stringLiteralToTypeMap.keySet();
2449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getGrammarTypeString() {
2452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return grammarTypeToString[type];
2453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getGrammarMaxLookahead() {
2456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( global_k>=0 ) {
2457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return global_k;
2458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object k = getOption("k");
2460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( k==null ) {
2461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			global_k = 0;
2462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else if (k instanceof Integer) {
2464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Integer kI = (Integer)k;
2465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			global_k = kI.intValue();
2466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
2468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// must be String "*"
2469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( k.equals("*") ) {  // this the default anyway
2470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				global_k = 0;
2471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return global_k;
2474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Save the option key/value pair and process it; return the key
2477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  or null if invalid option.
2478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String setOption(String key, Object value, Token optionsStartToken) {
2480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( legalOption(key) ) {
2481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.grammarError(ErrorManager.MSG_ILLEGAL_OPTION,
2482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  this,
2483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  optionsStartToken,
2484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver									  key);
2485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( !optionIsValid(key, value) ) {
2488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( key.equals("backtrack") && value.toString().equals("true") ) {
2491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            composite.getRootGrammar().atLeastOneBacktrackOption = true;
2492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
2493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        if ( options==null ) {
2494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			options = new HashMap();
2495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		options.put(key, value);
2497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return key;
2498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean legalOption(String key) {
2501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		switch ( type ) {
2502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case LEXER :
2503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return !legalLexerOptions.contains(key);
2504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case PARSER :
2505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return !legalParserOptions.contains(key);
2506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			case TREE_PARSER :
2507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return !legalTreeParserOptions.contains(key);
2508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			default :
2509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return !legalParserOptions.contains(key);
2510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setOptions(Map options, Token optionsStartToken) {
2514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( options==null ) {
2515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			this.options = null;
2516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return;
2517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Set keys = options.keySet();
2519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = keys.iterator(); it.hasNext();) {
2520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String optionName = (String) it.next();
2521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Object optionValue = options.get(optionName);
2522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String stored=setOption(optionName, optionValue, optionsStartToken);
2523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( stored==null ) {
2524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				it.remove();
2525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Object getOption(String key) {
2530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getOption(key);
2531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Object getLocallyDefinedOption(String key) {
2534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object value = null;
2535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( options!=null ) {
2536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			value = options.get(key);
2537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( value==null ) {
2539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			value = defaultOptions.get(key);
2540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return value;
2542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Object getBlockOption(GrammarAST blockAST, String key) {
2545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String v = (String)blockAST.getBlockOption(key);
2546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( v!=null ) {
2547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return v;
2548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( type==Grammar.LEXER ) {
2550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return defaultLexerBlockOptions.get(key);
2551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return defaultBlockOptions.get(key);
2553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getUserMaxLookahead(int decision) {
2556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int user_k = 0;
2557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST blockAST = nfa.grammar.getDecisionBlockAST(decision);
2558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object k = blockAST.getBlockOption("k");
2559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( k==null ) {
2560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			user_k = nfa.grammar.getGrammarMaxLookahead();
2561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return user_k;
2562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if (k instanceof Integer) {
2564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Integer kI = (Integer)k;
2565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			user_k = kI.intValue();
2566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
2568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// must be String "*"
2569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( k.equals("*") ) {
2570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				user_k = 0;
2571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return user_k;
2574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean getAutoBacktrackMode(int decision) {
2577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NFAState decisionNFAStartState = getDecisionNFAStartState(decision);
2578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String autoBacktrack =
2579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			(String)getBlockOption(decisionNFAStartState.associatedASTNode, "backtrack");
2580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( autoBacktrack==null ) {
2582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			autoBacktrack = (String)nfa.grammar.getOption("backtrack");
2583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return autoBacktrack!=null&&autoBacktrack.equals("true");
2585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean optionIsValid(String key, Object value) {
2588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return true;
2589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean buildAST() {
2592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String outputType = (String)getOption("output");
2593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( outputType!=null ) {
2594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return outputType.toString().equals("AST");
2595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return false;
2597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean rewriteMode() {
2600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Object outputType = getOption("rewrite");
2601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( outputType!=null ) {
2602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return outputType.toString().equals("true");
2603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return false;
2605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean isBuiltFromString() {
2608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return builtFromString;
2609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean buildTemplate() {
2612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String outputType = (String)getOption("output");
2613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( outputType!=null ) {
2614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return outputType.toString().equals("template");
2615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return false;
2617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Collection<Rule> getRules() {
2620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return nameToRuleMap.values();
2621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the set of Rules that need to have manual delegations
2624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  like "void rule() { importedGrammar.rule(); }"
2625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  If this grammar is master, get list of all rule definitions from all
2627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  delegate grammars.  Only master has complete interface from combined
2628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  grammars...we will generated delegates as helper objects.
2629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Composite grammars that are not the root/master do not have complete
2631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  interfaces.  It is not my intention that people use subcomposites.
2632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Only the outermost grammar should be used from outside code.  The
2633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  other grammar components are specifically generated to work only
2634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  with the master/root.
2635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  delegatedRules = imported - overridden
2637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Rule> getDelegatedRules() {
2639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getDelegatedRules(this);
2640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get set of all rules imported from all delegate grammars even if
2643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  indirectly delegated.
2644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Rule> getAllImportedRules() {
2646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getAllImportedRules(this);
2647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get list of all delegates from all grammars directly or indirectly
2650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  imported into this grammar.
2651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<Grammar> getDelegates() {
2653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getDelegates(this);
2654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean getHasDelegates() {
2657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	   return !getDelegates().isEmpty();
2658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<String> getDelegateNames() {
2661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// compute delegates:{Grammar g | return g.name;}
2662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<String> names = new ArrayList<String>();
2663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List<Grammar> delegates = composite.getDelegates(this);
2664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( delegates!=null ) {
2665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			for (Grammar g : delegates) {
2666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				names.add(g.name);
2667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return names;
2670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<Grammar> getDirectDelegates() {
2673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getDirectDelegates(this);
2674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get delegates below direct delegates */
2677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<Grammar> getIndirectDelegates() {
2678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getIndirectDelegates(this);
2679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get list of all delegators.  This amounts to the grammars on the path
2682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  to the root of the delegation tree.
2683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<Grammar> getDelegators() {
2685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getDelegators(this);
2686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Who's my direct parent grammar? */
2689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Grammar getDelegator() {
2690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.getDelegator(this);
2691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Set<Rule> getDelegatedRuleReferences() {
2694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return delegatedRuleReferences;
2695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean getGrammarIsRoot() {
2698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.delegateGrammarTreeRoot.grammar == this;
2699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setRuleAST(String ruleName, GrammarAST t) {
2702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getLocallyDefinedRule(ruleName);
2703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
2704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.tree = t;
2705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			r.EORNode = t.getLastChild();
2706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFAState getRuleStartState(String ruleName) {
2710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return getRuleStartState(null, ruleName);
2711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFAState getRuleStartState(String scopeName, String ruleName) {
2714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(scopeName, ruleName);
2715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
2716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("getRuleStartState("+scopeName+", "+ruleName+")="+r.startState);
2717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return r.startState;
2718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("getRuleStartState("+scopeName+", "+ruleName+")=null");
2720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
2721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String getRuleModifier(String ruleName) {
2724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(ruleName);
2725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
2726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return r.modifier;
2727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
2729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFAState getRuleStopState(String ruleName) {
2732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(ruleName);
2733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r!=null ) {
2734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return r.stopState;
2735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
2737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int assignDecisionNumber(NFAState state) {
2740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		decisionCount++;
2741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		state.setDecisionNumber(decisionCount);
2742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return decisionCount;
2743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Decision getDecision(int decision) {
2746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int index = decision-1;
2747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( index >= indexToDecision.size() ) {
2748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = indexToDecision.get(index);
2751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d;
2752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List<Decision> getDecisions() {
2755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return indexToDecision;
2756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	protected Decision createDecision(int decision) {
2759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int index = decision-1;
2760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( index < indexToDecision.size() ) {
2761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return getDecision(decision); // don't recreate
2762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = new Decision();
2764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.decision = decision;
2765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.grammar = this;
2766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		indexToDecision.setSize(getNumberOfDecisions());
2767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		indexToDecision.set(index, d);
2768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d;
2769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List getDecisionNFAStartStateList() {
2772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List states = new ArrayList(100);
2773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int d = 0; d < indexToDecision.size(); d++) {
2774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Decision dec = (Decision) indexToDecision.get(d);
2775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			states.add(dec.startState);
2776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return states;
2778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFAState getDecisionNFAStartState(int decision) {
2781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
2782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( d==null ) {
2783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d.startState;
2786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public DFA getLookaheadDFA(int decision) {
2789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
2790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( d==null ) {
2791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d.dfa;
2794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public GrammarAST getDecisionBlockAST(int decision) {
2797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
2798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( d==null ) {
2799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d.blockAST;
2802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** returns a list of column numbers for all decisions
2805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  on a particular line so ANTLRWorks choose the decision
2806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  depending on the location of the cursor (otherwise,
2807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  ANTLRWorks has to give the *exact* location which
2808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  is not easy from the user point of view).
2809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This is not particularly fast as it walks entire line:col->DFA map
2811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  looking for a prefix of "line:".
2812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public List getLookaheadDFAColumnsForLineInFile(int line) {
2814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String prefix = line+":";
2815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		List columns = new ArrayList();
2816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for(Iterator iter = lineColumnToLookaheadDFAMap.keySet().iterator();
2817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			iter.hasNext(); ) {
2818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String key = (String)iter.next();
2819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if(key.startsWith(prefix)) {
2820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				columns.add(Integer.valueOf(key.substring(prefix.length())));
2821324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2822324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2823324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return columns;
2824324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2825324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2826324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Useful for ANTLRWorks to map position in file to the DFA for display */
2827324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public DFA getLookaheadDFAFromPositionInFile(int line, int col) {
2828324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return (DFA)lineColumnToLookaheadDFAMap.get(
2829324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			new StringBuffer().append(line + ":").append(col).toString());
2830324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2831324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2832324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Map getLineColumnToLookaheadDFAMap() {
2833324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return lineColumnToLookaheadDFAMap;
2834324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2835324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2836324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/*
2837324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setDecisionOptions(int decision, Map options) {
2838324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = createDecision(decision);
2839324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.options = options;
2840324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2841324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2842324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setDecisionOption(int decision, String name, Object value) {
2843324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
2844324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( d!=null ) {
2845324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( d.options==null ) {
2846324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				d.options = new HashMap();
2847324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2848324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			d.options.put(name,value);
2849324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2850324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2851324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2852324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Map getDecisionOptions(int decision) {
2853324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = getDecision(decision);
2854324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( d==null ) {
2855324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
2856324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2857324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return d.options;
2858324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
2859324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    */
2860324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2861324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getNumberOfDecisions() {
2862324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return decisionCount;
2863324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2864324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2865324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getNumberOfCyclicDecisions() {
2866324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int n = 0;
2867324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (int i=1; i<=getNumberOfDecisions(); i++) {
2868324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Decision d = getDecision(i);
2869324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( d.dfa!=null && d.dfa.isCyclic() ) {
2870324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				n++;
2871324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2872324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2873324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return n;
2874324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2875324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2876324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Set the lookahead DFA for a particular decision.  This means
2877324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  that the appropriate AST node must updated to have the new lookahead
2878324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  DFA.  This method could be used to properly set the DFAs without
2879324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  using the createLookaheadDFAs() method.  You could do this
2880324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2881324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *    Grammar g = new Grammar("...");
2882324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *    g.setLookahead(1, dfa1);
2883324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *    g.setLookahead(2, dfa2);
2884324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *    ...
2885324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2886324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setLookaheadDFA(int decision, DFA lookaheadDFA) {
2887324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = createDecision(decision);
2888324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.dfa = lookaheadDFA;
2889324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		GrammarAST ast = d.startState.associatedASTNode;
2890324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ast.setLookaheadDFA(lookaheadDFA);
2891324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2892324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2893324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setDecisionNFA(int decision, NFAState state) {
2894324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = createDecision(decision);
2895324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.startState = state;
2896324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2897324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2898324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setDecisionBlockAST(int decision, GrammarAST blockAST) {
2899324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("setDecisionBlockAST("+decision+", "+blockAST.token);
2900324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Decision d = createDecision(decision);
2901324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		d.blockAST = blockAST;
2902324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2903324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2904324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean allDecisionDFAHaveBeenCreated() {
2905324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return allDecisionDFACreated;
2906324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2907324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2908324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** How many token types have been allocated so far? */
2909324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getMaxTokenType() {
2910324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return composite.maxTokenType;
2911324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2912324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2913324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** What is the max char value possible for this grammar's target?  Use
2914324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  unicode max if no target defined.
2915324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2916324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getMaxCharValue() {
2917324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( generator!=null ) {
2918324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return generator.target.getMaxCharValue(generator);
2919324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2920324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		else {
2921324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return Label.MAX_CHAR_VALUE;
2922324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2923324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2924324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2925324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Return a set of all possible token or char types for this grammar */
2926324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public IntSet getTokenTypes() {
2927324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( type==LEXER ) {
2928324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return getAllCharValues();
2929324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2930324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return IntervalSet.of(Label.MIN_TOKEN_TYPE, getMaxTokenType());
2931324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2932324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2933324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** If there is a char vocabulary, use it; else return min to max char
2934324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as defined by the target.  If no target, use max unicode char value.
2935324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2936324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public IntSet getAllCharValues() {
2937324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( charVocabulary!=null ) {
2938324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return charVocabulary;
2939324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2940324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		IntSet allChar = IntervalSet.of(Label.MIN_CHAR_VALUE, getMaxCharValue());
2941324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return allChar;
2942324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2943324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2944324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Return a string representing the escaped char for code c.  E.g., If c
2945324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  has value 0x100, you will get "\u0100".  ASCII gets the usual
2946324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  char (non-hex) representation.  Control characters are spit out
2947324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  as unicode.  While this is specially set up for returning Java strings,
2948324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  it can be used by any language target that has the same syntax. :)
2949324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
2950324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  11/26/2005: I changed this to use double quotes, consistent with antlr.g
2951324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  12/09/2005: I changed so everything is single quotes
2952324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2953324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public static String getANTLRCharLiteralForChar(int c) {
2954324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( c<Label.MIN_CHAR_VALUE ) {
2955324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.internalError("invalid char value "+c);
2956324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return "'<INVALID>'";
2957324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2958324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( c<ANTLRLiteralCharValueEscape.length && ANTLRLiteralCharValueEscape[c]!=null ) {
2959324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return '\''+ANTLRLiteralCharValueEscape[c]+'\'';
2960324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2961324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( Character.UnicodeBlock.of((char)c)==Character.UnicodeBlock.BASIC_LATIN &&
2962324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			 !Character.isISOControl((char)c) ) {
2963324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( c=='\\' ) {
2964324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return "'\\\\'";
2965324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2966324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( c=='\'') {
2967324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return "'\\''";
2968324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
2969324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return '\''+Character.toString((char)c)+'\'';
2970324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
2971324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// turn on the bit above max "\uFFFF" value so that we pad with zeros
2972324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		// then only take last 4 digits
2973324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String hex = Integer.toHexString(c|0x10000).toUpperCase().substring(1,5);
2974324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String unicodeStr = "'\\u"+hex+"'";
2975324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return unicodeStr;
2976324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2977324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2978324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** For lexer grammars, return everything in unicode not in set.
2979324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  For parser and tree grammars, return everything in token space
2980324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  from MIN_TOKEN_TYPE to last valid token type or char value.
2981324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2982324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public IntSet complement(IntSet set) {
2983324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("complement "+set.toString(this));
2984324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("vocabulary "+getTokenTypes().toString(this));
2985324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		IntSet c = set.complement(getTokenTypes());
2986324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("result="+c.toString(this));
2987324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return c;
2988324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2989324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2990324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public IntSet complement(int atom) {
2991324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return complement(IntervalSet.of(atom));
2992324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
2993324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
2994324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Given set tree like ( SET A B ), check that A and B
2995324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  are both valid sets themselves, else we must tree like a BLOCK
2996324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
2997324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public boolean isValidSet(TreeToNFAConverter nfabuilder, GrammarAST t) {
2998324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		boolean valid = true;
2999324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
3000324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			//System.out.println("parse BLOCK as set tree: "+t.toStringTree());
3001324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			int alts = nfabuilder.testBlockAsSet(t);
3002324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			valid = alts > 1;
3003324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3004324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
3005324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			// The rule did not parse as a set, return null; ignore exception
3006324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			valid = false;
3007324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3008324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("valid? "+valid);
3009324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return valid;
3010324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3011324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3012324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the set equivalent (if any) of the indicated rule from this
3013324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  grammar.  Mostly used in the lexer to do ~T for some fragment rule
3014324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  T.  If the rule AST has a SET use that.  If the rule is a single char
3015324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  convert it to a set and return.  If rule is not a simple set (w/o actions)
3016324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  then return null.
3017324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  Rules have AST form:
3018324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
3019324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *		^( RULE ID modifier ARG RET SCOPE block EOR )
3020324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
3021324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public IntSet getSetFromRule(TreeToNFAConverter nfabuilder, String ruleName)
3022324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		throws RecognitionException
3023324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	{
3024324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		Rule r = getRule(ruleName);
3025324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( r==null ) {
3026324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
3027324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3028324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		IntSet elements = null;
3029324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("parsed tree: "+r.tree.toStringTree());
3030324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		elements = nfabuilder.setRule(r.tree);
3031324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		//System.out.println("elements="+elements);
3032324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return elements;
3033324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3034324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3035324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Decisions are linked together with transition(1).  Count how
3036324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  many there are.  This is here rather than in NFAState because
3037324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  a grammar decides how NFAs are put together to form a decision.
3038324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
3039324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public int getNumberOfAltsForDecisionNFA(NFAState decisionState) {
3040324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( decisionState==null ) {
3041324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return 0;
3042324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3043324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int n = 1;
3044324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NFAState p = decisionState;
3045324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		while ( p.transition[1] !=null ) {
3046324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			n++;
3047324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = (NFAState)p.transition[1].target;
3048324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3049324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return n;
3050324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3051324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3052324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** Get the ith alternative (1..n) from a decision; return null when
3053324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  an invalid alt is requested.  I must count in to find the right
3054324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  alternative number.  For (A|B), you get NFA structure (roughly):
3055324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
3056324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  o->o-A->o
3057324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  |
3058324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  o->o-B->o
3059324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *
3060324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  This routine returns the leftmost state for each alt.  So alt=1, returns
3061324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  the upperleft most state in this structure.
3062324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
3063324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public NFAState getNFAStateForAltOfDecision(NFAState decisionState, int alt) {
3064324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( decisionState==null || alt<=0 ) {
3065324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			return null;
3066324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3067324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		int n = 1;
3068324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		NFAState p = decisionState;
3069324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		while ( p!=null ) {
3070324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( n==alt ) {
3071324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				return p;
3072324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
3073324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			n++;
3074324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Transition next = p.transition[1];
3075324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			p = null;
3076324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( next!=null ) {
3077324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				p = (NFAState)next.target;
3078324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
3079324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3080324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return null;
3081324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3082324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3083324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/*
3084324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void computeRuleFOLLOWSets() {
3085324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		if ( getNumberOfDecisions()==0 ) {
3086324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			createNFAs();
3087324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3088324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		for (Iterator it = getRules().iterator(); it.hasNext();) {
3089324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			Rule r = (Rule)it.next();
3090324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			if ( r.isSynPred ) {
3091324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver				continue;
3092324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			}
3093324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			LookaheadSet s = ll1Analyzer.FOLLOW(r);
3094324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			System.out.println("FOLLOW("+r.name+")="+s);
3095324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3096324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3097324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	*/
3098324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3099324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public LookaheadSet FIRST(NFAState s) {
3100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ll1Analyzer.FIRST(s);
3101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public LookaheadSet LOOK(NFAState s) {
3104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return ll1Analyzer.LOOK(s);
3105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setCodeGenerator(CodeGenerator generator) {
3108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.generator = generator;
3109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public CodeGenerator getCodeGenerator() {
3112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return generator;
3113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public GrammarAST getGrammarTree() {
3116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return grammarTree;
3117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setGrammarTree(GrammarAST value) {
3120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		grammarTree = value;
3121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public Tool getTool() {
3124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return tool;
3125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void setTool(Tool tool) {
3128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		this.tool = tool;
3129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	/** given a token type and the text of the literal, come up with a
3132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  decent token type label.  For now it's just T<type>.  Actually,
3133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 *  if there is an aliased name from tokens like PLUS='+', use it.
3134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	 */
3135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String computeTokenNameFromLiteral(int tokenType, String literal) {
3136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return AUTO_GENERATED_TOKEN_NAME_PREFIX +tokenType;
3137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String toString() {
3140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	//	return "FFFFFFFFFFFFFF";
3141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return grammarTreeToString(grammarTree);
3142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String grammarTreeToString(GrammarAST t) {
3145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return grammarTreeToString(t, true);
3146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public String grammarTreeToString(GrammarAST t, boolean showActions) {
3149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		String s = null;
3150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
3151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s = t.getLine()+":"+(t.getCharPositionInLine()+1)+": ";
3152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s += new ANTLRTreePrinter(new CommonTreeNodeStream(t)).toString(this, showActions);
3153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (Exception e) {
3155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			s = "<invalid or missing tree structure>";
3156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		return s;
3158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	public void printGrammar(PrintStream output) {
3161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		ANTLRTreePrinter printer = new ANTLRTreePrinter(new CommonTreeNodeStream(getGrammarTree()));
3162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		try {
3163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			String g = printer.toString(this, false);
3164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			output.println(g);
3165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		catch (RecognitionException re) {
3167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver			ErrorManager.error(ErrorManager.MSG_SYNTAX_ERROR,re);
3168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver		}
3169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver	}
3170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
3171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
3172