From b4413e865642fc32145986721902c6f4d4954804 Mon Sep 17 00:00:00 2001 From: Sam Harwell Date: Tue, 26 Mar 2013 23:29:03 -0500 Subject: [PATCH] Fix handling of empty options{} block in grammar (fixes #194) --- tool/src/org/antlr/v4/tool/Grammar.java | 2 +- .../v4/tool/GrammarTransformPipeline.java | 2 +- .../antlr/v4/test/TestCompositeGrammars.java | 17 +++++++ .../antlr/v4/test/TestToolSyntaxErrors.java | 45 +++++++++++++++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/tool/src/org/antlr/v4/tool/Grammar.java b/tool/src/org/antlr/v4/tool/Grammar.java index 679609ad0..2b1ef17df 100644 --- a/tool/src/org/antlr/v4/tool/Grammar.java +++ b/tool/src/org/antlr/v4/tool/Grammar.java @@ -756,7 +756,7 @@ public class Grammar implements AttributeResolver { */ public static void setNodeOptions(GrammarAST node, GrammarAST options) { GrammarASTWithOptions t = (GrammarASTWithOptions)node; - if ( t.getChildCount()==0 ) return; + if ( t.getChildCount()==0 || options.getChildCount()==0 ) return; for (Object o : options.getChildren()) { GrammarAST c = (GrammarAST)o; if ( c.getType()==ANTLRParser.ASSIGN ) { diff --git a/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java b/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java index 5fd0b248d..6f9bf037d 100644 --- a/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java +++ b/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java @@ -293,7 +293,7 @@ public class GrammarTransformPipeline { // COPY OPTIONS GrammarAST optionsRoot = (GrammarAST)combinedAST.getFirstChildWithType(ANTLRParser.OPTIONS); - if ( optionsRoot!=null ) { + if ( optionsRoot!=null && optionsRoot.getChildCount()!=0 ) { GrammarAST lexerOptionsRoot = (GrammarAST)adaptor.dupNode(optionsRoot); lexerAST.addChild(lexerOptionsRoot); GrammarAST[] options = optionsRoot.getChildren().toArray(new GrammarAST[0]); diff --git a/tool/test/org/antlr/v4/test/TestCompositeGrammars.java b/tool/test/org/antlr/v4/test/TestCompositeGrammars.java index 112cac938..e91440cfc 100644 --- a/tool/test/org/antlr/v4/test/TestCompositeGrammars.java +++ b/tool/test/org/antlr/v4/test/TestCompositeGrammars.java @@ -664,4 +664,21 @@ public class TestCompositeGrammars extends BaseTest { assertEquals("", found); } + @Test public void testImportedGrammarWithEmptyOptions() throws Exception { + String slave = + "parser grammar S;\n" + + "options {}\n" + + "a : B ;\n"; + mkdir(tmpdir); + writeFile(tmpdir, "S.g4", slave); + String master = + "grammar M;\n" + + "import S;\n" + + "s : a ;\n" + + "B : 'b' ;" + + "WS : (' '|'\\n') -> skip ;\n" ; + String found = execParser("M.g4", master, "MParser", "MLexer", + "s", "b", debug); + assertEquals("", found); + } } diff --git a/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java b/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java index 143b5f37c..f8864e20a 100644 --- a/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java +++ b/tool/test/org/antlr/v4/test/TestToolSyntaxErrors.java @@ -172,4 +172,49 @@ public class TestToolSyntaxErrors extends BaseTest { super.testErrors(pair, true); } + /** + * This is a regression test for antlr/antlr4#194 + * "NullPointerException on 'options{}' in grammar file" + * https://github.com/antlr/antlr4/issues/194 + */ + @Test public void testEmptyGrammarOptions() { + String[] pair = new String[] { + "grammar A;\n" + + "options {}\n" + + "a : 'x' ;\n", + + "" + }; + super.testErrors(pair, true); + } + + /** + * This is a "related" regression test for antlr/antlr4#194 + * "NullPointerException on 'options{}' in grammar file" + * https://github.com/antlr/antlr4/issues/194 + */ + @Test public void testEmptyRuleOptions() { + String[] pair = new String[] { + "grammar A;\n" + + "a options{} : 'x' ;\n", + + "" + }; + super.testErrors(pair, true); + } + + /** + * This is a "related" regression test for antlr/antlr4#194 + * "NullPointerException on 'options{}' in grammar file" + * https://github.com/antlr/antlr4/issues/194 + */ + @Test public void testEmptyBlockOptions() { + String[] pair = new String[] { + "grammar A;\n" + + "a : (options{} : 'x') ;\n", + + "" + }; + super.testErrors(pair, true); + } }