forked from jasder/antlr
prepare release
all tests pass added test for complement set
This commit is contained in:
parent
bfb819e045
commit
0f557737da
|
@ -1,72 +0,0 @@
|
||||||
# Work in progress
|
|
||||||
|
|
||||||
This document is a work in progress, and may or may not resemble the final
|
|
||||||
documentation for creating a new language target (runtime+templates) for ANTLR 4.
|
|
||||||
|
|
||||||
# Creating a runtime port
|
|
||||||
|
|
||||||
## Development directory structure
|
|
||||||
|
|
||||||
The directory structure for developing a new ANTLR 4 target does not have a required
|
|
||||||
form. The following directory structure may be used to provide the same form as the
|
|
||||||
ANTLR 4 reference code base. This form is especially recommended for developers who
|
|
||||||
plan to port both the ANTLR 4 Tool *and* Runtime to a new language.
|
|
||||||
|
|
||||||
/
|
|
||||||
/runtime/[target]/
|
|
||||||
/tool/src/org/antlr/v4/codegen/[target]Target.java
|
|
||||||
/tool/resources/org/antlr/v4/tool/templates/codegen/[target]/[target].stg
|
|
||||||
|
|
||||||
### Tracking progress against the reference repository
|
|
||||||
|
|
||||||
To assist in updating your target as changes are made in the reference (Java) repository,
|
|
||||||
you can include the reference repository as a submodule of the Git repository for your
|
|
||||||
target. The submodule will also allow other users to see which commit your target is
|
|
||||||
synchronized with. I included this submodule at the following location.
|
|
||||||
|
|
||||||
/reference/antlr4
|
|
||||||
|
|
||||||
The following command will add the submodule to your working repository.
|
|
||||||
|
|
||||||
git submodule add -b "master" "git://github.com/antlr/antlr4.git" "reference/antlr4"
|
|
||||||
|
|
||||||
*Note:* the C# target uses a special branch of ANTLR 4 as a reference. The branch "sharpen"
|
|
||||||
is based on the "optimized" branch, but modified to operate as an input to the Sharpen tool
|
|
||||||
for automatically converting Java code to C#. The submodule for this target was added
|
|
||||||
using the following command.
|
|
||||||
|
|
||||||
git submodule add -b "sharpen" "git://github.com/sharwell/antlr4.git" "reference/antlr4"
|
|
||||||
|
|
||||||
## Release structure
|
|
||||||
|
|
||||||
### Code generation support
|
|
||||||
|
|
||||||
The target must provide a `.jar` file for the ANTLR 4 Tool to use for code generation.
|
|
||||||
The key file to include is the following:
|
|
||||||
|
|
||||||
/META-INF/services/org.antlr.v4.codegen.Target
|
|
||||||
|
|
||||||
This file should contain the fully qualified name of the class extending `Target` for
|
|
||||||
your runtime. This will likely look like the following.
|
|
||||||
|
|
||||||
org.antlr.v4.codegen.[target]Target
|
|
||||||
|
|
||||||
If you are providing multiple code generation targets in a single `.jar` file, you
|
|
||||||
should include one line for each target. The C# code generation target provides the
|
|
||||||
following entries.
|
|
||||||
|
|
||||||
org.antlr.v4.codegen.CSharp2Target
|
|
||||||
org.antlr.v4.codegen.CSharp3Target
|
|
||||||
org.antlr.v4.codegen.CSharp4Target
|
|
||||||
|
|
||||||
The code generation templates themselves are loaded by the runtime via the `TODO()`
|
|
||||||
method. The default implementation (inherited from the `Target` superclass) will
|
|
||||||
attempt to load the template from the following path in the `.jar` file.
|
|
||||||
|
|
||||||
/org/antlr/v4/tool/templates/codegen/[target]/[target].stg
|
|
||||||
|
|
||||||
### Runtime
|
|
||||||
|
|
||||||
The runtime for a new target may be distributed in any form relevant to that target
|
|
||||||
language.
|
|
||||||
|
|
|
@ -195,8 +195,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
{
|
{
|
||||||
// allow zero-length tokens
|
// allow zero-length tokens
|
||||||
CaptureSimState(prevAccept, input, ds0);
|
CaptureSimState(prevAccept, input, ds0);
|
||||||
// adjust index since the current input character was not yet consumed
|
|
||||||
prevAccept.index--;
|
|
||||||
}
|
}
|
||||||
int t = input.La(1);
|
int t = input.La(1);
|
||||||
DFAState s = ds0;
|
DFAState s = ds0;
|
||||||
|
@ -230,6 +228,14 @@ namespace Antlr4.Runtime.Atn
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// If this is a consumable input element, make sure to consume before
|
||||||
|
// capturing the accept state so the input index, line, and char
|
||||||
|
// position accurately reflect the state of the interpreter at the
|
||||||
|
// end of the token.
|
||||||
|
if (t != IntStreamConstants.Eof) {
|
||||||
|
Consume(input);
|
||||||
|
}
|
||||||
|
|
||||||
if (target.IsAcceptState)
|
if (target.IsAcceptState)
|
||||||
{
|
{
|
||||||
CaptureSimState(prevAccept, input, target);
|
CaptureSimState(prevAccept, input, target);
|
||||||
|
@ -238,11 +244,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (t != IntStreamConstants.Eof)
|
|
||||||
{
|
|
||||||
Consume(input);
|
|
||||||
t = input.La(1);
|
t = input.La(1);
|
||||||
}
|
|
||||||
s = target;
|
s = target;
|
||||||
}
|
}
|
||||||
// flip; current DFA target becomes new src/from state
|
// flip; current DFA target becomes new src/from state
|
||||||
|
@ -398,10 +400,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
input.Seek(index);
|
input.Seek(index);
|
||||||
this._line = line;
|
this._line = line;
|
||||||
this.charPositionInLine = charPos;
|
this.charPositionInLine = charPos;
|
||||||
if (input.La(1) != IntStreamConstants.Eof)
|
|
||||||
{
|
|
||||||
Consume(input);
|
|
||||||
}
|
|
||||||
if (lexerActionExecutor != null && recog != null)
|
if (lexerActionExecutor != null && recog != null)
|
||||||
{
|
{
|
||||||
lexerActionExecutor.Execute(recog, input, startIndex);
|
lexerActionExecutor.Execute(recog, input, startIndex);
|
||||||
|
|
|
@ -355,14 +355,8 @@ outer_continue: ;
|
||||||
public virtual IToken EmitEOF()
|
public virtual IToken EmitEOF()
|
||||||
{
|
{
|
||||||
int cpos = Column;
|
int cpos = Column;
|
||||||
// The character position for EOF is one beyond the position of
|
int line = Line;
|
||||||
// the previous token's last character
|
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.Eof, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, line, cpos);
|
||||||
if (_token != null)
|
|
||||||
{
|
|
||||||
int n = _token.StopIndex - _token.StartIndex + 1;
|
|
||||||
cpos = _token.Column + n;
|
|
||||||
}
|
|
||||||
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.Eof, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, Line, cpos);
|
|
||||||
Emit(eof);
|
Emit(eof);
|
||||||
return eof;
|
return eof;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
<Properties>
|
<Properties>
|
||||||
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
|
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
|
||||||
<MonoDevelop.Ide.Workbench />
|
<MonoDevelop.Ide.Workbench ActiveDocument="Antlr4.Runtime/Atn/LexerATNSimulator.cs">
|
||||||
|
<Files>
|
||||||
|
<File FileName="Antlr4.Runtime/Lexer.cs" Line="1" Column="1" />
|
||||||
|
<File FileName="Antlr4.Runtime/Atn/LexerATNSimulator.cs" Line="39" Column="39" />
|
||||||
|
</Files>
|
||||||
|
</MonoDevelop.Ide.Workbench>
|
||||||
<MonoDevelop.Ide.DebuggingService.Breakpoints>
|
<MonoDevelop.Ide.DebuggingService.Breakpoints>
|
||||||
<BreakpointStore>
|
<BreakpointStore>
|
||||||
<Breakpoint file="/Users/ericvergnaud/Development/antlr4/antlr/antlr4-csharp/runtime/CSharp/Antlr4.Test.mono/TParser.cs" line="158" column="1" />
|
<Breakpoint file="/Users/ericvergnaud/Development/antlr4/antlr/antlr4-csharp/runtime/CSharp/Antlr4.Test.mono/TParser.cs" line="158" column="1" />
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
package org.antlr.v4.test.rt.csharp;
|
package org.antlr.v4.test.rt.csharp;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -90,7 +91,7 @@ public abstract class BaseTest {
|
||||||
* directories for all tests which completed successfully, and preserving
|
* directories for all tests which completed successfully, and preserving
|
||||||
* the directories for tests which failed.</p>
|
* the directories for tests which failed.</p>
|
||||||
*/
|
*/
|
||||||
public static final boolean PRESERVE_TEST_DIR = Boolean.parseBoolean(System.getProperty("antlr.preserve-csharp-test-dir"));
|
public static final boolean PRESERVE_TEST_DIR = Boolean.parseBoolean(System.getProperty("antlr-preserve-csharp-test-dir"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The base test directory is the directory where generated files get placed
|
* The base test directory is the directory where generated files get placed
|
||||||
|
@ -116,7 +117,7 @@ public abstract class BaseTest {
|
||||||
public static final boolean CREATE_PER_TEST_DIRECTORIES;
|
public static final boolean CREATE_PER_TEST_DIRECTORIES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
String baseTestDir = System.getProperty("antlr.csharp-test-dir");
|
String baseTestDir = System.getProperty("antlr-csharp-test-dir");
|
||||||
boolean perTestDirectories = false;
|
boolean perTestDirectories = false;
|
||||||
if (baseTestDir == null || baseTestDir.isEmpty()) {
|
if (baseTestDir == null || baseTestDir.isEmpty()) {
|
||||||
baseTestDir = System.getProperty("java.io.tmpdir");
|
baseTestDir = System.getProperty("java.io.tmpdir");
|
||||||
|
@ -403,21 +404,41 @@ public abstract class BaseTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private File getProjectFile() {
|
private File getTestProjectFile() {
|
||||||
return new File(tmpdir, "Antlr4.Test.mono.csproj");
|
return new File(tmpdir, "Antlr4.Test.mono.csproj");
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean buildProject() throws Exception {
|
private boolean buildProject() throws Exception {
|
||||||
|
String msbuild = locateMSBuild();
|
||||||
String[] args = {
|
String[] args = {
|
||||||
"xbuild",
|
msbuild,
|
||||||
"/p:Configuration=Release",
|
"/p:Configuration=Release",
|
||||||
getProjectFile().getAbsolutePath()
|
getTestProjectFile().getAbsolutePath()
|
||||||
};
|
};
|
||||||
Process process = Runtime.getRuntime().exec(args, null, new File(tmpdir));
|
Process process = Runtime.getRuntime().exec(args, null, new File(tmpdir));
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
return process.exitValue()==0;
|
return process.exitValue()==0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String locateMSBuild() {
|
||||||
|
return locateTool("xbuild");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locateExec() {
|
||||||
|
return locateTool("mono");
|
||||||
|
// new File(tmpdir, "bin/Release/Test.exe").getAbsolutePath(),
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locateTool(String tool) {
|
||||||
|
String[] roots = { "/usr/bin/", "/usr/local/bin/" };
|
||||||
|
for(String root : roots) {
|
||||||
|
if(new File(root + tool).exists())
|
||||||
|
return root + tool;
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Could not locate " + tool);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean createProject() {
|
public boolean createProject() {
|
||||||
try {
|
try {
|
||||||
String pack = this.getClass().getPackage().getName().replace(".", "/") + "/";
|
String pack = this.getClass().getPackage().getName().replace(".", "/") + "/";
|
||||||
|
@ -433,7 +454,13 @@ public abstract class BaseTest {
|
||||||
input = Thread.currentThread().getContextClassLoader().getResourceAsStream(pack + "Antlr4.Test.mono.csproj");
|
input = Thread.currentThread().getContextClassLoader().getResourceAsStream(pack + "Antlr4.Test.mono.csproj");
|
||||||
Document prjXml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
|
Document prjXml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
|
||||||
// update runtime project reference
|
// update runtime project reference
|
||||||
String runtimePath = System.getProperty("antlr.csharp-runtime-project");
|
String runtimePath = System.getProperty("antlr-csharp-runtime-project");
|
||||||
|
if(runtimePath==null)
|
||||||
|
runtimePath = "../../antlr4-csharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.mono.csproj";
|
||||||
|
File projFile = new File(runtimePath);
|
||||||
|
if(!projFile.exists())
|
||||||
|
throw new RuntimeException("C# runtime project file not found at:" + projFile.getAbsolutePath());
|
||||||
|
runtimePath = projFile.getAbsolutePath();
|
||||||
XPathExpression exp = XPathFactory.newInstance().newXPath().compile("/Project/ItemGroup/ProjectReference[@Include='Antlr4.Runtime.mono.csproj']");
|
XPathExpression exp = XPathFactory.newInstance().newXPath().compile("/Project/ItemGroup/ProjectReference[@Include='Antlr4.Runtime.mono.csproj']");
|
||||||
Element node = (Element)exp.evaluate(prjXml, XPathConstants.NODE);
|
Element node = (Element)exp.evaluate(prjXml, XPathConstants.NODE);
|
||||||
node.setAttribute("Include", runtimePath.replace("/", "\\"));
|
node.setAttribute("Include", runtimePath.replace("/", "\\"));
|
||||||
|
@ -454,7 +481,7 @@ public abstract class BaseTest {
|
||||||
group.appendChild(elem);
|
group.appendChild(elem);
|
||||||
}
|
}
|
||||||
// save project
|
// save project
|
||||||
File prjFile = getProjectFile();
|
File prjFile = getTestProjectFile();
|
||||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||||
transformer.transform(new DOMSource(prjXml), new StreamResult(prjFile));
|
transformer.transform(new DOMSource(prjXml), new StreamResult(prjFile));
|
||||||
|
@ -466,8 +493,9 @@ public abstract class BaseTest {
|
||||||
|
|
||||||
public String execTest() {
|
public String execTest() {
|
||||||
try {
|
try {
|
||||||
|
String exec = locateExec();
|
||||||
String[] args = new String[] {
|
String[] args = new String[] {
|
||||||
"mono",
|
exec,
|
||||||
new File(tmpdir, "bin/Release/Test.exe").getAbsolutePath(),
|
new File(tmpdir, "bin/Release/Test.exe").getAbsolutePath(),
|
||||||
new File(tmpdir, "input").getAbsolutePath()
|
new File(tmpdir, "input").getAbsolutePath()
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,9 @@ public void test<test.name>() throws Exception {
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "<grammar.grammarName>.g4", slave_<grammar.grammarName>);
|
writeFile(tmpdir, "<grammar.grammarName>.g4", slave_<grammar.grammarName>);
|
||||||
};separator="\n", wrap, anchor>
|
};separator="\n", wrap, anchor>
|
||||||
String grammar = <test.grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
|
StringBuilder sb = new StringBuilder();
|
||||||
|
<test.grammar.lines:{ line | sb.append("<line>\\n");};separator="\n", wrap, anchor>
|
||||||
|
String grammar = sb.toString();
|
||||||
<test.afterGrammar>
|
<test.afterGrammar>
|
||||||
String found = execLexer("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName><if(!test.lexerOnly)>Lexer<endif>", "<test.input>", <test.showDFA>);
|
String found = execLexer("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName><if(!test.lexerOnly)>Lexer<endif>", "<test.input>", <test.showDFA>);
|
||||||
assertEquals(<test.outputLines:{ line | "<line>\\n"};separator=" + \n", wrap, anchor>, found);
|
assertEquals(<test.outputLines:{ line | "<line>\\n"};separator=" + \n", wrap, anchor>, found);
|
||||||
|
|
|
@ -12,10 +12,12 @@ public class TestCompositeLexers extends BaseTest {
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "S.g4", slave_S);
|
writeFile(tmpdir, "S.g4", slave_S);
|
||||||
|
|
||||||
String grammar = "lexer grammar M;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"import S;\n" +
|
sb.append("lexer grammar M;\n");
|
||||||
"B : 'b';\n" +
|
sb.append("import S;\n");
|
||||||
"WS : (' '|'\\n') -> skip ;";
|
sb.append("B : 'b';\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("M.g4", grammar, "M", "abc", false);
|
String found = execLexer("M.g4", grammar, "M", "abc", false);
|
||||||
assertEquals("S.A\n" +
|
assertEquals("S.A\n" +
|
||||||
"[@0,0:0='a',<3>,1:0]\n" +
|
"[@0,0:0='a',<3>,1:0]\n" +
|
||||||
|
@ -33,10 +35,12 @@ public class TestCompositeLexers extends BaseTest {
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "S.g4", slave_S);
|
writeFile(tmpdir, "S.g4", slave_S);
|
||||||
|
|
||||||
String grammar = "lexer grammar M;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"import S;\n" +
|
sb.append("lexer grammar M;\n");
|
||||||
"A : 'a' B {Console.WriteLine(\"M.A\");};\n" +
|
sb.append("import S;\n");
|
||||||
"WS : (' '|'\\n') -> skip ;";
|
sb.append("A : 'a' B {Console.WriteLine(\"M.A\");};\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("M.g4", grammar, "M", "ab", false);
|
String found = execLexer("M.g4", grammar, "M", "ab", false);
|
||||||
assertEquals("M.A\n" +
|
assertEquals("M.A\n" +
|
||||||
"[@0,0:1='ab',<1>,1:0]\n" +
|
"[@0,0:1='ab',<1>,1:0]\n" +
|
||||||
|
|
|
@ -6,8 +6,10 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidCharAtStart() throws Exception {
|
public void testInvalidCharAtStart() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'a' 'b' ;";
|
sb.append("lexer grammar L;\n");
|
||||||
|
sb.append("A : 'a' 'b' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "x", false);
|
String found = execLexer("L.g4", grammar, "L", "x", false);
|
||||||
assertEquals("[@0,1:0='<EOF>',<-1>,1:1]\n", found);
|
assertEquals("[@0,1:0='<EOF>',<-1>,1:1]\n", found);
|
||||||
assertEquals("line 1:0 token recognition error at: 'x'\n", this.stderrDuringParse);
|
assertEquals("line 1:0 token recognition error at: 'x'\n", this.stderrDuringParse);
|
||||||
|
@ -15,10 +17,12 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringsEmbeddedInActions_1() throws Exception {
|
public void testStringsEmbeddedInActions_1() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ACTION2 : '[' (STRING | ~'\"')*? ']';\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"STRING : '\"' ('\\\"' | .)*? '\"';\n" +
|
sb.append("ACTION2 : '[' (STRING | ~'\"')*? ']';\n");
|
||||||
"WS : [ \\t\\r\\n]+ -> skip;";
|
sb.append("STRING : '\"' ('\\\"' | .)*? '\"';\n");
|
||||||
|
sb.append("WS : [ \\t\\r\\n]+ -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "[\"foo\"]", false);
|
String found = execLexer("L.g4", grammar, "L", "[\"foo\"]", false);
|
||||||
assertEquals("[@0,0:6='[\"foo\"]',<1>,1:0]\n" +
|
assertEquals("[@0,0:6='[\"foo\"]',<1>,1:0]\n" +
|
||||||
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
|
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
|
||||||
|
@ -27,10 +31,12 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testStringsEmbeddedInActions_2() throws Exception {
|
public void testStringsEmbeddedInActions_2() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ACTION2 : '[' (STRING | ~'\"')*? ']';\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"STRING : '\"' ('\\\"' | .)*? '\"';\n" +
|
sb.append("ACTION2 : '[' (STRING | ~'\"')*? ']';\n");
|
||||||
"WS : [ \\t\\r\\n]+ -> skip;";
|
sb.append("STRING : '\"' ('\\\"' | .)*? '\"';\n");
|
||||||
|
sb.append("WS : [ \\t\\r\\n]+ -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "[\"foo]", false);
|
String found = execLexer("L.g4", grammar, "L", "[\"foo]", false);
|
||||||
assertEquals("[@0,6:5='<EOF>',<-1>,1:6]\n", found);
|
assertEquals("[@0,6:5='<EOF>',<-1>,1:6]\n", found);
|
||||||
assertEquals("line 1:0 token recognition error at: '[\"foo]'\n", this.stderrDuringParse);
|
assertEquals("line 1:0 token recognition error at: '[\"foo]'\n", this.stderrDuringParse);
|
||||||
|
@ -38,9 +44,11 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnforcedGreedyNestedBrances_1() throws Exception {
|
public void testEnforcedGreedyNestedBrances_1() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ACTION : '{' (ACTION | ~[{}])* '}';\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"WS : [ \\r\\n\\t]+ -> skip;";
|
sb.append("ACTION : '{' (ACTION | ~[{}])* '}';\n");
|
||||||
|
sb.append("WS : [ \\r\\n\\t]+ -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "{ { } }", false);
|
String found = execLexer("L.g4", grammar, "L", "{ { } }", false);
|
||||||
assertEquals("[@0,0:6='{ { } }',<1>,1:0]\n" +
|
assertEquals("[@0,0:6='{ { } }',<1>,1:0]\n" +
|
||||||
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
|
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
|
||||||
|
@ -49,9 +57,11 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnforcedGreedyNestedBrances_2() throws Exception {
|
public void testEnforcedGreedyNestedBrances_2() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ACTION : '{' (ACTION | ~[{}])* '}';\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"WS : [ \\r\\n\\t]+ -> skip;";
|
sb.append("ACTION : '{' (ACTION | ~[{}])* '}';\n");
|
||||||
|
sb.append("WS : [ \\r\\n\\t]+ -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "{ { }", false);
|
String found = execLexer("L.g4", grammar, "L", "{ { }", false);
|
||||||
assertEquals("[@0,5:4='<EOF>',<-1>,1:5]\n", found);
|
assertEquals("[@0,5:4='<EOF>',<-1>,1:5]\n", found);
|
||||||
assertEquals("line 1:0 token recognition error at: '{ { }'\n", this.stderrDuringParse);
|
assertEquals("line 1:0 token recognition error at: '{ { }'\n", this.stderrDuringParse);
|
||||||
|
@ -59,8 +69,10 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidCharAtStartAfterDFACache() throws Exception {
|
public void testInvalidCharAtStartAfterDFACache() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'a' 'b' ;";
|
sb.append("lexer grammar L;\n");
|
||||||
|
sb.append("A : 'a' 'b' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "abx", false);
|
String found = execLexer("L.g4", grammar, "L", "abx", false);
|
||||||
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
||||||
"[@1,3:2='<EOF>',<-1>,1:3]\n", found);
|
"[@1,3:2='<EOF>',<-1>,1:3]\n", found);
|
||||||
|
@ -69,8 +81,10 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidCharInToken() throws Exception {
|
public void testInvalidCharInToken() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'a' 'b' ;";
|
sb.append("lexer grammar L;\n");
|
||||||
|
sb.append("A : 'a' 'b' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "ax", false);
|
String found = execLexer("L.g4", grammar, "L", "ax", false);
|
||||||
assertEquals("[@0,2:1='<EOF>',<-1>,1:2]\n", found);
|
assertEquals("[@0,2:1='<EOF>',<-1>,1:2]\n", found);
|
||||||
assertEquals("line 1:0 token recognition error at: 'ax'\n", this.stderrDuringParse);
|
assertEquals("line 1:0 token recognition error at: 'ax'\n", this.stderrDuringParse);
|
||||||
|
@ -78,8 +92,10 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testInvalidCharInTokenAfterDFACache() throws Exception {
|
public void testInvalidCharInTokenAfterDFACache() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'a' 'b' ;";
|
sb.append("lexer grammar L;\n");
|
||||||
|
sb.append("A : 'a' 'b' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "abax", false);
|
String found = execLexer("L.g4", grammar, "L", "abax", false);
|
||||||
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
||||||
"[@1,4:3='<EOF>',<-1>,1:4]\n", found);
|
"[@1,4:3='<EOF>',<-1>,1:4]\n", found);
|
||||||
|
@ -88,9 +104,11 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDFAToATNThatFailsBackToDFA() throws Exception {
|
public void testDFAToATNThatFailsBackToDFA() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'ab' ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"B : 'abc' ;";
|
sb.append("A : 'ab' ;\n");
|
||||||
|
sb.append("B : 'abc' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "ababx", false);
|
String found = execLexer("L.g4", grammar, "L", "ababx", false);
|
||||||
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
||||||
"[@1,2:3='ab',<1>,1:2]\n" +
|
"[@1,2:3='ab',<1>,1:2]\n" +
|
||||||
|
@ -100,10 +118,12 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDFAToATNThatMatchesThenFailsInATN() throws Exception {
|
public void testDFAToATNThatMatchesThenFailsInATN() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'ab' ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"B : 'abc' ;\n" +
|
sb.append("A : 'ab' ;\n");
|
||||||
"C : 'abcd' ;";
|
sb.append("B : 'abc' ;\n");
|
||||||
|
sb.append("C : 'abcd' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "ababcx", false);
|
String found = execLexer("L.g4", grammar, "L", "ababcx", false);
|
||||||
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
assertEquals("[@0,0:1='ab',<1>,1:0]\n" +
|
||||||
"[@1,2:4='abc',<2>,1:2]\n" +
|
"[@1,2:4='abc',<2>,1:2]\n" +
|
||||||
|
@ -113,8 +133,10 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testErrorInMiddle() throws Exception {
|
public void testErrorInMiddle() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"A : 'abc' ;";
|
sb.append("lexer grammar L;\n");
|
||||||
|
sb.append("A : 'abc' ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "abx", false);
|
String found = execLexer("L.g4", grammar, "L", "abx", false);
|
||||||
assertEquals("[@0,3:2='<EOF>',<-1>,1:3]\n", found);
|
assertEquals("[@0,3:2='<EOF>',<-1>,1:3]\n", found);
|
||||||
assertEquals("line 1:0 token recognition error at: 'abx'\n", this.stderrDuringParse);
|
assertEquals("line 1:0 token recognition error at: 'abx'\n", this.stderrDuringParse);
|
||||||
|
@ -122,11 +144,13 @@ public class TestLexerErrors extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLexerExecDFA() throws Exception {
|
public void testLexerExecDFA() throws Exception {
|
||||||
String grammar = "grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"start : ID ':' expr;\n" +
|
sb.append("grammar L;\n");
|
||||||
"expr : primary expr? {} | expr '->' ID;\n" +
|
sb.append("start : ID ':' expr;\n");
|
||||||
"primary : ID;\n" +
|
sb.append("expr : primary expr? {} | expr '->' ID;\n");
|
||||||
"ID : [a-z]+;";
|
sb.append("primary : ID;\n");
|
||||||
|
sb.append("ID : [a-z]+;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "LLexer", "x : x", false);
|
String found = execLexer("L.g4", grammar, "LLexer", "x : x", false);
|
||||||
assertEquals("[@0,0:0='x',<3>,1:0]\n" +
|
assertEquals("[@0,0:0='x',<3>,1:0]\n" +
|
||||||
"[@1,2:2=':',<1>,1:2]\n" +
|
"[@1,2:2=':',<1>,1:2]\n" +
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -415,28 +415,5 @@ public class TestParserExec extends BaseTest {
|
||||||
assertNull(this.stderrDuringParse);
|
assertNull(this.stderrDuringParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAlternateQuotes() throws Exception {
|
|
||||||
String slave_ModeTagsLexer = "lexer grammar ModeTagsLexer;\n" +
|
|
||||||
"// Default mode rules (the SEA)\n" +
|
|
||||||
"OPEN : '«' -> mode(ISLAND) ; // switch to ISLAND mode\n" +
|
|
||||||
"TEXT : ~'«'+ ; // clump all text together\n" +
|
|
||||||
"mode ISLAND;\n" +
|
|
||||||
"CLOSE : '»' -> mode(DEFAULT_MODE) ; // back to SEA mode\n" +
|
|
||||||
"SLASH : '/' ;\n" +
|
|
||||||
"ID : [a-zA-Z]+ ; // match/send ID in tag to parser";
|
|
||||||
rawGenerateRecognizer("ModeTagsLexer.g4", slave_ModeTagsLexer, null, "ModeTagsLexer");
|
|
||||||
|
|
||||||
String grammar = "parser grammar ModeTagsParser;\n" +
|
|
||||||
"options { tokenVocab=ModeTagsLexer; } // use tokens from ModeTagsLexer.g4\n" +
|
|
||||||
"file_: (tag | TEXT)* ;\n" +
|
|
||||||
"tag : '«' ID '»'\n" +
|
|
||||||
" | '«' '/' ID '»'\n" +
|
|
||||||
" ;";
|
|
||||||
String found = execParser("ModeTagsParser.g4", grammar, "ModeTagsParser", "ModeTagsLexer", "file_", "", false);
|
|
||||||
assertEquals("", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -6,11 +6,13 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDisableRule() throws Exception {
|
public void testDisableRule() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"E1 : 'enum' { false }? ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"E2 : 'enum' { true }? ; // winner not E1 or ID\n" +
|
sb.append("E1 : 'enum' { false }? ;\n");
|
||||||
"ID : 'a'..'z'+ ;\n" +
|
sb.append("E2 : 'enum' { true }? ; // winner not E1 or ID\n");
|
||||||
"WS : (' '|'\\n') -> skip;";
|
sb.append("ID : 'a'..'z'+ ;\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "enum abc", true);
|
String found = execLexer("L.g4", grammar, "L", "enum abc", true);
|
||||||
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
||||||
"[@1,5:7='abc',<3>,1:5]\n" +
|
"[@1,5:7='abc',<3>,1:5]\n" +
|
||||||
|
@ -27,10 +29,12 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIDvsEnum() throws Exception {
|
public void testIDvsEnum() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ENUM : 'enum' { false }? ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"ID : 'a'..'z'+ ;\n" +
|
sb.append("ENUM : 'enum' { false }? ;\n");
|
||||||
"WS : (' '|'\\n') -> skip;";
|
sb.append("ID : 'a'..'z'+ ;\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
||||||
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
||||||
"[@1,5:7='abc',<2>,1:5]\n" +
|
"[@1,5:7='abc',<2>,1:5]\n" +
|
||||||
|
@ -48,10 +52,12 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIDnotEnum() throws Exception {
|
public void testIDnotEnum() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ENUM : [a-z]+ { false }? ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"ID : [a-z]+ ;\n" +
|
sb.append("ENUM : [a-z]+ { false }? ;\n");
|
||||||
"WS : (' '|'\\n') -> skip;";
|
sb.append("ID : [a-z]+ ;\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
||||||
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
assertEquals("[@0,0:3='enum',<2>,1:0]\n" +
|
||||||
"[@1,5:7='abc',<2>,1:5]\n" +
|
"[@1,5:7='abc',<2>,1:5]\n" +
|
||||||
|
@ -63,10 +69,12 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEnumNotID() throws Exception {
|
public void testEnumNotID() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ENUM : [a-z]+ { this.Text.Equals(\"enum\") }? ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"ID : [a-z]+ ;\n" +
|
sb.append("ENUM : [a-z]+ { this.Text.Equals(\"enum\") }? ;\n");
|
||||||
"WS : (' '|'\\n') -> skip;";
|
sb.append("ID : [a-z]+ ;\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
String found = execLexer("L.g4", grammar, "L", "enum abc enum", true);
|
||||||
assertEquals("[@0,0:3='enum',<1>,1:0]\n" +
|
assertEquals("[@0,0:3='enum',<1>,1:0]\n" +
|
||||||
"[@1,5:7='abc',<2>,1:5]\n" +
|
"[@1,5:7='abc',<2>,1:5]\n" +
|
||||||
|
@ -78,12 +86,14 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIndent() throws Exception {
|
public void testIndent() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ID : [a-z]+ ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"INDENT : [ \\t]+ { this.TokenStartColumn==0 }?\n" +
|
sb.append("ID : [a-z]+ ;\n");
|
||||||
" { Console.WriteLine(\"INDENT\"); } ;\n" +
|
sb.append("INDENT : [ \\t]+ { this.TokenStartColumn==0 }?\n");
|
||||||
"NL : '\\n';\n" +
|
sb.append(" { Console.WriteLine(\"INDENT\"); } ;\n");
|
||||||
"WS : [ \\t]+ ;";
|
sb.append("NL : '\\n';\n");
|
||||||
|
sb.append("WS : [ \\t]+ ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "abc\n def \n", true);
|
String found = execLexer("L.g4", grammar, "L", "abc\n def \n", true);
|
||||||
assertEquals("INDENT\n" +
|
assertEquals("INDENT\n" +
|
||||||
"[@0,0:2='abc',<1>,1:0]\n" +
|
"[@0,0:2='abc',<1>,1:0]\n" +
|
||||||
|
@ -92,7 +102,7 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
"[@3,6:8='def',<1>,2:2]\n" +
|
"[@3,6:8='def',<1>,2:2]\n" +
|
||||||
"[@4,9:10=' ',<4>,2:5]\n" +
|
"[@4,9:10=' ',<4>,2:5]\n" +
|
||||||
"[@5,11:11='\\n',<3>,2:7]\n" +
|
"[@5,11:11='\\n',<3>,2:7]\n" +
|
||||||
"[@6,12:11='<EOF>',<-1>,3:8]\n" +
|
"[@6,12:11='<EOF>',<-1>,3:0]\n" +
|
||||||
"s0-'\n" +
|
"s0-'\n" +
|
||||||
"'->:s2=>3\n" +
|
"'->:s2=>3\n" +
|
||||||
"s0-'a'->:s1=>1\n" +
|
"s0-'a'->:s1=>1\n" +
|
||||||
|
@ -106,12 +116,14 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLexerInputPositionSensitivePredicates() throws Exception {
|
public void testLexerInputPositionSensitivePredicates() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"WORD1 : ID1+ { Console.WriteLine(this.Text); } ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"WORD2 : ID2+ { Console.WriteLine(this.Text); } ;\n" +
|
sb.append("WORD1 : ID1+ { Console.WriteLine(this.Text); } ;\n");
|
||||||
"fragment ID1 : { this.Column < 2 }? [a-zA-Z];\n" +
|
sb.append("WORD2 : ID2+ { Console.WriteLine(this.Text); } ;\n");
|
||||||
"fragment ID2 : { this.Column >= 2 }? [a-zA-Z];\n" +
|
sb.append("fragment ID1 : { this.Column < 2 }? [a-zA-Z];\n");
|
||||||
"WS : (' '|'\\n') -> skip;";
|
sb.append("fragment ID2 : { this.Column >= 2 }? [a-zA-Z];\n");
|
||||||
|
sb.append("WS : (' '|'\\n') -> skip;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "a cde\nabcde\n", true);
|
String found = execLexer("L.g4", grammar, "L", "a cde\nabcde\n", true);
|
||||||
assertEquals("a\n" +
|
assertEquals("a\n" +
|
||||||
"cde\n" +
|
"cde\n" +
|
||||||
|
@ -127,10 +139,12 @@ public class TestSemPredEvalLexer extends BaseTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPredicatedKeywords() throws Exception {
|
public void testPredicatedKeywords() throws Exception {
|
||||||
String grammar = "lexer grammar L;\n" +
|
StringBuilder sb = new StringBuilder();
|
||||||
"ENUM : [a-z]+ { this.Text.Equals(\"enum\") }? { Console.WriteLine(\"enum!\"); } ;\n" +
|
sb.append("lexer grammar L;\n");
|
||||||
"ID : [a-z]+ { Console.WriteLine(\"ID \" + this.Text); } ;\n" +
|
sb.append("ENUM : [a-z]+ { this.Text.Equals(\"enum\") }? { Console.WriteLine(\"enum!\"); } ;\n");
|
||||||
"WS : [ \\n] -> skip ;";
|
sb.append("ID : [a-z]+ { Console.WriteLine(\"ID \" + this.Text); } ;\n");
|
||||||
|
sb.append("WS : [ \\n] -> skip ;\n");
|
||||||
|
String grammar = sb.toString();
|
||||||
String found = execLexer("L.g4", grammar, "L", "enum enu a", false);
|
String found = execLexer("L.g4", grammar, "L", "enum enu a", false);
|
||||||
assertEquals("enum!\n" +
|
assertEquals("enum!\n" +
|
||||||
"ID enu\n" +
|
"ID enu\n" +
|
||||||
|
|
|
@ -411,7 +411,7 @@ public class TestSemPredEvalParser extends BaseTest {
|
||||||
public void testPredFromAltTestedInLoopBack_1() throws Exception {
|
public void testPredFromAltTestedInLoopBack_1() throws Exception {
|
||||||
String found = testPredFromAltTestedInLoopBack("s\n\n\nx\n");
|
String found = testPredFromAltTestedInLoopBack("s\n\n\nx\n");
|
||||||
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n", found);
|
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n", found);
|
||||||
assertEquals("line 5:2 mismatched input '<EOF>' expecting '\n'\n", this.stderrDuringParse);
|
assertEquals("line 5:0 mismatched input '<EOF>' expecting '\n'\n", this.stderrDuringParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -222,5 +222,15 @@ public class TestSets extends BaseTest {
|
||||||
assertNull(this.stderrDuringParse);
|
assertNull(this.stderrDuringParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testComplementSet() throws Exception {
|
||||||
|
String grammar = "grammar T;\n" +
|
||||||
|
"parse : ~NEW_LINE;\n" +
|
||||||
|
"NEW_LINE: '\\r'? '\\n';";
|
||||||
|
String found = execParser("T.g4", grammar, "TParser", "TLexer", "parse", "a", false);
|
||||||
|
assertEquals("", found);
|
||||||
|
assertEquals("line 1:0 token recognition error at: 'a'\nline 1:1 missing {} at '<EOF>'\n", this.stderrDuringParse);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue