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