diff --git a/tool/src/org/antlr/v4/codegen/model/InvokeRule.java b/tool/src/org/antlr/v4/codegen/model/InvokeRule.java index efa39a68b..5649a138f 100644 --- a/tool/src/org/antlr/v4/codegen/model/InvokeRule.java +++ b/tool/src/org/antlr/v4/codegen/model/InvokeRule.java @@ -48,7 +48,7 @@ public class InvokeRule extends RuleElement implements LabeledOp { @ModelElement public List argExprsChunks; - public InvokeRule(OutputModelFactory factory, GrammarAST ast, GrammarAST labelAST) { + public InvokeRule(ParserFactory factory, GrammarAST ast, GrammarAST labelAST) { super(factory, ast); if ( ast.atnState!=null ) { RuleTransition ruleTrans = (RuleTransition)ast.atnState.transition(0); @@ -65,14 +65,17 @@ public class InvokeRule extends RuleElement implements LabeledOp { if ( labelAST!=null ) { // for x=r, define x and list_x String label = labelAST.getText(); - RuleContextDecl d = new RuleContextDecl(factory,label,ctxName); - labels.add(d); - rf.addContextDecl(ast.getAltLabel(), d); if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) { + factory.defineImplicitLabel(ast, this); String listLabel = gen.target.getListLabel(label); RuleContextListDecl l = new RuleContextListDecl(factory, listLabel, ctxName); rf.addContextDecl(ast.getAltLabel(), l); } + else { + RuleContextDecl d = new RuleContextDecl(factory,label,ctxName); + labels.add(d); + rf.addContextDecl(ast.getAltLabel(), d); + } } if ( ast.getChildCount()>0 ) { ActionAST arg = (ActionAST)ast.getChild(0); diff --git a/tool/test/org/antlr/v4/test/TestParserExec.java b/tool/test/org/antlr/v4/test/TestParserExec.java index 4f641034c..9f3c6622b 100644 --- a/tool/test/org/antlr/v4/test/TestParserExec.java +++ b/tool/test/org/antlr/v4/test/TestParserExec.java @@ -34,6 +34,21 @@ import org.junit.Test; * the remaining input to match. */ public class TestParserExec extends BaseTest { + @Test public void testLabels() throws Exception { + String grammar = + "grammar T;\n" + + "a : b1=b b2+=b*;\n" + + "b : id=ID val+=INT*;\n" + + "ID : 'a'..'z'+ ;\n" + + "INT : '0'..'9'+;\n" + + "WS : (' '|'\\n') {skip();} ;\n"; + + String found = execParser("T.g", grammar, "TParser", "TLexer", "a", + "abc 34", false); + assertEquals("", found); + assertEquals(null, stderrDuringParse); + } + @Test public void testBasic() throws Exception { String grammar = "grammar T;\n" + diff --git a/tool/test/org/antlr/v4/test/TestPerformance.java b/tool/test/org/antlr/v4/test/TestPerformance.java index 2740bc1b8..c6c7afc86 100644 --- a/tool/test/org/antlr/v4/test/TestPerformance.java +++ b/tool/test/org/antlr/v4/test/TestPerformance.java @@ -44,7 +44,9 @@ import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import org.antlr.v4.runtime.atn.ATNConfig; @@ -298,6 +300,8 @@ public class TestPerformance extends BaseTest { if (SHOW_DFA_STATE_STATS) { int states = 0; + int configs = 0; + Set uniqueConfigs = new HashSet(); for (int i = 0; i < decisionToDFA.length; i++) { DFA dfa = decisionToDFA[i]; @@ -306,9 +310,13 @@ public class TestPerformance extends BaseTest { } states += dfa.states.size(); + for (DFAState state : dfa.states.values()) { + configs += state.configset.size(); + uniqueConfigs.addAll(state.configset); + } } - System.out.format("There are %d DFAState instances.\n", states); + System.out.format("There are %d DFAState instances, %d configs (%d unique).\n", states, configs, uniqueConfigs.size()); } int localDfaCount = 0; @@ -418,7 +426,7 @@ public class TestPerformance extends BaseTest { @SuppressWarnings({"unchecked"}) final Class parserClass = (Class)loader.loadClass("JavaParser"); @SuppressWarnings({"unchecked"}) - final Class> listenerClass = (Class>)loader.loadClass("BlankJavaListener"); + final Class> listenerClass = (Class>)loader.loadClass("JavaBaseListener"); TestPerformance.sharedListener = listenerClass.newInstance(); final Constructor lexerCtor = lexerClass.getConstructor(CharStream.class);