persistence.antlr.DefineGrammarSymbols Maven / Gradle / Ivy
The newest version!
package persistence.antlr;
/* ANTLR Translator Generator
* Project led by Terence Parr at http://www.jGuru.com
* Software rights: http://www.antlr.org/license.html
*
*/
import java.util.Hashtable;
import persistence.antlr.collections.impl.BitSet;
/**DefineGrammarSymbols is a behavior for the ANTLRParser that adds all
* the token and rule symbols to the grammar symbol table.
*
* Token types are assigned to token symbols in this class also.
* The token type for a token is done in the order seen (lexically).
*/
public class DefineGrammarSymbols implements ANTLRGrammarParseBehavior {
// Contains all of the defined parser and lexer Grammar's indexed by name
protected Hashtable grammars = new Hashtable();
// Contains all the TokenManagers indexed by name
protected Hashtable tokenManagers = new Hashtable();
// Current grammar (parser or lexer)
protected Grammar grammar;
// The tool under which this is invoked
protected Tool tool;
// The grammar analyzer object
LLkAnalyzer analyzer;
// The command-line arguments passed to the tool.
// This allows each grammar to parse the arguments as it is created
String[] args;
// Name for default token manager does not match any valid name
static final String DEFAULT_TOKENMANAGER_NAME = "*default";
// Header actions apply to all parsers unless redefined
// Contains all of the header actions indexed by name
protected Hashtable headerActions = new Hashtable();
// Place where preamble is stored until a grammar is defined
Token thePreambleAction = new CommonToken(Token.INVALID_TYPE, ""); // init to empty token
// The target language
String language = "Java";
protected int numLexers = 0;
protected int numParsers = 0;
protected int numTreeParsers = 0;
public DefineGrammarSymbols(Tool tool_, String[] args_, LLkAnalyzer analyzer_) {
tool = tool_;
args = args_;
analyzer = analyzer_;
}
public void _refStringLiteral(Token lit, Token label, int autoGenType, boolean lastInRule) {
if (!(grammar instanceof LexerGrammar)) {
// String literals are treated like tokens except by the lexer
String str = lit.getText();
if (grammar.tokenManager.getTokenSymbol(str) != null) {
// string symbol is already defined
return;
}
StringLiteralSymbol sl = new StringLiteralSymbol(str);
int tt = grammar.tokenManager.nextTokenType();
sl.setTokenType(tt);
grammar.tokenManager.define(sl);
}
}
/** Reference a token */
public void _refToken(Token assignId,
Token t,
Token label,
Token args,
boolean inverted,
int autoGenType,
boolean lastInRule) {
String id = t.getText();
if (!grammar.tokenManager.tokenDefined(id)) {
/*
// RK: dish out a warning if the token was not defined before.
tool.warning("Token '" + id + "' defined outside tokens section",
tool.grammarFile, t.getLine(), t.getColumn());
*/
int tt = grammar.tokenManager.nextTokenType();
TokenSymbol ts = new TokenSymbol(id);
ts.setTokenType(tt);
grammar.tokenManager.define(ts);
}
}
/** Abort the processing of a grammar due to syntax errors */
public void abortGrammar() {
if (grammar != null && grammar.getClassName() != null) {
grammars.remove(grammar.getClassName());
}
grammar = null;
}
public void beginAlt(boolean doAST_) {
}
public void beginChildList() {
}
// Exception handling
public void beginExceptionGroup() {
}
public void beginExceptionSpec(Token label) {
}
public void beginSubRule(Token label, Token start, boolean not) {
}
public void beginTree(Token tok) throws SemanticException {
}
/** Define a lexer or parser rule */
public void defineRuleName(Token r,
String access,
boolean ruleAutoGen,
String docComment)
throws SemanticException {
String id = r.getText();
// if ( Character.isUpperCase(id.charAt(0)) ) {
if (r.type == ANTLRTokenTypes.TOKEN_REF) {
// lexer rule
id = CodeGenerator.encodeLexerRuleName(id);
// make sure we define it as token identifier also
if (!grammar.tokenManager.tokenDefined(r.getText())) {
int tt = grammar.tokenManager.nextTokenType();
TokenSymbol ts = new TokenSymbol(r.getText());
ts.setTokenType(tt);
grammar.tokenManager.define(ts);
}
}
RuleSymbol rs;
if (grammar.isDefined(id)) {
// symbol seen before?
rs = (RuleSymbol)grammar.getSymbol(id);
// rule just referenced or has it been defined yet?
if (rs.isDefined()) {
tool.error("redefinition of rule " + id, grammar.getFilename(), r.getLine(), r.getColumn());
}
}
else {
rs = new RuleSymbol(id);
grammar.define(rs);
}
rs.setDefined();
rs.access = access;
rs.comment = docComment;
}
/** Define a token from tokens {...}.
* Must be label and literal or just label or just a literal.
*/
public void defineToken(Token tokname, Token tokliteral) {
String name = null;
String literal = null;
if (tokname != null) {
name = tokname.getText();
}
if (tokliteral != null) {
literal = tokliteral.getText();
}
// System.out.println("defining " + name + " with literal " + literal);
//
if (literal != null) {
StringLiteralSymbol sl = (StringLiteralSymbol)grammar.tokenManager.getTokenSymbol(literal);
if (sl != null) {
// This literal is known already.
// If the literal has no label already, but we can provide
// one here, then no problem, just map the label to the literal
// and don't change anything else.
// Otherwise, labels conflict: error.
if (name == null || sl.getLabel() != null) {
tool.warning("Redefinition of literal in tokens {...}: " + literal, grammar.getFilename(), tokliteral.getLine(), tokliteral.getColumn());
return;
}
else if (name != null) {
// The literal had no label, but new def does. Set it.
sl.setLabel(name);
// Also, map the label to the literal.
grammar.tokenManager.mapToTokenSymbol(name, sl);
}
}
// if they provide a name/label and that name/label already
// exists, just hook this literal onto old token.
if (name != null) {
TokenSymbol ts = (TokenSymbol)grammar.tokenManager.getTokenSymbol(name);
if (ts != null) {
// watch out that the label is not more than just a token.
// If it already has a literal attached, then: conflict.
if (ts instanceof StringLiteralSymbol) {
tool.warning("Redefinition of token in tokens {...}: " + name, grammar.getFilename(), tokliteral.getLine(), tokliteral.getColumn());
return;
}
// a simple token symbol such as DECL is defined
// must convert it to a StringLiteralSymbol with a
// label by co-opting token type and killing old
// TokenSymbol. Kill mapping and entry in vector
// of token manager.
// First, claim token type.
int ttype = ts.getTokenType();
// now, create string literal with label
sl = new StringLiteralSymbol(literal);
sl.setTokenType(ttype);
sl.setLabel(name);
// redefine this critter as a string literal
grammar.tokenManager.define(sl);
// make sure the label can be used also.
grammar.tokenManager.mapToTokenSymbol(name, sl);
return;
}
// here, literal was labeled but not by a known token symbol.
}
sl = new StringLiteralSymbol(literal);
int tt = grammar.tokenManager.nextTokenType();
sl.setTokenType(tt);
sl.setLabel(name);
grammar.tokenManager.define(sl);
if (name != null) {
// make the label point at token symbol too
grammar.tokenManager.mapToTokenSymbol(name, sl);
}
}
// create a token in the token manager not a literal
else {
if (grammar.tokenManager.tokenDefined(name)) {
tool.warning("Redefinition of token in tokens {...}: " + name, grammar.getFilename(), tokname.getLine(), tokname.getColumn());
return;
}
int tt = grammar.tokenManager.nextTokenType();
TokenSymbol ts = new TokenSymbol(name);
ts.setTokenType(tt);
grammar.tokenManager.define(ts);
}
}
public void endAlt() {
}
public void endChildList() {
}
public void endExceptionGroup() {
}
public void endExceptionSpec() {
}
public void endGrammar() {
}
/** Called after the optional options section, to compensate for
* options that may not have been set.
* This method is bigger than it needs to be, but is much more
* clear if I delineate all the cases.
*/
public void endOptions() {
// NO VOCAB OPTIONS
if (grammar.exportVocab == null && grammar.importVocab == null) {
grammar.exportVocab = grammar.getClassName();
// Can we get initial vocab from default shared vocab?
if (tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
// Use the already-defined token manager
grammar.exportVocab = DEFAULT_TOKENMANAGER_NAME;
TokenManager tm = (TokenManager)tokenManagers.get(DEFAULT_TOKENMANAGER_NAME);
// System.out.println("No tokenVocabulary for '" + grammar.getClassName() + "', using default '" + tm.getName() + "'");
grammar.setTokenManager(tm);
return;
}
// no shared vocab for file, make new one
// System.out.println("No exportVocab for '" + grammar.getClassName() + "', creating default '" + grammar.exportVocab + "'");
TokenManager tm = new SimpleTokenManager(grammar.exportVocab, tool);
grammar.setTokenManager(tm);
// Add the token manager to the list of token managers
tokenManagers.put(grammar.exportVocab, tm);
// no default vocab, so make this the default vocab
tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
return;
}
// NO OUTPUT, BUT HAS INPUT VOCAB
if (grammar.exportVocab == null && grammar.importVocab != null) {
grammar.exportVocab = grammar.getClassName();
// first make sure input!=output
if (grammar.importVocab.equals(grammar.exportVocab)) {
tool.warning("Grammar " + grammar.getClassName() +
" cannot have importVocab same as default output vocab (grammar name); ignored.");
// kill importVocab option and try again: use default vocab
grammar.importVocab = null;
endOptions();
return;
}
// check to see if the vocab is already in memory
// (defined by another grammar in the file). Not normal situation.
if (tokenManagers.containsKey(grammar.importVocab)) {
// make a copy since we'll be generating a new output vocab
// and we don't want to affect this one. Set the name to
// the default output vocab==classname.
TokenManager tm = (TokenManager)tokenManagers.get(grammar.importVocab);
// System.out.println("Duping importVocab of " + grammar.importVocab);
TokenManager dup = (TokenManager)tm.clone();
dup.setName(grammar.exportVocab);
// System.out.println("Setting name to " + grammar.exportVocab);
dup.setReadOnly(false);
grammar.setTokenManager(dup);
tokenManagers.put(grammar.exportVocab, dup);
return;
}
// System.out.println("reading in vocab "+grammar.importVocab);
// Must be a file, go get it.
ImportVocabTokenManager tm =
new ImportVocabTokenManager(grammar,
grammar.importVocab + CodeGenerator.TokenTypesFileSuffix + CodeGenerator.TokenTypesFileExt,
grammar.exportVocab,
tool);
tm.setReadOnly(false); // since renamed, can write out
// Add this token manager to the list so its tokens will be generated
tokenManagers.put(grammar.exportVocab, tm);
// System.out.println("vocab renamed to default output vocab of "+tm.getName());
// Assign the token manager to this grammar.
grammar.setTokenManager(tm);
// set default vocab if none
if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
}
return;
}
// OUTPUT VOCAB, BUT NO INPUT VOCAB
if (grammar.exportVocab != null && grammar.importVocab == null) {
// share with previous vocab if it exists
if (tokenManagers.containsKey(grammar.exportVocab)) {
// Use the already-defined token manager
TokenManager tm = (TokenManager)tokenManagers.get(grammar.exportVocab);
// System.out.println("Sharing exportVocab of " + grammar.exportVocab);
grammar.setTokenManager(tm);
return;
}
// create new output vocab
// System.out.println("Creating exportVocab " + grammar.exportVocab);
TokenManager tm = new SimpleTokenManager(grammar.exportVocab, tool);
grammar.setTokenManager(tm);
// Add the token manager to the list of token managers
tokenManagers.put(grammar.exportVocab, tm);
// set default vocab if none
if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
}
return;
}
// BOTH INPUT AND OUTPUT VOCAB
if (grammar.exportVocab != null && grammar.importVocab != null) {
// don't want input==output
if (grammar.importVocab.equals(grammar.exportVocab)) {
tool.error("exportVocab of " + grammar.exportVocab + " same as importVocab; probably not what you want");
}
// does the input vocab already exist in memory?
if (tokenManagers.containsKey(grammar.importVocab)) {
// make a copy since we'll be generating a new output vocab
// and we don't want to affect this one.
TokenManager tm = (TokenManager)tokenManagers.get(grammar.importVocab);
// System.out.println("Duping importVocab of " + grammar.importVocab);
TokenManager dup = (TokenManager)tm.clone();
dup.setName(grammar.exportVocab);
// System.out.println("Setting name to " + grammar.exportVocab);
dup.setReadOnly(false);
grammar.setTokenManager(dup);
tokenManagers.put(grammar.exportVocab, dup);
return;
}
// Must be a file, go get it.
ImportVocabTokenManager tm =
new ImportVocabTokenManager(grammar,
grammar.importVocab + CodeGenerator.TokenTypesFileSuffix + CodeGenerator.TokenTypesFileExt,
grammar.exportVocab,
tool);
tm.setReadOnly(false); // write it out as we've changed name
// Add this token manager to the list so its tokens will be generated
tokenManagers.put(grammar.exportVocab, tm);
// Assign the token manager to this grammar.
grammar.setTokenManager(tm);
// set default vocab if none
if (!tokenManagers.containsKey(DEFAULT_TOKENMANAGER_NAME)) {
tokenManagers.put(DEFAULT_TOKENMANAGER_NAME, tm);
}
return;
}
}
public void endRule(String r) {
}
public void endSubRule() {
}
public void endTree() {
}
public void hasError() {
}
public void noASTSubRule() {
}
public void oneOrMoreSubRule() {
}
public void optionalSubRule() {
}
public void setUserExceptions(String thr) {
}
public void refAction(Token action) {
}
public void refArgAction(Token action) {
}
public void refCharLiteral(Token lit, Token label, boolean inverted, int autoGenType, boolean lastInRule) {
}
public void refCharRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
}
public void refElementOption(Token option, Token value) {
}
public void refTokensSpecElementOption(Token tok, Token option, Token value) {
}
public void refExceptionHandler(Token exTypeAndName, Token action) {
}
// Header action applies to all parsers and lexers.
public void refHeaderAction(Token name, Token act) {
String key;
if (name == null)
key = "";
else
key = StringUtils.stripFrontBack(name.getText(), "\"", "\"");
// FIXME: depending on the mode the inserted header actions should
// be checked for sanity.
if (headerActions.containsKey(key)) {
if (key.equals(""))
tool.error(act.getLine() + ": header action already defined");
else
tool.error(act.getLine() + ": header action '" + key + "' already defined");
}
headerActions.put(key, act);
}
public String getHeaderAction(String name) {
Token t = (Token)headerActions.get(name);
if (t == null) {
return "";
}
return t.getText();
}
public void refInitAction(Token action) {
}
public void refMemberAction(Token act) {
}
public void refPreambleAction(Token act) {
thePreambleAction = act;
}
public void refReturnAction(Token returnAction) {
}
public void refRule(Token idAssign,
Token r,
Token label,
Token args,
int autoGenType) {
String id = r.getText();
// if ( Character.isUpperCase(id.charAt(0)) ) { // lexer rule?
if (r.type == ANTLRTokenTypes.TOKEN_REF) {
// lexer rule?
id = CodeGenerator.encodeLexerRuleName(id);
}
if (!grammar.isDefined(id)) {
grammar.define(new RuleSymbol(id));
}
}
public void refSemPred(Token pred) {
}
public void refStringLiteral(Token lit,
Token label,
int autoGenType,
boolean lastInRule) {
_refStringLiteral(lit, label, autoGenType, lastInRule);
}
/** Reference a token */
public void refToken(Token assignId, Token t, Token label, Token args,
boolean inverted, int autoGenType, boolean lastInRule) {
_refToken(assignId, t, label, args, inverted, autoGenType, lastInRule);
}
public void refTokenRange(Token t1, Token t2, Token label, int autoGenType, boolean lastInRule) {
// ensure that the DefineGrammarSymbols methods are called; otherwise a range addes more
// token refs to the alternative by calling MakeGrammar.refToken etc...
if (t1.getText().charAt(0) == '"') {
refStringLiteral(t1, null, GrammarElement.AUTO_GEN_NONE, lastInRule);
}
else {
_refToken(null, t1, null, null, false, GrammarElement.AUTO_GEN_NONE, lastInRule);
}
if (t2.getText().charAt(0) == '"') {
_refStringLiteral(t2, null, GrammarElement.AUTO_GEN_NONE, lastInRule);
}
else {
_refToken(null, t2, null, null, false, GrammarElement.AUTO_GEN_NONE, lastInRule);
}
}
public void refTreeSpecifier(Token treeSpec) {
}
public void refWildcard(Token t, Token label, int autoGenType) {
}
/** Get ready to process a new grammar */
public void reset() {
grammar = null;
}
public void setArgOfRuleRef(Token argaction) {
}
/** Set the character vocabulary for a lexer */
public void setCharVocabulary(BitSet b) {
// grammar should enforce that this is only called for lexer
((LexerGrammar)grammar).setCharVocabulary(b);
}
/** setFileOption: Associate an option value with a key.
* This applies to options for an entire grammar file.
* @param key The token containing the option name
* @param value The token containing the option value.
*/
public void setFileOption(Token key, Token value, String filename) {
if (key.getText().equals("language")) {
if (value.getType() == ANTLRParser.STRING_LITERAL) {
language = StringUtils.stripBack(StringUtils.stripFront(value.getText(), '"'), '"');
}
else if (value.getType() == ANTLRParser.TOKEN_REF || value.getType() == ANTLRParser.RULE_REF) {
language = value.getText();
}
else {
tool.error("language option must be string or identifier", filename, value.getLine(), value.getColumn());
}
}
else if (key.getText().equals("mangleLiteralPrefix")) {
if (value.getType() == ANTLRParser.STRING_LITERAL) {
tool.literalsPrefix = StringUtils.stripFrontBack(value.getText(), "\"", "\"");
}
else {
tool.error("mangleLiteralPrefix option must be string", filename, value.getLine(), value.getColumn());
}
}
else if (key.getText().equals("upperCaseMangledLiterals")) {
if (value.getText().equals("true")) {
tool.upperCaseMangledLiterals = true;
}
else if (value.getText().equals("false")) {
tool.upperCaseMangledLiterals = false;
}
else {
grammar.antlrTool.error("Value for upperCaseMangledLiterals must be true or false", filename, key.getLine(), key.getColumn());
}
}
else if ( key.getText().equals("namespaceStd") ||
key.getText().equals("namespaceAntlr") ||
key.getText().equals("genHashLines")
) {
if (!language.equals("Cpp")) {
tool.error(key.getText() + " option only valid for C++", filename, key.getLine(), key.getColumn());
}
else {
if (key.getText().equals("noConstructors")) {
if (!(value.getText().equals("true") || value.getText().equals("false")))
tool.error("noConstructors option must be true or false", filename, value.getLine(), value.getColumn());
tool.noConstructors = value.getText().equals("true");
} else if (key.getText().equals("genHashLines")) {
if (!(value.getText().equals("true") || value.getText().equals("false")))
tool.error("genHashLines option must be true or false", filename, value.getLine(), value.getColumn());
tool.genHashLines = value.getText().equals("true");
}
else {
if (value.getType() != ANTLRParser.STRING_LITERAL) {
tool.error(key.getText() + " option must be a string", filename, value.getLine(), value.getColumn());
}
else {
if (key.getText().equals("namespaceStd"))
tool.namespaceStd = value.getText();
else if (key.getText().equals("namespaceAntlr"))
tool.namespaceAntlr = value.getText();
}
}
}
}
else if ( key.getText().equals("namespace") ) {
if ( !language.equals("Cpp") && !language.equals("CSharp") )
{
tool.error(key.getText() + " option only valid for C++ and C# (a.k.a CSharp)", filename, key.getLine(), key.getColumn());
}
else
{
if (value.getType() != ANTLRParser.STRING_LITERAL)
{
tool.error(key.getText() + " option must be a string", filename, value.getLine(), value.getColumn());
}
else {
if (key.getText().equals("namespace"))
tool.setNameSpace(value.getText());
}
}
}
else {
tool.error("Invalid file-level option: " + key.getText(), filename, key.getLine(), value.getColumn());
}
}
/** setGrammarOption: Associate an option value with a key.
* This function forwards to Grammar.setOption for some options.
* @param key The token containing the option name
* @param value The token containing the option value.
*/
public void setGrammarOption(Token key, Token value) {
if (key.getText().equals("tokdef") || key.getText().equals("tokenVocabulary")) {
tool.error("tokdef/tokenVocabulary options are invalid >= ANTLR 2.6.0.\n" +
" Use importVocab/exportVocab instead. Please see the documentation.\n" +
" The previous options were so heinous that Terence changed the whole\n" +
" vocabulary mechanism; it was better to change the names rather than\n" +
" subtly change the functionality of the known options. Sorry!", grammar.getFilename(), value.getLine(), value.getColumn());
}
else if (key.getText().equals("literal") &&
grammar instanceof LexerGrammar) {
tool.error("the literal option is invalid >= ANTLR 2.6.0.\n" +
" Use the \"tokens {...}\" mechanism instead.",
grammar.getFilename(), value.getLine(), value.getColumn());
}
else if (key.getText().equals("exportVocab")) {
// Set the token manager associated with the parser
if (value.getType() == ANTLRParser.RULE_REF || value.getType() == ANTLRParser.TOKEN_REF) {
grammar.exportVocab = value.getText();
}
else {
tool.error("exportVocab must be an identifier", grammar.getFilename(), value.getLine(), value.getColumn());
}
}
else if (key.getText().equals("importVocab")) {
if (value.getType() == ANTLRParser.RULE_REF || value.getType() == ANTLRParser.TOKEN_REF) {
grammar.importVocab = value.getText();
}
else {
tool.error("importVocab must be an identifier", grammar.getFilename(), value.getLine(), value.getColumn());
}
}
else {
// Forward all unrecognized options to the grammar
grammar.setOption(key.getText(), value);
}
}
public void setRuleOption(Token key, Token value) {
}
public void setSubruleOption(Token key, Token value) {
}
/** Start a new lexer */
public void startLexer(String file, Token name, String superClass, String doc) {
if (numLexers > 0) {
tool.panic("You may only have one lexer per grammar file: class " + name.getText());
}
numLexers++;
reset();
//System.out.println("Processing lexer '" + name.getText() + "'");
// Does the lexer already exist?
Grammar g = (Grammar)grammars.get(name);
if (g != null) {
if (!(g instanceof LexerGrammar)) {
tool.panic("'" + name.getText() + "' is already defined as a non-lexer");
}
else {
tool.panic("Lexer '" + name.getText() + "' is already defined");
}
}
else {
// Create a new lexer grammar
LexerGrammar lg = new LexerGrammar(name.getText(), tool, superClass);
lg.comment = doc;
lg.processArguments(args);
lg.setFilename(file);
grammars.put(lg.getClassName(), lg);
// Use any preamble action
lg.preambleAction = thePreambleAction;
thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
// This is now the current grammar
grammar = lg;
}
}
/** Start a new parser */
public void startParser(String file, Token name, String superClass, String doc) {
if (numParsers > 0) {
tool.panic("You may only have one parser per grammar file: class " + name.getText());
}
numParsers++;
reset();
//System.out.println("Processing parser '" + name.getText() + "'");
// Is this grammar already defined?
Grammar g = (Grammar)grammars.get(name);
if (g != null) {
if (!(g instanceof ParserGrammar)) {
tool.panic("'" + name.getText() + "' is already defined as a non-parser");
}
else {
tool.panic("Parser '" + name.getText() + "' is already defined");
}
}
else {
// Create a new grammar
grammar = new ParserGrammar(name.getText(), tool, superClass);
grammar.comment = doc;
grammar.processArguments(args);
grammar.setFilename(file);
grammars.put(grammar.getClassName(), grammar);
// Use any preamble action
grammar.preambleAction = thePreambleAction;
thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
}
}
/** Start a new tree-walker */
public void startTreeWalker(String file, Token name, String superClass, String doc) {
if (numTreeParsers > 0) {
tool.panic("You may only have one tree parser per grammar file: class " + name.getText());
}
numTreeParsers++;
reset();
//System.out.println("Processing tree-walker '" + name.getText() + "'");
// Is this grammar already defined?
Grammar g = (Grammar)grammars.get(name);
if (g != null) {
if (!(g instanceof TreeWalkerGrammar)) {
tool.panic("'" + name.getText() + "' is already defined as a non-tree-walker");
}
else {
tool.panic("Tree-walker '" + name.getText() + "' is already defined");
}
}
else {
// Create a new grammar
grammar = new TreeWalkerGrammar(name.getText(), tool, superClass);
grammar.comment = doc;
grammar.processArguments(args);
grammar.setFilename(file);
grammars.put(grammar.getClassName(), grammar);
// Use any preamble action
grammar.preambleAction = thePreambleAction;
thePreambleAction = new CommonToken(Token.INVALID_TYPE, "");
}
}
public void synPred() {
}
public void zeroOrMoreSubRule() {
}
}