grammar option cleanup. was a mess. -Doption=value works to override grammar options on cmd-line now.

This commit is contained in:
Terence Parr 2012-09-05 18:37:28 -07:00
parent ab64b1c62d
commit e4a9a44671
11 changed files with 82 additions and 40 deletions

View File

@ -1,14 +1,7 @@
grammar T;
options
{
output=AST;
backtrack=true;
options {
superClass=Z;
}
Integer : '0' .. '9';
myID : Integer*;
public json : myID+ -> ^(myID);
s : A ;

View File

@ -73,7 +73,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
public class Tool {
@ -124,6 +126,7 @@ public class Tool {
public boolean gen_listener = true;
public boolean gen_visitor = false;
public boolean abstract_recognizer = false;
public Map<String, String> grammarOptions = null;
public static Option[] optionDefs = {
new Option("outputDirectory", "-o", OptionArgType.STRING, "specify output directory where all output is generated"),
@ -140,6 +143,8 @@ public class Tool {
new Option("gen_visitor", "-visitor", "generate parse tree visitor"),
new Option("gen_visitor", "-no-visitor", "don't generate parse tree visitor (default)"),
new Option("abstract_recognizer", "-abstract", "generate abstract recognizer classes"),
new Option("-D<option>=value", "-message-format", "set a grammar-level option"),
new Option("saveLexer", "-Xsave-lexer", "save temp lexer file created for combined grammars"),
new Option("launch_ST_inspector", "-XdbgST", "launch StringTemplate visualizer on generated code"),
@ -209,6 +214,10 @@ public class Tool {
while ( args!=null && i<args.length ) {
String arg = args[i];
i++;
if ( arg.startsWith("-D") ) { // -Dlanguage=Java syntax
handleOptionSetArg(arg);
continue;
}
if ( arg.charAt(0)!='-' ) { // file name
grammarFiles.add(arg);
continue;
@ -275,6 +284,34 @@ public class Tool {
STGroup.trackCreationEvents = true;
return_dont_exit = true;
}
System.out.println(grammarOptions);
}
protected void handleOptionSetArg(String arg) {
int eq = arg.indexOf('=');
if ( eq>0 && arg.length()>3 ) {
String option = arg.substring("-D".length(), eq);
String value = arg.substring(eq+1);
if ( value.length()==0 ) {
errMgr.toolError(ErrorType.BAD_OPTION_SET_SYNTAX, arg);
return;
}
if ( Grammar.parserOptions.contains(option) ||
Grammar.lexerOptions.contains(option) )
{
if ( grammarOptions==null ) grammarOptions = new HashMap<String, String>();
grammarOptions.put(option, value);
}
else {
errMgr.grammarError(ErrorType.ILLEGAL_OPTION,
null,
null,
option);
}
}
else {
errMgr.toolError(ErrorType.BAD_OPTION_SET_SYNTAX, arg);
}
}
public void processGrammarsOnCommandLine() {
@ -432,6 +469,9 @@ public class Tool {
if ( root instanceof GrammarRootAST) {
((GrammarRootAST)root).hasErrors = p.getNumberOfSyntaxErrors()>0;
((GrammarRootAST)root).tokens = tokens;
if ( grammarOptions!=null ) {
((GrammarRootAST)root).cmdLineOptions = grammarOptions;
}
return ((GrammarRootAST)root);
}
return null;

View File

@ -69,17 +69,18 @@ import java.util.List;
public class LeftRecursiveRuleTransformer {
public GrammarRootAST ast;
public Collection<Rule> rules;
public Grammar g;
public Tool tool;
public LeftRecursiveRuleTransformer(GrammarRootAST ast, Collection<Rule> rules, Tool tool) {
public LeftRecursiveRuleTransformer(GrammarRootAST ast, Collection<Rule> rules, Grammar g) {
this.ast = ast;
this.rules = rules;
this.tool = tool;
this.g = g;
this.tool = g.tool;
}
public void translateLeftRecursiveRules() {
// TODO: what about -language foo cmd line?
String language = Grammar.getLanguageOption(ast);
String language = g.getOptionString("language");
// translate all recursive rules
List<String> leftRecursiveRuleNames = new ArrayList<String>();
for (Rule r : rules) {

View File

@ -46,7 +46,6 @@ import org.antlr.v4.runtime.atn.TokensStartState;
import org.antlr.v4.runtime.atn.Transition;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.LexerGrammar;
import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.ast.ActionAST;
@ -63,7 +62,7 @@ public class LexerATNFactory extends ParserATNFactory {
public LexerATNFactory(LexerGrammar g) {
super(g);
// use codegen to get correct language templates for lexer commands
String language = Grammar.getLanguageOption(g.ast);
String language = g.getOptionString("language");
CodeGenerator gen = new CodeGenerator(g.tool, null, language);
codegenTemplates = gen.templates;
}

View File

@ -70,7 +70,7 @@ public class CodeGenerator {
public int lineWidth = 72;
public CodeGenerator(@NotNull Grammar g) {
this(g.tool, g, g.getOptionString("language", "Java"));
this(g.tool, g, g.getOptionString("language"));
}
public CodeGenerator(@NotNull Tool tool, @NotNull Grammar g, String language) {

View File

@ -47,7 +47,7 @@ public class SemPred extends Action {
public SemPred(OutputModelFactory factory, GrammarAST ast) {
super(factory,ast);
GrammarAST failNode = ((PredAST)ast).getOption("fail");
GrammarAST failNode = ((PredAST)ast).getOptionAST("fail");
CodeGenerator gen = factory.getGenerator();
if ( failNode==null ) {
msg = ast.getText();

View File

@ -87,7 +87,7 @@ public class SemanticPipeline {
// TRANSFORM LEFT-RECURSIVE RULES
LeftRecursiveRuleTransformer lrtrans =
new LeftRecursiveRuleTransformer(g.ast, ruleCollector.rules.values(), g.tool);
new LeftRecursiveRuleTransformer(g.ast, ruleCollector.rules.values(), g);
lrtrans.translateLeftRecursiveRules();
// STORE RULES IN GRAMMAR

View File

@ -52,7 +52,7 @@ public enum ErrorType {
OUTPUT_DIR_IS_FILE(6, "output directory is a file: <arg>", ErrorSeverity.ERROR),
CANNOT_OPEN_FILE(7, "cannot find or open file: <arg><if(exception)>; reason: <exception><endif>", ErrorSeverity.ERROR),
FILE_AND_GRAMMAR_NAME_DIFFER(8, "grammar name <arg> and file name <arg2> differ", ErrorSeverity.ERROR),
// FILENAME_EXTENSION_ERROR("", ErrorSeverity.ERROR),
BAD_OPTION_SET_SYNTAX(9, "invalid -Dname=value syntax: <arg>", ErrorSeverity.ERROR),
INTERNAL_ERROR(20, "internal error: <arg> <arg2><if(exception)>: <exception><endif>\n" +
"<stackTrace; separator=\"\\n\">", ErrorSeverity.ERROR),

View File

@ -728,13 +728,6 @@ public class Grammar implements AttributeResolver {
}
public String getOptionString(String key) { return ast.getOptionString(key); }
public GrammarAST getOption(String key) { return ast.getOption(key); }
public String getOptionString(String key, String defaultValue) {
String v = ast.getOptionString(key);
if ( v!=null ) return v;
return defaultValue;
}
/** Manually get language option from tree */
// TODO: move to general tree visitor/parser class?

View File

@ -32,7 +32,8 @@ package org.antlr.v4.tool.ast;
import org.antlr.runtime.Token;
import org.antlr.v4.misc.CharSupport;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
public abstract class GrammarASTWithOptions extends GrammarAST {
protected Map<String, GrammarAST> options;
@ -53,7 +54,7 @@ public abstract class GrammarASTWithOptions extends GrammarAST {
}
public String getOptionString(String key) {
GrammarAST value = getOption(key);
GrammarAST value = getOptionAST(key);
if ( value == null ) return null;
if ( value instanceof ActionAST ) {
return value.getText();
@ -67,7 +68,10 @@ public abstract class GrammarASTWithOptions extends GrammarAST {
}
}
public GrammarAST getOption(String key) {
/** Gets AST node holding value for option key; ignores default options
* and command-line forced options.
*/
public GrammarAST getOptionAST(String key) {
if ( options==null ) return null;
return options.get(key);
}

View File

@ -37,16 +37,15 @@ import java.util.HashMap;
import java.util.Map;
public class GrammarRootAST extends GrammarASTWithOptions {
public static final Map<String, String> defaultOptions =
new HashMap<String, String>() {
{
put("language","Java");
}
};
public int grammarType; // LEXER, PARSER, TREE, GRAMMAR (combined)
public static final Map<String, String> defaultOptions =
new HashMap<String, String>() {{
put("language","Java");
}};
public int grammarType; // LEXER, PARSER, GRAMMAR (combined)
public boolean hasErrors;
/** Track stream used to create this tree */
public TokenStream tokens;
public Map<String, String> cmdLineOptions; // -DsuperClass=T on command line
public GrammarRootAST(GrammarAST node) {
super(node);
@ -54,9 +53,6 @@ public class GrammarRootAST extends GrammarASTWithOptions {
this.hasErrors = ((GrammarRootAST)node).hasErrors;
}
@Override
public Tree dupNode() { return new GrammarRootAST(this); }
public GrammarRootAST(int type) { super(type); }
public GrammarRootAST(Token t) { super(t); }
public GrammarRootAST(int type, Token t) { super(type, t); }
@ -64,6 +60,22 @@ public class GrammarRootAST extends GrammarASTWithOptions {
super(type,t,text);
}
@Override
public String getOptionString(String key) {
if ( cmdLineOptions!=null && cmdLineOptions.containsKey(key) ) {
return cmdLineOptions.get(key);
}
String value = super.getOptionString(key);
if ( value==null ) {
value = defaultOptions.get(key);
}
return value;
}
@Override
public Object visit(GrammarASTVisitor v) { return v.visit(this); }
@Override
public Tree dupNode() { return new GrammarRootAST(this); }
}