23 import grammar unit tests pass
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8896]
This commit is contained in:
parent
36f3590f6c
commit
40f9e867cd
|
@ -163,6 +163,17 @@ public abstract class BaseTree implements Tree {
|
||||||
return killed;
|
return killed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean deleteChild(Tree t) {
|
||||||
|
for (int i=0; i<children.size(); i++) {
|
||||||
|
Object c = children.get(i);
|
||||||
|
if ( c == t ) {
|
||||||
|
deleteChild(t.getChildIndex());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Delete children from start to stop and replace with t even if t is
|
/** Delete children from start to stop and replace with t even if t is
|
||||||
* a list (nil-root tree). num of children can increase or decrease.
|
* a list (nil-root tree). num of children can increase or decrease.
|
||||||
* For huge child lists, inserting children can force walking rest of
|
* For huge child lists, inserting children can force walking rest of
|
||||||
|
|
|
@ -318,18 +318,10 @@ public class Tool {
|
||||||
/** Try current dir then dir of g then lib dir */
|
/** Try current dir then dir of g then lib dir */
|
||||||
public GrammarRootAST loadImportedGrammar(Grammar g, String fileName) throws IOException {
|
public GrammarRootAST loadImportedGrammar(Grammar g, String fileName) throws IOException {
|
||||||
System.out.println("loadImportedGrammar "+fileName+" from "+g.fileName);
|
System.out.println("loadImportedGrammar "+fileName+" from "+g.fileName);
|
||||||
File importedFile = new File(fileName);
|
File importedFile = getImportedGrammarFile(g, fileName);
|
||||||
if ( !importedFile.exists() ) {
|
if ( importedFile==null ) {
|
||||||
File gfile = new File(g.fileName);
|
errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_FILE, fileName, g.fileName);
|
||||||
String parentDir = gfile.getParent();
|
return null;
|
||||||
importedFile = new File(parentDir, fileName);
|
|
||||||
if ( !importedFile.exists() ) { // try in lib dir
|
|
||||||
importedFile = new File(libDirectory, fileName);
|
|
||||||
if ( !importedFile.exists() ) {
|
|
||||||
errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_FILE, g.fileName, fileName);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ANTLRFileStream in = new ANTLRFileStream(importedFile.getAbsolutePath());
|
ANTLRFileStream in = new ANTLRFileStream(importedFile.getAbsolutePath());
|
||||||
return load(in);
|
return load(in);
|
||||||
|
@ -549,7 +541,11 @@ public class Tool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
elements.removeAll(actionsWeMoved);
|
|
||||||
|
for (GrammarAST r : actionsWeMoved) {
|
||||||
|
combinedAST.deleteChild( r );
|
||||||
|
}
|
||||||
|
|
||||||
GrammarAST combinedRulesRoot =
|
GrammarAST combinedRulesRoot =
|
||||||
(GrammarAST)combinedAST.getFirstChildWithType(ANTLRParser.RULES);
|
(GrammarAST)combinedAST.getFirstChildWithType(ANTLRParser.RULES);
|
||||||
if ( combinedRulesRoot==null ) return lexerAST;
|
if ( combinedRulesRoot==null ) return lexerAST;
|
||||||
|
@ -606,6 +602,7 @@ public class Tool {
|
||||||
lexerRulesRoot.freshenParentAndChildIndexes(); // reset indexes and set litRule parent
|
lexerRulesRoot.freshenParentAndChildIndexes(); // reset indexes and set litRule parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: take out after stable if slow
|
||||||
lexerAST.sanityCheckParentAndChildIndexes();
|
lexerAST.sanityCheckParentAndChildIndexes();
|
||||||
combinedAST.sanityCheckParentAndChildIndexes();
|
combinedAST.sanityCheckParentAndChildIndexes();
|
||||||
// System.out.println(combinedAST.toTokenString());
|
// System.out.println(combinedAST.toTokenString());
|
||||||
|
@ -655,7 +652,7 @@ public class Tool {
|
||||||
*
|
*
|
||||||
* If outputDirectory==null then write a String.
|
* If outputDirectory==null then write a String.
|
||||||
*/
|
*/
|
||||||
public Writer getOutputFile(Grammar g, String fileName) throws IOException {
|
public Writer getOutputFileWriter(Grammar g, String fileName) throws IOException {
|
||||||
if (outputDirectory == null) {
|
if (outputDirectory == null) {
|
||||||
return new StringWriter();
|
return new StringWriter();
|
||||||
}
|
}
|
||||||
|
@ -680,6 +677,22 @@ public class Tool {
|
||||||
return new BufferedWriter(fw);
|
return new BufferedWriter(fw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public File getImportedGrammarFile(Grammar g, String fileName) {
|
||||||
|
File importedFile = new File(fileName);
|
||||||
|
if ( !importedFile.exists() ) {
|
||||||
|
File gfile = new File(g.fileName);
|
||||||
|
String parentDir = gfile.getParent();
|
||||||
|
importedFile = new File(parentDir, fileName);
|
||||||
|
if ( !importedFile.exists() ) { // try in lib dir
|
||||||
|
importedFile = new File(libDirectory, fileName);
|
||||||
|
if ( !importedFile.exists() ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return importedFile;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the location where ANTLR will generate output files for a given
|
* Return the location where ANTLR will generate output files for a given
|
||||||
* file. This is a base directory and output files will be relative to
|
* file. This is a base directory and output files will be relative to
|
||||||
|
@ -744,7 +757,7 @@ public class Tool {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void writeDOTFile(Grammar g, String name, String dot) throws IOException {
|
protected void writeDOTFile(Grammar g, String name, String dot) throws IOException {
|
||||||
Writer fw = getOutputFile(g, name + ".dot");
|
Writer fw = getOutputFileWriter(g, name + ".dot");
|
||||||
fw.write(dot);
|
fw.write(dot);
|
||||||
fw.close();
|
fw.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,7 +193,7 @@ public class CodeGenerator {
|
||||||
|
|
||||||
public void write(ST code, String fileName) throws IOException {
|
public void write(ST code, String fileName) throws IOException {
|
||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
Writer w = g.tool.getOutputFile(g, fileName);
|
Writer w = g.tool.getOutputFileWriter(g, fileName);
|
||||||
STWriter wr = new AutoIndentWriter(w);
|
STWriter wr = new AutoIndentWriter(w);
|
||||||
wr.setLineWidth(lineWidth);
|
wr.setLineWidth(lineWidth);
|
||||||
code.write(wr);
|
code.write(wr);
|
||||||
|
|
|
@ -128,7 +128,7 @@ public enum ErrorType {
|
||||||
//TOKEN_VOCAB_IN_DELEGATE("tokenVocab option ignored in imported grammar <arg>", ErrorSeverity.ERROR),
|
//TOKEN_VOCAB_IN_DELEGATE("tokenVocab option ignored in imported grammar <arg>", ErrorSeverity.ERROR),
|
||||||
OPTIONS_IN_DELEGATE("options ignored in imported grammar <arg>", ErrorSeverity.WARNING),
|
OPTIONS_IN_DELEGATE("options ignored in imported grammar <arg>", ErrorSeverity.WARNING),
|
||||||
// TOKEN_ALIAS_IN_DELEGATE("can't assign string to token name <arg> to string in imported grammar <arg2>", ErrorSeverity.ERROR),
|
// TOKEN_ALIAS_IN_DELEGATE("can't assign string to token name <arg> to string in imported grammar <arg2>", ErrorSeverity.ERROR),
|
||||||
CANNOT_FIND_IMPORTED_FILE("can't find or load grammar <arg>", ErrorSeverity.ERROR),
|
CANNOT_FIND_IMPORTED_FILE("can't find or load grammar <arg> from <arg2>", ErrorSeverity.ERROR),
|
||||||
INVALID_IMPORT("<arg.typeString> grammar <arg.name> cannot import <arg2.typeString> grammar <arg2.name>", ErrorSeverity.ERROR),
|
INVALID_IMPORT("<arg.typeString> grammar <arg.name> cannot import <arg2.typeString> grammar <arg2.name>", ErrorSeverity.ERROR),
|
||||||
IMPORTED_TOKENS_RULE_EMPTY("", ErrorSeverity.ERROR),
|
IMPORTED_TOKENS_RULE_EMPTY("", ErrorSeverity.ERROR),
|
||||||
IMPORT_NAME_CLASH("<arg.typeString> grammar <arg.name> and imported <arg2.typeString> grammar <arg2.name> both generate <arg2.recognizerName>", ErrorSeverity.ERROR),
|
IMPORT_NAME_CLASH("<arg.typeString> grammar <arg.name> and imported <arg2.typeString> grammar <arg2.name> both generate <arg2.recognizerName>", ErrorSeverity.ERROR),
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.antlr.v4.runtime.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.misc.*;
|
import org.antlr.v4.runtime.misc.*;
|
||||||
import org.antlr.v4.semantics.SymbolCollector;
|
import org.antlr.v4.semantics.SymbolCollector;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Grammar implements AttributeResolver {
|
public class Grammar implements AttributeResolver {
|
||||||
|
@ -232,15 +232,18 @@ public class Grammar implements AttributeResolver {
|
||||||
grammarAST = tool.loadImportedGrammar(this, importedGrammarName + ".g");
|
grammarAST = tool.loadImportedGrammar(this, importedGrammarName + ".g");
|
||||||
}
|
}
|
||||||
catch (IOException ioe) {
|
catch (IOException ioe) {
|
||||||
tool.errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_FILE, ioe, fileName);
|
tool.errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_FILE, ioe, importedGrammarName+".g");
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// did it come back as error node or missing?
|
// did it come back as error node or missing?
|
||||||
if ( grammarAST==null || grammarAST instanceof GrammarASTErrorNode ) return;
|
if ( grammarAST==null || grammarAST instanceof GrammarASTErrorNode ) return;
|
||||||
GrammarRootAST ast = (GrammarRootAST)grammarAST;
|
GrammarRootAST ast = (GrammarRootAST)grammarAST;
|
||||||
Grammar g = tool.createGrammar(ast);
|
Grammar g = tool.createGrammar(ast);
|
||||||
g.fileName = importedGrammarName+".g";
|
File f = tool.getImportedGrammarFile(this, importedGrammarName+".g");
|
||||||
|
g.fileName = f.getAbsolutePath();
|
||||||
g.parent = this;
|
g.parent = this;
|
||||||
importedGrammars.add(g);
|
importedGrammars.add(g);
|
||||||
|
g.loadImportedGrammars(); // recursively pursue any imports in this import
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,12 +89,15 @@ public class GrammarAST extends CommonTree {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteChild(GrammarAST t) {
|
public boolean deleteChild(org.antlr.runtime.tree.Tree t) {
|
||||||
List<GrammarAST> dup = new ArrayList<GrammarAST>();
|
for (int i=0; i<children.size(); i++) {
|
||||||
dup.addAll(children);
|
Object c = children.get(i);
|
||||||
for (Object c : dup) {
|
if ( c == t ) {
|
||||||
if ( c == t ) deleteChild(t.getChildIndex());
|
deleteChild(t.getChildIndex());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to basetree when i settle on how runtime works
|
// TODO: move to basetree when i settle on how runtime works
|
||||||
|
|
|
@ -359,7 +359,6 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
assertEquals("JavaDecl: floatx=3;\n", found);
|
assertEquals("JavaDecl: floatx=3;\n", found);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
@Test public void testDelegatorRuleOverridesDelegates() throws Exception {
|
@Test public void testDelegatorRuleOverridesDelegates() throws Exception {
|
||||||
String slave =
|
String slave =
|
||||||
"parser grammar S;\n" +
|
"parser grammar S;\n" +
|
||||||
|
@ -384,7 +383,6 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
assertEquals("M.b\n" +
|
assertEquals("M.b\n" +
|
||||||
"S.a\n", found);
|
"S.a\n", found);
|
||||||
}
|
}
|
||||||
|
|
||||||
// LEXER INHERITANCE
|
// LEXER INHERITANCE
|
||||||
|
|
||||||
@Test public void testLexerDelegatorInvokesDelegateRule() throws Exception {
|
@Test public void testLexerDelegatorInvokesDelegateRule() throws Exception {
|
||||||
|
@ -399,8 +397,14 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
"import S;\n" +
|
"import S;\n" +
|
||||||
"B : 'b' ;\n" +
|
"B : 'b' ;\n" +
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
"WS : (' '|'\\n') {skip();} ;\n" ;
|
||||||
|
String expecting =
|
||||||
|
"S.A\n" +
|
||||||
|
"[@0,0:0='a',<5>,1:0]\n" +
|
||||||
|
"[@1,1:1='b',<3>,1:1]\n" +
|
||||||
|
"[@2,2:2='c',<6>,1:2]\n" +
|
||||||
|
"[@3,3:3='<EOF>',<-1>,1:3]\n";
|
||||||
String found = execLexer("M.g", master, "M", "abc", debug);
|
String found = execLexer("M.g", master, "M", "abc", debug);
|
||||||
assertEquals("S.A\nabc\n", found);
|
assertEquals(expecting, found);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testLexerDelegatorRuleOverridesDelegate() throws Exception {
|
@Test public void testLexerDelegatorRuleOverridesDelegate() throws Exception {
|
||||||
|
@ -416,119 +420,26 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
"A : 'a' B {System.out.println(\"M.A\");} ;\n" +
|
"A : 'a' B {System.out.println(\"M.A\");} ;\n" +
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
"WS : (' '|'\\n') {skip();} ;\n" ;
|
||||||
String found = execLexer("M.g", master, "M", "ab", debug);
|
String found = execLexer("M.g", master, "M", "ab", debug);
|
||||||
assertEquals("S.B\n" +
|
assertEquals("M.A\n" +
|
||||||
"M.A\n" +
|
"[@0,0:1='ab',<3>,1:0]\n" +
|
||||||
"ab\n", found);
|
"[@1,2:2='<EOF>',<-1>,1:2]\n", found);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test public void testLexerDelegatorRuleOverridesDelegateLeavingNoRules() throws Exception {
|
@Test public void testKeywordVSIDOrder() throws Exception {
|
||||||
// M.Tokens has nothing to predict tokens from S. Should
|
// rules in lexer are imported at END so rules in master override
|
||||||
// not include S.Tokens alt in this case?
|
// *and* get priority over imported rules. So importing ID doesn't
|
||||||
|
// mess up keywords in master grammar
|
||||||
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
String slave =
|
String slave =
|
||||||
"lexer grammar S;\n" +
|
"lexer grammar S;\n" +
|
||||||
"A : 'a' {System.out.println(\"S.A\");} ;\n";
|
|
||||||
mkdir(tmpdir);
|
|
||||||
writeFile(tmpdir, "S.g", slave);
|
|
||||||
String master =
|
|
||||||
"lexer grammar M;\n" +
|
|
||||||
"import S;\n" +
|
|
||||||
"A : 'a' {System.out.println(\"M.A\");} ;\n" +
|
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
|
||||||
writeFile(tmpdir, "/M.g", master);
|
|
||||||
|
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
composite.assignTokenTypes();
|
|
||||||
composite.defineGrammarSymbols();
|
|
||||||
composite.createNFAs();
|
|
||||||
g.createLookaheadDFAs(false);
|
|
||||||
|
|
||||||
// predict only alts from M not S
|
|
||||||
String expectingDFA =
|
|
||||||
".s0-'a'->.s1\n" +
|
|
||||||
".s0-{'\\n', ' '}->:s3=>2\n" +
|
|
||||||
".s1-<EOT>->:s2=>1\n";
|
|
||||||
org.antlr.analysis.DFA dfa = g.getLookaheadDFA(1);
|
|
||||||
FASerializer serializer = new FASerializer(g);
|
|
||||||
String result = serializer.serialize(dfa.startState);
|
|
||||||
assertEquals(expectingDFA, result);
|
|
||||||
|
|
||||||
// must not be a "unreachable alt: Tokens" error
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void testInvalidImportMechanism() throws Exception {
|
|
||||||
// M.Tokens has nothing to predict tokens from S. Should
|
|
||||||
// not include S.Tokens alt in this case?
|
|
||||||
String slave =
|
|
||||||
"lexer grammar S;\n" +
|
|
||||||
"A : 'a' {System.out.println(\"S.A\");} ;\n";
|
|
||||||
mkdir(tmpdir);
|
|
||||||
writeFile(tmpdir, "S.g", slave);
|
|
||||||
String master =
|
|
||||||
"tree grammar M;\n" +
|
|
||||||
"import S;\n" +
|
|
||||||
"a : A ;";
|
|
||||||
writeFile(tmpdir, "/M.g", master);
|
|
||||||
|
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 1, equeue.errors.size());
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.warnings.size());
|
|
||||||
|
|
||||||
String expectedError =
|
|
||||||
"error(161): "+tmpdir.toString().replaceFirst("\\-[0-9]+","")+"/M.g:2:8: tree grammar M cannot import lexer grammar S";
|
|
||||||
assertEquals(expectedError, equeue.errors.get(0).toString().replaceFirst("\\-[0-9]+",""));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void testSyntacticPredicateRulesAreNotInherited() throws Exception {
|
|
||||||
// if this compiles, it means that synpred1_S is defined in S.java
|
|
||||||
// but not MParser.java. MParser has its own synpred1_M which must
|
|
||||||
// be separate to compile.
|
|
||||||
String slave =
|
|
||||||
"parser grammar S;\n" +
|
|
||||||
"a : 'a' {System.out.println(\"S.a1\");}\n" +
|
|
||||||
" | 'a' {System.out.println(\"S.a2\");}\n" +
|
|
||||||
" ;\n" +
|
|
||||||
"b : 'x' | 'y' {;} ;\n"; // preds generated but not need in DFA here
|
|
||||||
mkdir(tmpdir);
|
|
||||||
writeFile(tmpdir, "S.g", slave);
|
|
||||||
String master =
|
|
||||||
"grammar M;\n" +
|
|
||||||
"options {backtrack=true;}\n" +
|
|
||||||
"import S;\n" +
|
|
||||||
"start : a b ;\n" +
|
|
||||||
"nonsense : 'q' | 'q' {;} ;" + // forces def of preds here in M
|
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
|
||||||
String found = execParser("M.g", master, "MParser", "MLexer",
|
|
||||||
"start", "ax", debug);
|
|
||||||
assertEquals("S.a1\n", found);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test public void testKeywordVSIDGivesNoWarning() throws Exception {
|
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String slave =
|
|
||||||
"lexer grammar S;\n" +
|
|
||||||
"A : 'abc' {System.out.println(\"S.A\");} ;\n" +
|
|
||||||
"ID : 'a'..'z'+ ;\n";
|
"ID : 'a'..'z'+ ;\n";
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "S.g", slave);
|
writeFile(tmpdir, "S.g", slave);
|
||||||
String master =
|
String master =
|
||||||
"grammar M;\n" +
|
"grammar M;\n" +
|
||||||
"import S;\n" +
|
"import S;\n" +
|
||||||
"a : A {System.out.println(\"M.a\");} ;\n" +
|
"a : A {System.out.println(\"M.a: \"+$A);} ;\n" +
|
||||||
|
"A : 'abc' {System.out.println(\"M.A\");} ;\n" +
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
"WS : (' '|'\\n') {skip();} ;\n" ;
|
||||||
String found = execParser("M.g", master, "MParser", "MLexer",
|
String found = execParser("M.g", master, "MParser", "MLexer",
|
||||||
"a", "abc", debug);
|
"a", "abc", debug);
|
||||||
|
@ -536,46 +447,20 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
||||||
assertEquals("unexpected warnings: "+equeue, 0, equeue.warnings.size());
|
assertEquals("unexpected warnings: "+equeue, 0, equeue.warnings.size());
|
||||||
|
|
||||||
assertEquals("S.A\nM.a\n", found);
|
assertEquals("M.A\n" +
|
||||||
}
|
"M.a: [@0,0:2='abc',<3>,1:0]\n", found);
|
||||||
|
|
||||||
@Test public void testWarningForUndefinedToken() throws Exception {
|
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String slave =
|
|
||||||
"lexer grammar S;\n" +
|
|
||||||
"A : 'abc' {System.out.println(\"S.A\");} ;\n";
|
|
||||||
mkdir(tmpdir);
|
|
||||||
writeFile(tmpdir, "S.g", slave);
|
|
||||||
String master =
|
|
||||||
"grammar M;\n" +
|
|
||||||
"import S;\n" +
|
|
||||||
"a : ABC A {System.out.println(\"M.a\");} ;\n" +
|
|
||||||
"WS : (' '|'\\n') {skip();} ;\n" ;
|
|
||||||
// A is defined in S but M should still see it and not give warning.
|
|
||||||
// only problem is ABC.
|
|
||||||
|
|
||||||
rawGenerateAndBuildRecognizer("M.g", master, "MParser", "MLexer", debug);
|
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
|
||||||
assertEquals("unexpected warnings: "+equeue, 1, equeue.warnings.size());
|
|
||||||
|
|
||||||
String expectedError =
|
|
||||||
"warning(105): "+tmpdir.toString().replaceFirst("\\-[0-9]+","")+ File.separator+"M.g:3:5: no lexer rule corresponding to token: ABC";
|
|
||||||
assertEquals(expectedError, equeue.warnings.get(0).toString().replaceFirst("\\-[0-9]+",""));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that M can import S that imports T.
|
// Make sure that M can import S that imports T.
|
||||||
@Test public void test3LevelImport() throws Exception {
|
@Test public void test3LevelImport() throws Exception {
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String slave =
|
String slave =
|
||||||
"parser grammar T;\n" +
|
"parser grammar T;\n" +
|
||||||
"a : T ;\n" ;
|
"a : T ;\n" ;
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "T.g", slave);
|
writeFile(tmpdir, "T.g", slave);
|
||||||
String slave2 =
|
String slave2 =
|
||||||
"parser grammar S;\n" + // A, B, C token type order
|
"parser grammar S;\n" +
|
||||||
"import T;\n" +
|
"import T;\n" +
|
||||||
"a : S ;\n" ;
|
"a : S ;\n" ;
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
|
@ -586,23 +471,17 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
"import S;\n" +
|
"import S;\n" +
|
||||||
"a : M ;\n" ;
|
"a : M ;\n" ;
|
||||||
writeFile(tmpdir, "M.g", master);
|
writeFile(tmpdir, "M.g", master);
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
Grammar g = new Grammar(tmpdir+"/M.g", master, equeue);
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
g.composite.assignTokenTypes();
|
|
||||||
g.composite.defineGrammarSymbols();
|
|
||||||
|
|
||||||
String expectedTokenIDToTypeMap = "[M=4, S=5, T=6]";
|
String expectedTokenIDToTypeMap = "{EOF=-1, M=3}"; // S and T aren't imported; overridden
|
||||||
String expectedStringLiteralToTypeMap = "{}";
|
String expectedStringLiteralToTypeMap = "{}";
|
||||||
String expectedTypeToTokenList = "[M, S, T]";
|
String expectedTypeToTokenList = "[M]";
|
||||||
|
|
||||||
assertEquals(expectedTokenIDToTypeMap,
|
assertEquals(expectedTokenIDToTypeMap,
|
||||||
realElements(g.composite.tokenIDToTypeMap).toString());
|
g.tokenNameToTypeMap.toString());
|
||||||
assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
|
assertEquals(expectedStringLiteralToTypeMap, g.stringLiteralToTypeMap.toString());
|
||||||
assertEquals(expectedTypeToTokenList,
|
assertEquals(expectedTypeToTokenList,
|
||||||
realElements(g.composite.typeToTokenList).toString());
|
realElements(g.typeToTokenList).toString());
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
||||||
|
|
||||||
|
@ -614,7 +493,6 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
|
|
||||||
@Test public void testBigTreeOfImports() throws Exception {
|
@Test public void testBigTreeOfImports() throws Exception {
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String slave =
|
String slave =
|
||||||
"parser grammar T;\n" +
|
"parser grammar T;\n" +
|
||||||
"x : T ;\n" ;
|
"x : T ;\n" ;
|
||||||
|
@ -649,25 +527,19 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
"import S,A;\n" +
|
"import S,A;\n" +
|
||||||
"a : M ;\n" ;
|
"a : M ;\n" ;
|
||||||
writeFile(tmpdir, "M.g", master);
|
writeFile(tmpdir, "M.g", master);
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
Grammar g = new Grammar(tmpdir+"/M.g", master, equeue);
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
g.composite.assignTokenTypes();
|
|
||||||
g.composite.defineGrammarSymbols();
|
|
||||||
|
|
||||||
String expectedTokenIDToTypeMap = "[A=4, B=5, C=6, M=7, S=8, T=9]";
|
assertEquals(equeue.errors.toString(), "[]");
|
||||||
|
assertEquals(equeue.warnings.toString(), "[]");
|
||||||
|
String expectedTokenIDToTypeMap = "{EOF=-1, M=3, S=4, T=5, A=6, B=7, C=8}";
|
||||||
String expectedStringLiteralToTypeMap = "{}";
|
String expectedStringLiteralToTypeMap = "{}";
|
||||||
String expectedTypeToTokenList = "[A, B, C, M, S, T]";
|
String expectedTypeToTokenList = "[M, S, T, A, B, C]";
|
||||||
|
|
||||||
assertEquals(expectedTokenIDToTypeMap,
|
assertEquals(expectedTokenIDToTypeMap,
|
||||||
realElements(g.composite.tokenIDToTypeMap).toString());
|
g.tokenNameToTypeMap.toString());
|
||||||
assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
|
assertEquals(expectedStringLiteralToTypeMap, g.stringLiteralToTypeMap.toString());
|
||||||
assertEquals(expectedTypeToTokenList,
|
assertEquals(expectedTypeToTokenList,
|
||||||
realElements(g.composite.typeToTokenList).toString());
|
realElements(g.typeToTokenList).toString());
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
|
||||||
|
|
||||||
boolean ok =
|
boolean ok =
|
||||||
rawGenerateAndBuildRecognizer("M.g", master, "MParser", null, false);
|
rawGenerateAndBuildRecognizer("M.g", master, "MParser", null, false);
|
||||||
|
@ -677,7 +549,6 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
|
|
||||||
@Test public void testRulesVisibleThroughMultilevelImport() throws Exception {
|
@Test public void testRulesVisibleThroughMultilevelImport() throws Exception {
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String slave =
|
String slave =
|
||||||
"parser grammar T;\n" +
|
"parser grammar T;\n" +
|
||||||
"x : T ;\n" ;
|
"x : T ;\n" ;
|
||||||
|
@ -695,23 +566,17 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
"import S;\n" +
|
"import S;\n" +
|
||||||
"a : M x ;\n" ; // x MUST BE VISIBLE TO M
|
"a : M x ;\n" ; // x MUST BE VISIBLE TO M
|
||||||
writeFile(tmpdir, "M.g", master);
|
writeFile(tmpdir, "M.g", master);
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
Grammar g = new Grammar(tmpdir+"/M.g", master, equeue);
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/M.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
g.composite.assignTokenTypes();
|
|
||||||
g.composite.defineGrammarSymbols();
|
|
||||||
|
|
||||||
String expectedTokenIDToTypeMap = "[M=4, S=5, T=6]";
|
String expectedTokenIDToTypeMap = "{EOF=-1, M=3, T=4}";
|
||||||
String expectedStringLiteralToTypeMap = "{}";
|
String expectedStringLiteralToTypeMap = "{}";
|
||||||
String expectedTypeToTokenList = "[M, S, T]";
|
String expectedTypeToTokenList = "[M, T]";
|
||||||
|
|
||||||
assertEquals(expectedTokenIDToTypeMap,
|
assertEquals(expectedTokenIDToTypeMap,
|
||||||
realElements(g.composite.tokenIDToTypeMap).toString());
|
g.tokenNameToTypeMap.toString());
|
||||||
assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
|
assertEquals(expectedStringLiteralToTypeMap, g.stringLiteralToTypeMap.toString());
|
||||||
assertEquals(expectedTypeToTokenList,
|
assertEquals(expectedTypeToTokenList,
|
||||||
realElements(g.composite.typeToTokenList).toString());
|
realElements(g.typeToTokenList).toString());
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
||||||
}
|
}
|
||||||
|
@ -719,7 +584,6 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
@Test public void testNestedComposite() throws Exception {
|
@Test public void testNestedComposite() throws Exception {
|
||||||
// Wasn't compiling. http://www.antlr.org/jira/browse/ANTLR-438
|
// Wasn't compiling. http://www.antlr.org/jira/browse/ANTLR-438
|
||||||
ErrorQueue equeue = new ErrorQueue();
|
ErrorQueue equeue = new ErrorQueue();
|
||||||
ErrorManager.setErrorListener(equeue);
|
|
||||||
String gstr =
|
String gstr =
|
||||||
"lexer grammar L;\n" +
|
"lexer grammar L;\n" +
|
||||||
"T1: '1';\n" +
|
"T1: '1';\n" +
|
||||||
|
@ -749,23 +613,17 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
mkdir(tmpdir);
|
mkdir(tmpdir);
|
||||||
writeFile(tmpdir, "G3.g", G3str);
|
writeFile(tmpdir, "G3.g", G3str);
|
||||||
|
|
||||||
Tool antlr = newTool(new String[] {"-lib", tmpdir});
|
Grammar g = new Grammar(tmpdir+"/G3.g", G3str, equeue);
|
||||||
CompositeGrammar composite = new CompositeGrammar();
|
|
||||||
Grammar g = new Grammar(antlr,tmpdir+"/G3.g",composite);
|
|
||||||
composite.setDelegationRoot(g);
|
|
||||||
g.parseAndBuildAST();
|
|
||||||
g.composite.assignTokenTypes();
|
|
||||||
g.composite.defineGrammarSymbols();
|
|
||||||
|
|
||||||
String expectedTokenIDToTypeMap = "[T1=4, T2=5, T3=6, T4=7]";
|
String expectedTokenIDToTypeMap = "{EOF=-1, T4=3, T3=4}";
|
||||||
String expectedStringLiteralToTypeMap = "{}";
|
String expectedStringLiteralToTypeMap = "{}";
|
||||||
String expectedTypeToTokenList = "[T1, T2, T3, T4]";
|
String expectedTypeToTokenList = "[T4, T3]";
|
||||||
|
|
||||||
assertEquals(expectedTokenIDToTypeMap,
|
assertEquals(expectedTokenIDToTypeMap,
|
||||||
realElements(g.composite.tokenIDToTypeMap).toString());
|
g.tokenNameToTypeMap.toString());
|
||||||
assertEquals(expectedStringLiteralToTypeMap, g.composite.stringLiteralToTypeMap.toString());
|
assertEquals(expectedStringLiteralToTypeMap, g.stringLiteralToTypeMap.toString());
|
||||||
assertEquals(expectedTypeToTokenList,
|
assertEquals(expectedTypeToTokenList,
|
||||||
realElements(g.composite.typeToTokenList).toString());
|
realElements(g.typeToTokenList).toString());
|
||||||
|
|
||||||
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
|
||||||
|
|
||||||
|
@ -774,7 +632,7 @@ public class TestCompositeGrammars extends BaseTest {
|
||||||
boolean expecting = true; // should be ok
|
boolean expecting = true; // should be ok
|
||||||
assertEquals(expecting, ok);
|
assertEquals(expecting, ok);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
@Test public void testHeadersPropogatedCorrectlyToImportedGrammars() throws Exception {
|
@Test public void testHeadersPropogatedCorrectlyToImportedGrammars() throws Exception {
|
||||||
String slave =
|
String slave =
|
||||||
"parser grammar S;\n" +
|
"parser grammar S;\n" +
|
||||||
|
|
Loading…
Reference in New Issue