diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/RunOptions.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/RunOptions.java index 87a9d8334c..29fe6e4d7c 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/RunOptions.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/RunOptions.java @@ -24,6 +24,7 @@ public class RunOptions { public final boolean showDFA; public final Stage endStage; public final String superClass; + public final String libDir; public final String actionTemplates; public final PredictionMode predictionMode; public final boolean buildParseTree; @@ -32,7 +33,7 @@ public RunOptions(String grammarFileName, String grammarStr, String parserName, boolean useListener, boolean useVisitor, String startRuleName, String input, boolean profile, boolean showDiagnosticErrors, boolean traceATN, boolean showDFA, Stage endStage, - String language, String superClass, String actionTemplates, PredictionMode predictionMode, boolean buildParseTree) { + String language, String superClass, String libDir, String actionTemplates, PredictionMode predictionMode, boolean buildParseTree) { this.grammarFileName = grammarFileName; this.grammarStr = grammarStr; this.parserName = parserName; @@ -70,6 +71,7 @@ else if (lexerName != null) { this.showDFA = showDFA; this.endStage = endStage; this.superClass = superClass; + this.libDir = libDir; this.actionTemplates = actionTemplates; this.predictionMode = predictionMode; this.buildParseTree = buildParseTree; diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeRunner.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeRunner.java index c9d302b34e..7840f33b12 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeRunner.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeRunner.java @@ -168,6 +168,12 @@ public State run(RunOptions runOptions) { if (runOptions.useVisitor) { options.add("-visitor"); } + + if (runOptions.libDir != null && runOptions.libDir.length() > 0) { + options.add("-lib"); + options.add(runOptions.libDir); + } + if (runOptions.superClass != null && runOptions.superClass.length() > 0) { options.add("-DsuperClass=" + runOptions.superClass); } diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTests.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTests.java index 733110a69b..762514b517 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTests.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTests.java @@ -168,6 +168,7 @@ private static String test(RuntimeTestDescriptor descriptor, RuntimeRunner runne targetName, superClass, null, + null, descriptor.predictionMode, descriptor.buildParseTree ); diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/TraceATN.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/TraceATN.java index 31f786a6ed..4aabb9e277 100644 --- a/runtime-testsuite/test/org/antlr/v4/test/runtime/TraceATN.java +++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/TraceATN.java @@ -159,6 +159,7 @@ public String test(RuntimeTestDescriptor descriptor, RuntimeRunner runner, Strin targetName, superClass, null, + null, PredictionMode.LL, true ); diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestActionTemplates.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestActionTemplates.java index 4182b5e531..981b46b4a3 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestActionTemplates.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestActionTemplates.java @@ -23,12 +23,12 @@ public class TestActionTemplates { String actionTemplates = tempDir + FileSeparator + "Java.st"; String grammar = - "lexer grammar L;"+ + "lexer grammar L;" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); - assertInstanceOf(GeneratedState.class, state); + assertInstanceOf(GeneratedState.class, state, state.getErrorMessage()); GeneratedState generated = (GeneratedState) state; @@ -45,12 +45,12 @@ public class TestActionTemplates { String actionTemplates = tempDir + FileSeparator + "Java.stg"; String grammar = - "lexer grammar L;"+ + "lexer grammar L;" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); - assertInstanceOf(GeneratedState.class, state); + assertInstanceOf(GeneratedState.class, state, state.getErrorMessage()); GeneratedState generated = (GeneratedState) state; @@ -69,13 +69,13 @@ public class TestActionTemplates { String grammarFile = tempDir + FileSeparator + "L.g4"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ {<¢>} ;\n"+ + "lexer grammar L;\n" + + "I : '0'..'9'+ {<¢>} ;\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); - assertInstanceOf(GeneratedState.class, state); + assertInstanceOf(GeneratedState.class, state, state.getErrorMessage()); GeneratedState generated = (GeneratedState) state; @@ -95,15 +95,15 @@ public class TestActionTemplates { String grammarFile = tempDir + FileSeparator + "L.g4"; String grammar = - "lexer grammar L;\n"+ + "lexer grammar L;\n" + "I : '0'..'9'+ {\n" + " <¢>\n" + - "};\n"+ + "};\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); - assertInstanceOf(GeneratedState.class, state); + assertInstanceOf(GeneratedState.class, state, state.getErrorMessage()); GeneratedState generated = (GeneratedState) state; @@ -123,8 +123,8 @@ public class TestActionTemplates { String grammarFile = tempDir + FileSeparator + "L.g4"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ {} ;\n"+ + "lexer grammar L;\n" + + "I : '0'..'9'+ {} ;\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); @@ -147,8 +147,8 @@ public class TestActionTemplates { String grammarFile = tempDir + FileSeparator + "L.g4"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ { skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); @@ -163,17 +163,18 @@ public class TestActionTemplates { generated.getErrorMessage()); } - @Test void testInvalidMultilineActionTemplate(@TempDir Path tempDir) { + @Test + void testInvalidMultilineActionTemplate(@TempDir Path tempDir) { writeActionTemplatesFile(tempDir, "writeln(s) ::= <\");>>"); String actionTemplates = tempDir + FileSeparator + "Java.stg"; String grammarFile = tempDir + FileSeparator + "L.g4"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ {\n"+ - " skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); @@ -188,14 +189,15 @@ public class TestActionTemplates { generated.getErrorMessage()); } - @Test void testValidActionTemplate(@TempDir Path tempDir) { + @Test + void testValidActionTemplate(@TempDir Path tempDir) { writeActionTemplatesFile(tempDir, "writeln(s) ::= <\");>>"); String actionTemplates = tempDir + FileSeparator + "Java.stg"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ {} ;\n"+ + "lexer grammar L;\n" + + "I : '0'..'9'+ {} ;\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); @@ -208,21 +210,22 @@ public class TestActionTemplates { "[@1,3:4='34',<1>,1:3]\n" + "[@2,5:4='',<-1>,1:5]\n"; - assertInstanceOf(ExecutedState.class, state); + assertInstanceOf(ExecutedState.class, state, state.getErrorMessage()); assertEquals(expecting, ((ExecutedState) state).output); } - @Test void testValidMultilineActionTemplate(@TempDir Path tempDir) { + @Test + void testValidMultilineActionTemplate(@TempDir Path tempDir) { writeActionTemplatesFile(tempDir, "writeln(s) ::= <\");>>"); String actionTemplates = tempDir + FileSeparator + "Java.stg"; String grammar = - "lexer grammar L;\n"+ - "I : '0'..'9'+ {\n"+ - " \n"+ - "};\n"+ + "lexer grammar L;\n" + + "I : '0'..'9'+ {\n" + + " \n" + + "};\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "34 34", tempDir, actionTemplates); @@ -235,12 +238,13 @@ public class TestActionTemplates { "[@1,3:4='34',<1>,1:3]\n" + "[@2,5:4='',<-1>,1:5]\n"; - assertInstanceOf(ExecutedState.class, state); + assertInstanceOf(ExecutedState.class, state, state.getErrorMessage()); assertEquals(expecting, ((ExecutedState) state).output); } - @Test void testActionTemplateHeader(@TempDir Path tempDir) { + @Test + void testActionTemplateHeader(@TempDir Path tempDir) { String actionTemplates = "normalizerImports() ::= <<\n" + "import java.text.Normalizer;\n" + @@ -255,29 +259,30 @@ public class TestActionTemplates { String actionTemplatesFile = tempDir + FileSeparator + "Java.stg"; String grammar = - "lexer grammar L;\n"+ - "@lexer::header {\n"+ - "\n"+ - "}\n"+ - "ID : (ID_START ID_CONTINUE* | '_' ID_CONTINUE+) { } ;\n"+ - "ID_START : [\\p{XID_Start}] ;\n"+ - "ID_CONTINUE: [\\p{XID_Continue}] ;\n"+ + "lexer grammar L;\n" + + "@lexer::header {\n" + + "\n" + + "}\n" + + "ID : (ID_START ID_CONTINUE* | '_' ID_CONTINUE+) { } ;\n" + + "ID_START : [\\p{XID_Start}] ;\n" + + "ID_CONTINUE: [\\p{XID_Continue}] ;\n" + "WS : (' '|'\\n') -> skip ;"; State state = execLexer(grammar, "This _is \ufb01ne", tempDir, actionTemplatesFile); String expecting = - "[@0,0:3='This',<1>,1:0]\n"+ - "[@1,5:7='_is',<1>,1:5]\n"+ - "[@2,9:11='fine',<1>,1:9]\n"+ + "[@0,0:3='This',<1>,1:0]\n" + + "[@1,5:7='_is',<1>,1:5]\n" + + "[@2,9:11='fine',<1>,1:9]\n" + "[@3,12:11='',<-1>,1:12]\n"; - assertInstanceOf(ExecutedState.class, state); + assertInstanceOf(ExecutedState.class, state, state.getErrorMessage()); assertEquals(expecting, ((ExecutedState) state).output); } - @Test void testActionTemplateSemanticPredicate(@TempDir Path tempDir) { + @Test + void testActionTemplateSemanticPredicate(@TempDir Path tempDir) { String actionTemplates = "pred() ::= <>"; writeActionTemplatesFile(tempDir, actionTemplates); @@ -285,24 +290,24 @@ public class TestActionTemplates { String actionTemplatesFile = tempDir + FileSeparator + "Java.stg"; String grammar = - "grammar P;\n"+ - "file : atom EOF ;\n"+ - "atom : scientific | { }? variable ;\n"+ - "variable: VARIABLE ;\n"+ - "scientific: SCIENTIFIC_NUMBER ;\n"+ + "grammar P;\n" + + "file : atom EOF ;\n" + + "atom : scientific | { }? variable ;\n" + + "variable: VARIABLE ;\n" + + "scientific: SCIENTIFIC_NUMBER ;\n" + "VARIABLE : VALID_ID_START VALID_ID_CHAR* ;\n" + - "SCIENTIFIC_NUMBER : NUMBER (E SIGN? UNSIGNED_INTEGER)? ;\n"+ - "fragment VALID_ID_START : ('a' .. 'z') | ('A' .. 'Z') | '_' ;\n"+ - "fragment VALID_ID_CHAR : VALID_ID_START | ('0' .. '9') ;\n"+ - "fragment NUMBER : ('0' .. '9') + ('.' ('0' .. '9') +)? ;\n"+ - "fragment UNSIGNED_INTEGER : ('0' .. '9')+ ;\n"+ - "fragment E : 'E' | 'e' ;\n"+ - "fragment SIGN : ('+' | '-') ;\n"+ + "SCIENTIFIC_NUMBER : NUMBER (E SIGN? UNSIGNED_INTEGER)? ;\n" + + "fragment VALID_ID_START : ('a' .. 'z') | ('A' .. 'Z') | '_' ;\n" + + "fragment VALID_ID_CHAR : VALID_ID_START | ('0' .. '9') ;\n" + + "fragment NUMBER : ('0' .. '9') + ('.' ('0' .. '9') +)? ;\n" + + "fragment UNSIGNED_INTEGER : ('0' .. '9')+ ;\n" + + "fragment E : 'E' | 'e' ;\n" + + "fragment SIGN : ('+' | '-') ;\n" + "WS : (' '|'\\n') -> skip ;"; State state = execParser(grammar, "Bla", tempDir, "file", actionTemplatesFile); - assertInstanceOf(ExecutedState.class, state); + assertInstanceOf(ExecutedState.class, state, state.getErrorMessage()); ExecutedState executedState = (ExecutedState) state; @@ -311,6 +316,32 @@ public class TestActionTemplates { assertEquals("", executedState.errors); } + @Test + void testValidActionTemplateInLibDir(@TempDir Path tempDir, @TempDir Path libDir) { + writeActionTemplatesFile(libDir, "writeln(s) ::= <\");>>"); + + String actionTemplates = "Java.stg"; + + String grammar = + "lexer grammar L;\n" + + "I : '0'..'9'+ {} ;\n" + + "WS : (' '|'\\n') -> skip ;"; + + State state = execLexer(grammar, "34 34", tempDir, libDir, actionTemplates); + + // Should have identical output to TestLexerActions.testActionExecutedInDFA + String expecting = + "I\n" + + "I\n" + + "[@0,0:1='34',<1>,1:0]\n" + + "[@1,3:4='34',<1>,1:3]\n" + + "[@2,5:4='',<-1>,1:5]\n"; + + assertInstanceOf(ExecutedState.class, state, state.getErrorMessage()); + + assertEquals(expecting, ((ExecutedState) state).output); + } + void writeActionTemplatesFile(Path tempDir, String template) { writeFile(tempDir.toString(), "Java.stg", template); } @@ -318,7 +349,7 @@ void writeActionTemplatesFile(Path tempDir, String template) { State execParser(String grammarStr, String input, Path tempDir, String startRule, String actionTemplates) { RunOptions runOptions = createOptionsForJavaToolTests("P.g4", grammarStr, "PParser", "PLexer", false, true, startRule, input, - false, false, Stage.Execute, actionTemplates); + false, false, Stage.Execute, null, actionTemplates); try (JavaRunner runner = new JavaRunner(tempDir, false)) { return runner.run(runOptions); } @@ -327,7 +358,16 @@ State execParser(String grammarStr, String input, Path tempDir, String startRule State execLexer(String grammarStr, String input, Path tempDir, String actionTemplates) { RunOptions runOptions = createOptionsForJavaToolTests("L.g4", grammarStr, null, "L", false, true, null, input, - false, false, Stage.Execute, actionTemplates); + false, false, Stage.Execute, null, actionTemplates); + try (JavaRunner runner = new JavaRunner(tempDir, false)) { + return runner.run(runOptions); + } + } + + State execLexer(String grammarStr, String input, Path tempDir, Path libDir, String actionTemplates) { + RunOptions runOptions = createOptionsForJavaToolTests("L.g4", grammarStr, null, "L", + false, true, null, input, + false, false, Stage.Execute, libDir.toString(), actionTemplates); try (JavaRunner runner = new JavaRunner(tempDir, false)) { return runner.run(runOptions); } diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestCompositeGrammars.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestCompositeGrammars.java index b97811946e..b9787d300d 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestCompositeGrammars.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestCompositeGrammars.java @@ -727,7 +727,7 @@ private static boolean compile(String grammarFileName, String grammarStr, String ) { RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, grammarStr, parserName, null, false, false, startRuleName, null, - false, false, Stage.Compile, null); + false, false, Stage.Compile, null, null); try (JavaRunner runner = new JavaRunner(tempDirPath, false)) { JavaCompiledState compiledState = (JavaCompiledState) runner.run(runOptions); return !compiledState.containsErrors(); diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestParseTreeMatcher.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestParseTreeMatcher.java index a4d4182edc..680fdbf438 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestParseTreeMatcher.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestParseTreeMatcher.java @@ -392,7 +392,7 @@ private static ParseTreeMatch checkPatternMatch(String grammar, String startRule String lexerName = grammarName+"Lexer"; RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, grammar, parserName, lexerName, false, false, startRule, input, - false, false, Stage.Execute, null); + false, false, Stage.Execute, null, null); try (JavaRunner runner = new JavaRunner()) { JavaExecutedState executedState = (JavaExecutedState)runner.run(runOptions); JavaCompiledState compiledState = (JavaCompiledState)executedState.previousState; @@ -413,7 +413,7 @@ private static ParseTreePatternMatcher getPatternMatcher( ) throws Exception { RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, grammar, parserName, lexerName, false, false, startRule, null, - false, false, Stage.Compile, null); + false, false, Stage.Compile, null, null); try (JavaRunner runner = new JavaRunner()) { JavaCompiledState compiledState = (JavaCompiledState) runner.run(runOptions); diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestParserProfiler.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestParserProfiler.java index fb67dd81af..5f7bc4c82b 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestParserProfiler.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestParserProfiler.java @@ -223,7 +223,7 @@ public class TestParserProfiler { RunOptions runOptions = createOptionsForJavaToolTests("T.g4", grammar, "TParser", "TLexer", false, false, "s", "xyz;abc;z.q", - true, false, Stage.Execute, null); + true, false, Stage.Execute, null, null); try (JavaRunner runner = new JavaRunner()) { ExecutedState state = (ExecutedState) runner.run(runOptions); String expecting = diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestPerformance.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestPerformance.java index 73d95570db..38d0c79d1e 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestPerformance.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestPerformance.java @@ -1103,7 +1103,7 @@ protected JavaCompiledState compileJavaParser(boolean leftRecursive) throws IOEx RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, body, parserName, lexerName, false, true, null, null, - false, false, Stage.Compile, null); + false, false, Stage.Compile, null, null); try (RuntimeRunner runner = new JavaRunner()) { return (JavaCompiledState) runner.run(runOptions); } diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/TestXPath.java b/tool-testsuite/test/org/antlr/v4/test/tool/TestXPath.java index 56091240c7..1dda380583 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/TestXPath.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/TestXPath.java @@ -201,7 +201,7 @@ private Pair> compileAndExtract(String grammarFi ) throws Exception { RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, grammar, parserName, lexerName, false, false, startRuleName, input, - false, false, Stage.Execute, null); + false, false, Stage.Execute, null, null); try (JavaRunner runner = new JavaRunner()) { JavaExecutedState executedState = (JavaExecutedState)runner.run(runOptions); JavaCompiledState compiledState = (JavaCompiledState)executedState.previousState; diff --git a/tool-testsuite/test/org/antlr/v4/test/tool/ToolTestUtils.java b/tool-testsuite/test/org/antlr/v4/test/tool/ToolTestUtils.java index 158cdcffc6..1066a56324 100644 --- a/tool-testsuite/test/org/antlr/v4/test/tool/ToolTestUtils.java +++ b/tool-testsuite/test/org/antlr/v4/test/tool/ToolTestUtils.java @@ -69,7 +69,7 @@ private static ExecutedState execRecognizer(String grammarFileName, String gramm Path workingDir, boolean saveTestDir) { RunOptions runOptions = createOptionsForJavaToolTests(grammarFileName, grammarStr, parserName, lexerName, false, true, startRuleName, input, - false, showDiagnosticErrors, Stage.Execute, null); + false, showDiagnosticErrors, Stage.Execute, null, null); try (JavaRunner runner = new JavaRunner(workingDir, saveTestDir)) { State result = runner.run(runOptions); if (!(result instanceof ExecutedState)) { @@ -83,11 +83,11 @@ public static RunOptions createOptionsForJavaToolTests( String grammarFileName, String grammarStr, String parserName, String lexerName, boolean useListener, boolean useVisitor, String startRuleName, String input, boolean profile, boolean showDiagnosticErrors, - Stage endStage, String actionTemplates + Stage endStage, String libDir, String actionTemplates ) { return new RunOptions(grammarFileName, grammarStr, parserName, lexerName, useListener, useVisitor, startRuleName, input, profile, showDiagnosticErrors, false, false, endStage, "Java", - JavaRunner.runtimeTestParserName, actionTemplates, PredictionMode.LL, true); + JavaRunner.runtimeTestParserName, libDir, actionTemplates, PredictionMode.LL, true); } public static void testErrors(String[] pairs, boolean printTree) { diff --git a/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java b/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java index 68649db70a..25f5a3ce76 100644 --- a/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java +++ b/tool/src/org/antlr/v4/tool/GrammarTransformPipeline.java @@ -770,7 +770,7 @@ public STGroupFile loadActionTemplatesGroupFile(GrammarRootAST root) { } try { - STGroupFile actionTemplates = new STGroupFile(actionTemplatesFile); + STGroupFile actionTemplates = new STGroupFile(actionTemplatesGroupFile.getAbsolutePath()); STErrorListener errorListener = createActionTemplateErrorListener(root, actionTemplates); // Force load the action templates group file