More thorough testing of tool error reporting
This commit is contained in:
parent
cb991ba46d
commit
805430177c
|
@ -405,15 +405,11 @@ public abstract class BaseTest {
|
|||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Return true if all is ok, no errors */
|
||||
protected boolean antlr(String fileName, String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
|
||||
boolean allIsWell = true;
|
||||
protected ErrorQueue antlr(String fileName, String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
|
||||
System.out.println("dir "+tmpdir);
|
||||
mkdir(tmpdir);
|
||||
writeFile(tmpdir, fileName, grammarStr);
|
||||
ErrorQueue equeue = new ErrorQueue();
|
||||
final List<String> options = new ArrayList<String>();
|
||||
Collections.addAll(options, extraOptions);
|
||||
options.add("-o");
|
||||
|
@ -421,23 +417,17 @@ public abstract class BaseTest {
|
|||
options.add("-lib");
|
||||
options.add(tmpdir);
|
||||
options.add(new File(tmpdir,grammarFileName).toString());
|
||||
try {
|
||||
final String[] optionsA = new String[options.size()];
|
||||
options.toArray(optionsA);
|
||||
Tool antlr = newTool(optionsA);
|
||||
antlr.addListener(equeue);
|
||||
if (defaultListener) {
|
||||
antlr.addListener(new DefaultToolListener(antlr));
|
||||
}
|
||||
antlr.processGrammarsOnCommandLine();
|
||||
}
|
||||
catch (Exception e) {
|
||||
allIsWell = false;
|
||||
System.err.println("problems building grammar: "+e);
|
||||
e.printStackTrace(System.err);
|
||||
}
|
||||
|
||||
allIsWell = equeue.errors.isEmpty();
|
||||
final String[] optionsA = new String[options.size()];
|
||||
options.toArray(optionsA);
|
||||
Tool antlr = newTool(optionsA);
|
||||
ErrorQueue equeue = new ErrorQueue(antlr);
|
||||
antlr.addListener(equeue);
|
||||
if (defaultListener) {
|
||||
antlr.addListener(new DefaultToolListener(antlr));
|
||||
}
|
||||
antlr.processGrammarsOnCommandLine();
|
||||
|
||||
if ( !defaultListener && !equeue.errors.isEmpty() ) {
|
||||
System.err.println("antlr reports errors from "+options);
|
||||
for (int i = 0; i < equeue.errors.size(); i++) {
|
||||
|
@ -456,7 +446,7 @@ public abstract class BaseTest {
|
|||
}
|
||||
}
|
||||
|
||||
return allIsWell;
|
||||
return equeue;
|
||||
}
|
||||
|
||||
protected String execLexer(String grammarFileName,
|
||||
|
@ -526,9 +516,9 @@ public abstract class BaseTest {
|
|||
boolean defaultListener,
|
||||
String... extraOptions)
|
||||
{
|
||||
boolean allIsWell =
|
||||
ErrorQueue equeue =
|
||||
antlr(grammarFileName, grammarFileName, grammarStr, defaultListener, extraOptions);
|
||||
if (!allIsWell) {
|
||||
if (!equeue.errors.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -546,7 +536,7 @@ public abstract class BaseTest {
|
|||
files.add(grammarFileName.substring(0, grammarFileName.lastIndexOf('.'))+"BaseVisitor.java");
|
||||
}
|
||||
}
|
||||
allIsWell = compile(files.toArray(new String[files.size()]));
|
||||
boolean allIsWell = compile(files.toArray(new String[files.size()]));
|
||||
return allIsWell;
|
||||
}
|
||||
|
||||
|
@ -670,23 +660,13 @@ public abstract class BaseTest {
|
|||
for (int i = 0; i < pairs.length; i+=2) {
|
||||
String input = pairs[i];
|
||||
String expect = pairs[i+1];
|
||||
ErrorQueue equeue = new ErrorQueue();
|
||||
Grammar g = null;
|
||||
try {
|
||||
String[] lines = input.split("\n");
|
||||
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
|
||||
if (input.startsWith("lexer ")) {
|
||||
g = new LexerGrammar(fileName, input, equeue);
|
||||
} else {
|
||||
g = new Grammar(fileName, input, equeue);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
}
|
||||
catch (org.antlr.runtime.RecognitionException re) {
|
||||
re.printStackTrace(System.err);
|
||||
}
|
||||
String actual = equeue.toString(g != null ? g.tool : new Tool());
|
||||
|
||||
String[] lines = input.split("\n");
|
||||
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
|
||||
ErrorQueue equeue = antlr(fileName, fileName, input, false);
|
||||
|
||||
String actual = equeue.toString(true);
|
||||
actual = actual.replace(tmpdir + File.separator, "");
|
||||
System.err.println(actual);
|
||||
String msg = input;
|
||||
msg = msg.replace("\n","\\n");
|
||||
|
@ -698,14 +678,14 @@ public abstract class BaseTest {
|
|||
}
|
||||
|
||||
public String getFilenameFromFirstLineOfGrammar(String line) {
|
||||
String fileName = "<string>";
|
||||
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
|
||||
int grIndex = line.lastIndexOf("grammar");
|
||||
int semi = line.lastIndexOf(';');
|
||||
if ( grIndex>=0 && semi>=0 ) {
|
||||
int space = line.indexOf(' ', grIndex);
|
||||
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
|
||||
}
|
||||
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "<string>";
|
||||
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
@ -776,7 +756,7 @@ public abstract class BaseTest {
|
|||
st.add(actionName, action);
|
||||
String grammar = st.render();
|
||||
ErrorQueue equeue = new ErrorQueue();
|
||||
Grammar g = new Grammar(grammar);
|
||||
Grammar g = new Grammar(grammar, equeue);
|
||||
if ( g.ast!=null && !g.ast.hasErrors ) {
|
||||
SemanticPipeline sem = new SemanticPipeline(g);
|
||||
sem.process();
|
||||
|
@ -797,7 +777,7 @@ public abstract class BaseTest {
|
|||
assertEquals(expected, snippet);
|
||||
}
|
||||
if ( equeue.size()>0 ) {
|
||||
System.err.println(equeue.toString(g.tool));
|
||||
System.err.println(equeue.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,10 +40,19 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
public class ErrorQueue implements ANTLRToolListener {
|
||||
public List<String> infos = new ArrayList<String>();
|
||||
public List<ANTLRMessage> errors = new ArrayList<ANTLRMessage>();
|
||||
public List<ANTLRMessage> warnings = new ArrayList<ANTLRMessage>();
|
||||
public List<ANTLRMessage> all = new ArrayList<ANTLRMessage>();
|
||||
public final Tool tool;
|
||||
public final List<String> infos = new ArrayList<String>();
|
||||
public final List<ANTLRMessage> errors = new ArrayList<ANTLRMessage>();
|
||||
public final List<ANTLRMessage> warnings = new ArrayList<ANTLRMessage>();
|
||||
public final List<ANTLRMessage> all = new ArrayList<ANTLRMessage>();
|
||||
|
||||
public ErrorQueue() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public ErrorQueue(Tool tool) {
|
||||
this.tool = tool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void info(String msg) {
|
||||
|
@ -64,7 +73,7 @@ public class ErrorQueue implements ANTLRToolListener {
|
|||
|
||||
public void error(ToolMessage msg) {
|
||||
errors.add(msg);
|
||||
all.add(msg);
|
||||
all.add(msg);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
|
@ -72,15 +81,26 @@ public class ErrorQueue implements ANTLRToolListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return Utils.join(all.iterator(), "\n"); }
|
||||
public String toString() {
|
||||
return toString(false);
|
||||
}
|
||||
|
||||
public String toString(boolean rendered) {
|
||||
if (!rendered) {
|
||||
return Utils.join(all.iterator(), "\n");
|
||||
}
|
||||
|
||||
if (tool == null) {
|
||||
throw new IllegalStateException(String.format("No %s instance is available.", Tool.class.getName()));
|
||||
}
|
||||
|
||||
public String toString(Tool tool) {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
for (ANTLRMessage m : all) {
|
||||
ST st = tool.errMgr.getMessageTemplate(m);
|
||||
buf.append(st.render());
|
||||
buf.append("\n");
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
|
|
|
@ -641,9 +641,9 @@ public class TestCompositeGrammars extends BaseTest {
|
|||
"s : a ;\n" +
|
||||
"B : 'b' ;" + // defines B from inherited token space
|
||||
"WS : (' '|'\\n') -> skip ;\n" ;
|
||||
boolean ok = antlr("M.g4", "M.g4", master, false);
|
||||
boolean expecting = true; // should be ok
|
||||
assertEquals(expecting, ok);
|
||||
ErrorQueue equeue = antlr("M.g4", "M.g4", master, false);
|
||||
int expecting = 0; // should be ok
|
||||
assertEquals(expecting, equeue.errors.size());
|
||||
}
|
||||
|
||||
@Test public void testImportedRuleWithAction() throws Exception {
|
||||
|
|
|
@ -42,14 +42,14 @@ public class TestToolSyntaxErrors extends BaseTest {
|
|||
"error(" + ErrorType.NO_RULES.code + "): A.g4::: grammar 'A' has no rules\n",
|
||||
|
||||
"A;",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): <string>:1:0: syntax error: 'A' came as a complete surprise to me\n",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): A.g4:1:0: syntax error: 'A' came as a complete surprise to me\n",
|
||||
|
||||
"grammar ;",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): <string>:1:8: syntax error: ';' came as a complete surprise to me while looking for an identifier\n",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): A.g4:1:8: syntax error: ';' came as a complete surprise to me while looking for an identifier\n",
|
||||
|
||||
"grammar A\n" +
|
||||
"a : ID ;\n",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): <string>:2:0: syntax error: missing SEMI at 'a'\n",
|
||||
"error(" + ErrorType.SYNTAX_ERROR.code + "): A.g4:2:0: syntax error: missing SEMI at 'a'\n",
|
||||
|
||||
"grammar A;\n" +
|
||||
"a : ID ;;\n"+
|
||||
|
|
Loading…
Reference in New Issue