Merge branch 'err-msgs-upgrade'

Conflicts:
	tool/src/org/antlr/v4/tool/ErrorType.java
This commit is contained in:
Terence Parr 2014-06-30 15:59:19 -07:00
commit d85ea0649a
23 changed files with 281 additions and 261 deletions

View File

@ -600,9 +600,10 @@ public class Tool {
/**
* Try current dir then dir of g then lib dir
* @param g
* @param name The imported grammar name.
* @param nameNode The node associated with the imported grammar name.
*/
public Grammar loadImportedGrammar(Grammar g, String name) throws IOException {
public Grammar loadImportedGrammar(Grammar g, GrammarAST nameNode) throws IOException {
String name = nameNode.getText();
g.tool.log("grammar", "load " + name + " from " + g.fileName);
File importedFile = null;
for (String extension : ALL_GRAMMAR_EXTENSIONS) {
@ -613,12 +614,15 @@ public class Tool {
}
if ( importedFile==null ) {
errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_GRAMMAR, name, g.fileName);
errMgr.grammarError(ErrorType.CANNOT_FIND_IMPORTED_GRAMMAR, g.fileName, nameNode.getToken(), name);
return null;
}
ANTLRFileStream in = new ANTLRFileStream(importedFile.getAbsolutePath(), grammarEncoding);
GrammarRootAST root = parse(g.fileName, in);
if ( root==null ) {
return null;
}
Grammar imported = createGrammar(root);
imported.fileName = importedFile.getAbsolutePath();
return imported;

View File

@ -131,7 +131,7 @@ public class LeftRecursiveRuleAnalyzer extends LeftRecursiveRuleWalker {
assoc = ASSOC.left;
}
else {
tool.errMgr.toolError(ErrorType.ILLEGAL_OPTION_VALUE, "assoc", assoc);
tool.errMgr.toolError(ErrorType.ILLEGAL_OPTION_VALUE, t.getOptionAST("assoc").getToken(), "assoc", assoc);
}
}
}

View File

@ -34,6 +34,7 @@ import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.ParserRuleReturnScope;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.v4.Tool;
import org.antlr.v4.misc.OrderedHashMap;
import org.antlr.v4.parse.ANTLRLexer;
@ -177,7 +178,7 @@ public class LeftRecursiveRuleTransformer {
// update Rule to just one alt and add prec alt
ActionAST arg = (ActionAST)r.ast.getFirstChildWithType(ANTLRParser.ARG_ACTION);
if ( arg!=null ) {
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g.tool.errMgr);
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g);
r.args.type = AttributeDict.DictType.ARG;
r.args.ast = arg;
arg.resolver = r.alt[1]; // todo: isn't this Rule or something?
@ -206,15 +207,18 @@ public class LeftRecursiveRuleTransformer {
lexer.tokens = tokens;
ToolANTLRParser p = new ToolANTLRParser(tokens, tool);
p.setTreeAdaptor(adaptor);
Token ruleStart = null;
try {
ParserRuleReturnScope r = p.rule();
RuleAST tree = (RuleAST)r.getTree();
ruleStart = (Token)r.getStart();
GrammarTransformPipeline.setGrammarPtr(g, tree);
GrammarTransformPipeline.augmentTokensWithOriginalPosition(g, tree);
return tree;
}
catch (Exception e) {
tool.errMgr.toolError(ErrorType.INTERNAL_ERROR,
ruleStart,
"error parsing rule created during left-recursion detection: "+ruleText,
e);
}

View File

@ -306,7 +306,7 @@ public class ParserATNFactory implements ATNFactory {
public Handle _ruleRef(@NotNull GrammarAST node) {
Rule r = g.getRule(node.getText());
if ( r==null ) {
g.tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, "Rule "+node.getText()+" undefined");
g.tool.errMgr.grammarError(ErrorType.INTERNAL_ERROR, g.fileName, node.getToken(), "Rule "+node.getText()+" undefined");
return null;
}
RuleStartState start = atn.ruleToStartState[r.index];

View File

@ -235,7 +235,8 @@ public class RuleFunction extends OutputModelObject {
}
return visitor.frequencies.peek();
} catch (RecognitionException ex) {
}
catch (RecognitionException ex) {
factory.getGrammar().tool.errMgr.toolError(ErrorType.INTERNAL_ERROR, ex);
return new FrequencySet<String>();
}

View File

@ -39,6 +39,7 @@ import org.antlr.v4.tool.Attribute;
import org.antlr.v4.tool.AttributeDict;
import org.antlr.v4.tool.ErrorManager;
import org.antlr.v4.tool.ErrorType;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.ast.ActionAST;
import java.util.ArrayList;
@ -62,17 +63,17 @@ public class ScopeParser {
*
* convert to an attribute scope.
*/
public static AttributeDict parseTypedArgList(@Nullable ActionAST action, String s, ErrorManager errMgr) {
return parse(action, s, ',', errMgr);
public static AttributeDict parseTypedArgList(@Nullable ActionAST action, String s, Grammar g) {
return parse(action, s, ',', g);
}
public static AttributeDict parse(@Nullable ActionAST action, String s, char separator, ErrorManager errMgr) {
public static AttributeDict parse(@Nullable ActionAST action, String s, char separator, Grammar g) {
AttributeDict dict = new AttributeDict();
List<Pair<String, Integer>> decls = splitDecls(s, separator);
for (Pair<String, Integer> decl : decls) {
// System.out.println("decl="+decl);
if ( decl.a.trim().length()>0 ) {
Attribute a = parseAttributeDef(action, decl, errMgr);
Attribute a = parseAttributeDef(action, decl, g);
dict.add(a);
}
}
@ -84,7 +85,7 @@ public class ScopeParser {
* but if the separator is ',' you cannot use ',' in the initvalue
* unless you escape use "\," escape.
*/
public static Attribute parseAttributeDef(@Nullable ActionAST action, @NotNull Pair<String, Integer> decl, ErrorManager errMgr) {
public static Attribute parseAttributeDef(@Nullable ActionAST action, @NotNull Pair<String, Integer> decl, Grammar g) {
if ( decl.a==null ) return null;
Attribute attr = new Attribute();
boolean inID = false;
@ -113,7 +114,7 @@ public class ScopeParser {
start = 0;
}
if ( start<0 ) {
errMgr.toolError(ErrorType.CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL,decl);
g.tool.errMgr.grammarError(ErrorType.CANNOT_FIND_ATTRIBUTE_NAME_IN_DECL, g.fileName, action.token, decl);
}
// walk forwards looking for end of an ID
int stop=-1;

View File

@ -34,6 +34,8 @@ import org.antlr.runtime.Token;
import org.antlr.v4.Tool;
import org.antlr.v4.codegen.CodeGenerator;
import org.antlr.v4.tool.ErrorType;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.ast.GrammarAST;
import java.io.BufferedReader;
import java.io.File;
@ -48,12 +50,10 @@ import java.util.regex.Pattern;
/** */
public class TokenVocabParser {
protected final Tool tool;
protected final String vocabName;
protected final Grammar g;
public TokenVocabParser(Tool tool, String vocabName) {
this.tool = tool;
this.vocabName = vocabName;
public TokenVocabParser(Grammar g) {
this.g = g;
}
/** Load a vocab file {@code <vocabName>.tokens} and return mapping. */
@ -63,6 +63,8 @@ public class TokenVocabParser {
File fullFile = getImportedVocabFile();
FileInputStream fis = null;
BufferedReader br = null;
Tool tool = g.tool;
String vocabName = g.getOptionString("tokenVocab");
try {
Pattern tokenDefPattern = Pattern.compile("([^\n]+?)[ \\t]*?=[ \\t]*?([0-9]+)");
fis = new FileInputStream(fullFile);
@ -102,7 +104,7 @@ public class TokenVocabParser {
if ( tokenDef.length()>0 ) { // ignore blank lines
tool.errMgr.toolError(ErrorType.TOKENS_FILE_SYNTAX_ERROR,
vocabName + CodeGenerator.VOCAB_FILE_EXTENSION,
" bad token def: "+tokenDef,
" bad token def: " + tokenDef,
lineNum);
}
}
@ -110,13 +112,25 @@ public class TokenVocabParser {
}
}
catch (FileNotFoundException fnfe) {
tool.errMgr.toolError(ErrorType.CANNOT_FIND_TOKENS_FILE,
fullFile);
GrammarAST inTree = g.ast.getOptionAST("tokenVocab");
String inTreeValue = inTree.getToken().getText();
if ( vocabName.equals(inTreeValue) ) {
tool.errMgr.grammarError(ErrorType.CANNOT_FIND_TOKENS_FILE_REFD_IN_GRAMMAR,
g.fileName,
inTree.getToken(),
fullFile);
}
else { // must be from -D option on cmd-line not token in tree
tool.errMgr.toolError(ErrorType.CANNOT_FIND_TOKENS_FILE_GIVEN_ON_CMDLINE,
fullFile,
g.name);
}
}
catch (Exception e) {
tool.errMgr.toolError(ErrorType.ERROR_READING_TOKENS_FILE,
e,
fullFile,
e);
e.getMessage());
}
finally {
try {
@ -124,8 +138,9 @@ public class TokenVocabParser {
}
catch (IOException ioe) {
tool.errMgr.toolError(ErrorType.ERROR_READING_TOKENS_FILE,
ioe,
fullFile,
ioe);
ioe.getMessage());
}
}
return tokens;
@ -141,8 +156,8 @@ public class TokenVocabParser {
* was no output directory specified.
*/
public File getImportedVocabFile() {
File f = new File(tool.libDirectory,
String vocabName = g.getOptionString("tokenVocab");
File f = new File(g.tool.libDirectory,
File.separator +
vocabName +
CodeGenerator.VOCAB_FILE_EXTENSION);
@ -154,7 +169,7 @@ public class TokenVocabParser {
// to look for it in the output directory which is where .tokens
// files are generated (in the base, not relative to the input
// location.)
f = new File(tool.outputDirectory, vocabName + CodeGenerator.VOCAB_FILE_EXTENSION);
f = new File(g.tool.outputDirectory, vocabName + CodeGenerator.VOCAB_FILE_EXTENSION);
return f;
}
}

View File

@ -81,20 +81,20 @@ public class RuleCollector extends GrammarTreeVisitor {
rules.put(r.name, r);
if ( arg!=null ) {
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g.tool.errMgr);
r.args = ScopeParser.parseTypedArgList(arg, arg.getText(), g);
r.args.type = AttributeDict.DictType.ARG;
r.args.ast = arg;
arg.resolver = r.alt[currentOuterAltNumber];
}
if ( returns!=null ) {
r.retvals = ScopeParser.parseTypedArgList(returns, returns.getText(), g.tool.errMgr);
r.retvals = ScopeParser.parseTypedArgList(returns, returns.getText(), g);
r.retvals.type = AttributeDict.DictType.RET;
r.retvals.ast = returns;
}
if ( locals!=null ) {
r.locals = ScopeParser.parseTypedArgList(locals, locals.getText(), g.tool.errMgr);
r.locals = ScopeParser.parseTypedArgList(locals, locals.getText(), g);
r.locals.type = AttributeDict.DictType.LOCAL;
r.locals.ast = locals;
}

View File

@ -30,6 +30,7 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.misc.Nullable;
import org.stringtemplate.v4.ST;
@ -50,18 +51,25 @@ public class ANTLRMessage {
public int line = -1;
public int charPosition = -1;
public ANTLRMessage(@NotNull ErrorType errorType) {
this(errorType, (Throwable)null);
public Grammar g;
/** Most of the time, we'll have a token such as an undefined rule ref
* and so this will be set.
*/
public Token offendingToken;
public ANTLRMessage(@NotNull ErrorType errorType) {
this(errorType, (Throwable)null, Token.INVALID_TOKEN);
}
public ANTLRMessage(@NotNull ErrorType errorType, Object... args) {
this(errorType, null, args);
}
public ANTLRMessage(@NotNull ErrorType errorType, Token offendingToken, Object... args) {
this(errorType, null, offendingToken, args);
}
public ANTLRMessage(@NotNull ErrorType errorType, @Nullable Throwable e, Object... args) {
public ANTLRMessage(@NotNull ErrorType errorType, @Nullable Throwable e, Token offendingToken, Object... args) {
this.errorType = errorType;
this.e = e;
this.args = args;
this.offendingToken = offendingToken;
}
@NotNull
@ -80,6 +88,7 @@ public class ANTLRMessage {
public ST getMessageTemplate(boolean verbose) {
ST messageST = new ST(getErrorType().msg);
messageST.impl.name = errorType.name();
messageST.add("verbose", verbose);
Object[] args = getArgs();

View File

@ -30,14 +30,14 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
import org.antlr.v4.Tool;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STErrorListener;
import org.stringtemplate.v4.STGroup;
import org.stringtemplate.v4.STGroupFile;
import org.stringtemplate.v4.misc.ErrorBuffer;
import org.stringtemplate.v4.misc.STMessage;
import java.io.File;
import java.net.URL;
import java.util.Collection;
import java.util.EnumSet;
@ -63,29 +63,6 @@ public class ErrorManager {
ErrorBuffer initSTListener = new ErrorBuffer();
STErrorListener theDefaultSTListener =
new STErrorListener() {
@Override
public void compileTimeError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
@Override
public void runTimeError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
@Override
public void IOError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
@Override
public void internalError(STMessage msg) {
ErrorManager.internalError(msg.toString());
}
};
public ErrorManager(Tool tool) {
this.tool = tool;
}
@ -111,7 +88,13 @@ public class ErrorManager {
locationValid = true;
}
if (msg.fileName != null) {
locationST.add("file", msg.fileName);
File f = new File(msg.fileName);
// Don't show path to file in messages; too long.
String displayFileName = msg.fileName;
if ( f.exists() ) {
displayFileName = f.getName();
}
locationST.add("file", displayFileName);
locationValid = true;
}
@ -181,12 +164,15 @@ public class ErrorManager {
* @param args The arguments to pass to the StringTemplate
*/
public void toolError(ErrorType errorType, Object... args) {
ToolMessage msg = new ToolMessage(errorType, args);
emit(errorType, msg);
toolError(errorType, null, Token.INVALID_TOKEN, args);
}
public void toolError(ErrorType errorType, Throwable e, Object... args) {
ToolMessage msg = new ToolMessage(errorType, e, args);
public void toolError(ErrorType errorType, Token offendingToken, Object... args) {
toolError(errorType, null, offendingToken, args);
}
public void toolError(ErrorType errorType, Throwable e, Token offendingToken, Object... args) {
ToolMessage msg = new ToolMessage(errorType, e, offendingToken, args);
emit(errorType, msg);
}

View File

@ -147,7 +147,7 @@ public enum ErrorType {
* ANTLR cannot generate '<em>language</em>' code as of version
* <em>version</em></p>
*/
CANNOT_CREATE_TARGET_GENERATOR(31, "ANTLR cannot generate '<arg>' code as of version "+ Tool.VERSION, ErrorSeverity.ERROR_ONE_OFF),
CANNOT_CREATE_TARGET_GENERATOR(31, "ANTLR cannot generate <arg> code as of version "+ Tool.VERSION, ErrorSeverity.ERROR),
/**
* Compiler Error 32.
*

View File

@ -30,6 +30,7 @@
package org.antlr.v4.tool;
import org.antlr.runtime.tree.Tree;
import org.antlr.v4.Tool;
import org.antlr.v4.analysis.LeftRecursiveRuleTransformer;
import org.antlr.v4.misc.CharSupport;
@ -355,7 +356,8 @@ public class Grammar implements AttributeResolver {
GrammarAST t = (GrammarAST)c;
String importedGrammarName = null;
if ( t.getType()==ANTLRParser.ASSIGN ) {
importedGrammarName = t.getChild(1).getText();
t = (GrammarAST)t.getChild(1);
importedGrammarName = t.getText();
tool.log("grammar", "import "+ importedGrammarName);
}
else if ( t.getType()==ANTLRParser.ID ) {
@ -364,11 +366,14 @@ public class Grammar implements AttributeResolver {
}
Grammar g;
try {
g = tool.loadImportedGrammar(this, importedGrammarName);
g = tool.loadImportedGrammar(this, t);
}
catch (IOException ioe) {
tool.errMgr.toolError(ErrorType.CANNOT_FIND_IMPORTED_GRAMMAR, ioe,
importedGrammarName);
tool.errMgr.grammarError(ErrorType.ERROR_READING_IMPORTED_GRAMMAR,
importedGrammarName,
t.getToken(),
importedGrammarName,
name);
continue;
}
// did it come back as error node or missing?
@ -811,7 +816,7 @@ public class Grammar implements AttributeResolver {
public void importTokensFromTokensFile() {
String vocab = getOptionString("tokenVocab");
if ( vocab!=null ) {
TokenVocabParser vparser = new TokenVocabParser(tool, vocab);
TokenVocabParser vparser = new TokenVocabParser(this);
Map<String,Integer> tokens = vparser.load();
tool.log("grammar", "tokens=" + tokens);
for (String t : tokens.keySet()) {

View File

@ -33,40 +33,17 @@ package org.antlr.v4.tool;
import org.antlr.runtime.Token;
/** A problem with the symbols and/or meaning of a grammar such as rule
* redefinition.
* redefinition. Any msg where we can point to a location in the grammar.
*/
public class GrammarSemanticsMessage extends ANTLRMessage {
public Grammar g;
/** Most of the time, we'll have a token such as an undefined rule ref
* and so this will be set.
*/
public Token offendingToken;
/*
public GrammarSemanticsMessage(ErrorType etype,
Grammar g,
Token offendingToken,
Object... args)
{
super(etype,args);
this.g = g;
if ( g!=null ) fileName = g.fileName;
this.offendingToken = offendingToken;
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}
}
*/
public GrammarSemanticsMessage(ErrorType etype,
String fileName,
Token offendingToken,
Object... args)
{
super(etype,args);
super(etype,offendingToken,args);
this.fileName = fileName;
this.offendingToken = offendingToken;
if ( offendingToken!=null ) {
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}

View File

@ -37,17 +37,13 @@ import org.antlr.runtime.Token;
* "The '{' came as a complete surprise to me at this point in your program"
*/
public class GrammarSyntaxMessage extends ANTLRMessage {
public Grammar g;
/** Most of the time, we'll have a token and so this will be set. */
public Token offendingToken;
public GrammarSyntaxMessage(ErrorType etype,
String fileName,
Token offendingToken,
RecognitionException antlrException,
Object... args)
{
super(etype, antlrException, args);
super(etype, antlrException, offendingToken, args);
this.fileName = fileName;
this.offendingToken = offendingToken;
if ( offendingToken!=null ) {

View File

@ -30,14 +30,32 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
import java.util.Collection;
public class LeftRecursionCyclesMessage extends ANTLRMessage {
public Collection<? extends Collection<Rule>> cycles;
public LeftRecursionCyclesMessage(String fileName, Collection<? extends Collection<Rule>> cycles) {
super(ErrorType.LEFT_RECURSION_CYCLES, cycles);
this.cycles = cycles;
super(ErrorType.LEFT_RECURSION_CYCLES, getStartTokenOfFirstRule(cycles), cycles);
this.fileName = fileName;
}
protected static Token getStartTokenOfFirstRule(Collection<? extends Collection<Rule>> cycles) {
if (cycles == null) {
return null;
}
for (Collection<Rule> collection : cycles) {
if (collection == null) {
return null;
}
for (Rule rule : collection) {
if (rule.ast != null) {
return rule.ast.getToken();
}
}
}
return null;
}
}

View File

@ -30,6 +30,8 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
/** A generic message from the tool such as "file not found" type errors; there
* is no reason to create a special object for each error unlike the grammar
* errors, which may be rather complex.
@ -43,9 +45,9 @@ public class ToolMessage extends ANTLRMessage {
super(errorType);
}
public ToolMessage(ErrorType errorType, Object... args) {
super(errorType, null, args);
super(errorType, null, Token.INVALID_TOKEN, args);
}
public ToolMessage(ErrorType errorType, Throwable e, Object... args) {
super(errorType, e, args);
super(errorType, e, Token.INVALID_TOKEN, args);
}
}

View File

@ -16,7 +16,7 @@
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
@ -55,8 +55,8 @@ public class TestAttributeChecks extends BaseTest {
"c : ;\n";
String[] membersChecks = {
"$a", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference 'a' in '$a'\n",
"$a.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference 'a' in '$a.y'\n",
"$a", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference a in $a\n",
"$a.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference a in $a.y\n",
};
String[] initChecks = {
@ -68,8 +68,8 @@ public class TestAttributeChecks extends BaseTest {
"$ids", "",
"$labs", "",
"$c", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference 'c' in '$c'\n",
"$a.q", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:10: unknown attribute 'q' for rule 'a' in '$a.q'\n",
"$c", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference c in $c\n",
"$a.q", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:10: unknown attribute q for rule a in $a.q\n",
};
String[] inlineChecks = {
@ -92,21 +92,21 @@ public class TestAttributeChecks extends BaseTest {
};
String[] bad_inlineChecks = {
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference 'lab' in '$lab'\n",
"$q", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q'\n",
"$q.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q.y'\n",
"$q = 3", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q'\n",
"$q = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q = 3;'\n",
"$q.y = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q.y'\n",
"$q = $blort;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'q' in '$q = $blort;'\n" +
"error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:9: unknown attribute reference 'blort' in '$blort'\n",
"$a.ick", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:6: unknown attribute 'ick' for rule 'a' in '$a.ick'\n",
"$a.ick = 3;", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:6: unknown attribute 'ick' for rule 'a' in '$a.ick'\n",
"$b.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:7:6: parameter 'd' of rule 'b' is not accessible in this scope: $b.d\n", // can't see rule ref's arg
"$d.text", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'd' in '$d.text'\n", // valid rule, but no ref
"$lab.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:7:8: parameter 'd' of rule 'b' is not accessible in this scope: $lab.d\n",
"$ids = null;", "error(" + ErrorType.ASSIGNMENT_TO_LIST_LABEL.code + "): A.g4:7:4: cannot assign a value to list label 'ids'\n",
"$labs = null;","error(" + ErrorType.ASSIGNMENT_TO_LIST_LABEL.code + "): A.g4:7:4: cannot assign a value to list label 'labs'\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference lab in $lab\n",
"$q", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q\n",
"$q.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q.y\n",
"$q = 3", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q\n",
"$q = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q = 3;\n",
"$q.y = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q.y\n",
"$q = $blort;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference q in $q = $blort;\n" +
"error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:9: unknown attribute reference blort in $blort\n",
"$a.ick", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:6: unknown attribute ick for rule a in $a.ick\n",
"$a.ick = 3;", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:6: unknown attribute ick for rule a in $a.ick\n",
"$b.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:7:6: parameter d of rule b is not accessible in this scope: $b.d\n", // cant see rule refs arg
"$d.text", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference d in $d.text\n", // valid rule, but no ref
"$lab.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:7:8: parameter d of rule b is not accessible in this scope: $lab.d\n",
"$ids = null;", "error(" + ErrorType.ASSIGNMENT_TO_LIST_LABEL.code + "): A.g4:7:4: cannot assign a value to list label ids\n",
"$labs = null;","error(" + ErrorType.ASSIGNMENT_TO_LIST_LABEL.code + "): A.g4:7:4: cannot assign a value to list label labs\n",
};
String[] finallyChecks = {
@ -121,97 +121,97 @@ public class TestAttributeChecks extends BaseTest {
"$ids", "",
"$labs", "",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference 'lab' in '$lab'\n",
"$q", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q'\n",
"$q.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q.y'\n",
"$q = 3", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q'\n",
"$q = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q = 3;'\n",
"$q.y = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q.y'\n",
"$q = $blort;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'q' in '$q = $blort;'\n" +
"error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:19: unknown attribute reference 'blort' in '$blort'\n",
"$a.ick", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:16: unknown attribute 'ick' for rule 'a' in '$a.ick'\n",
"$a.ick = 3;", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:16: unknown attribute 'ick' for rule 'a' in '$a.ick'\n",
"$b.e", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'b' in '$b.e'\n", // can't see rule refs outside alts
"$b.d", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'b' in '$b.d'\n",
"$c.text", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'c' in '$c.text'\n",
"$lab.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:10:18: parameter 'd' of rule 'b' is not accessible in this scope: $lab.d\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference lab in $lab\n",
"$q", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q\n",
"$q.y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q.y\n",
"$q = 3", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q\n",
"$q = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q = 3;\n",
"$q.y = 3;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q.y\n",
"$q = $blort;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference q in $q = $blort;\n" +
"error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:19: unknown attribute reference blort in $blort\n",
"$a.ick", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:16: unknown attribute ick for rule a in $a.ick\n",
"$a.ick = 3;", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:16: unknown attribute ick for rule a in $a.ick\n",
"$b.e", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference b in $b.e\n", // cant see rule refs outside alts
"$b.d", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference b in $b.d\n",
"$c.text", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference c in $c.text\n",
"$lab.d", "error(" + ErrorType.INVALID_RULE_PARAMETER_REF.code + "): A.g4:10:18: parameter d of rule b is not accessible in this scope: $lab.d\n",
};
String[] dynMembersChecks = {
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference 'S' in '$S'\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule 'S' in non-local ref '$S::i'\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:17: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:2:11: unknown attribute reference S in $S\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule S in non-local ref $S::i\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule S in non-local ref $S::i\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:17: reference to undefined rule S in non-local ref $S::i\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:2:14: unknown attribute 'f' for rule 'b' in '$b::f'\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule 'S' in non-local ref '$S::j'\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule 'S' in non-local ref '$S::j = 3;'\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule 'S' in non-local ref '$S::j = $S::k;'\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:2:14: unknown attribute f for rule b in $b::f\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule S in non-local ref $S::j\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule S in non-local ref $S::j = 3;\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:2:11: reference to undefined rule S in non-local ref $S::j = $S::k;\n",
};
String[] dynInitChecks = {
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:5:8: missing attribute access on rule reference 'a' in '$a'\n",
"$b", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference 'b' in '$b'\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:5:8: missing attribute access on rule reference 'lab' in '$lab'\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:11: unknown attribute 'f' for rule 'b' in '$b::f'\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule 'S' in non-local ref '$S::i'\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:14: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:11: unknown attribute 'z' for rule 'a' in '$a::z'\n",
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference 'S' in '$S'\n",
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:5:8: missing attribute access on rule reference a in $a\n",
"$b", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference b in $b\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:5:8: missing attribute access on rule reference lab in $lab\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:11: unknown attribute f for rule b in $b::f\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule S in non-local ref $S::i\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule S in non-local ref $S::i\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:14: reference to undefined rule S in non-local ref $S::i\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:5:11: unknown attribute z for rule a in $a::z\n",
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:5:8: unknown attribute reference S in $S\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule 'S' in non-local ref '$S::j'\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule 'S' in non-local ref '$S::j = 3;'\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule 'S' in non-local ref '$S::j = $S::k;'\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule S in non-local ref $S::j\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule S in non-local ref $S::j = 3;\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:5:8: reference to undefined rule S in non-local ref $S::j = $S::k;\n",
};
String[] dynInlineChecks = {
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference 'a' in '$a'\n",
"$b", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference 'b' in '$b'\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference 'lab' in '$lab'\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:7: unknown attribute 'f' for rule 'b' in '$b::f'\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule 'S' in non-local ref '$S::i'\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:10: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:7: unknown attribute 'z' for rule 'a' in '$a::z'\n",
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference a in $a\n",
"$b", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference b in $b\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:7:4: missing attribute access on rule reference lab in $lab\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:7: unknown attribute f for rule b in $b::f\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule S in non-local ref $S::i\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule S in non-local ref $S::i\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:10: reference to undefined rule S in non-local ref $S::i\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:7:7: unknown attribute z for rule a in $a::z\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule 'S' in non-local ref '$S::j'\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule 'S' in non-local ref '$S::j = 3;'\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule 'S' in non-local ref '$S::j = $S::k;'\n",
"$Q[-1]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[-i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[0]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[-1]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[-i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$Q[0]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'Q' in '$Q'\n",
"$S[-1]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[-i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[0]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[-1]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[-i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[0]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n",
"$S[$S::y]::i", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference 'S' in '$S'\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:7: reference to undefined rule 'S' in non-local ref '$S::y'\n"
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule S in non-local ref $S::j\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule S in non-local ref $S::j = 3;\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:4: reference to undefined rule S in non-local ref $S::j = $S::k;\n",
"$Q[-1]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[-i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[0]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[-1]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[-i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$Q[0]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference Q in $Q\n",
"$S[-1]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[-i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[i]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[0]::y", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[-1]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[-i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[i]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[0]::y = 23;", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n",
"$S[$S::y]::i", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:7:4: unknown attribute reference S in $S\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:7:7: reference to undefined rule S in non-local ref $S::y\n"
};
String[] dynFinallyChecks = {
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference 'a' in '$a'\n",
"$b", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'b' in '$b'\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference 'lab' in '$lab'\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:17: unknown attribute 'f' for rule 'b' in '$b::f'\n",
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference 'S' in '$S'\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule 'S' in non-local ref '$S::i'\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:20: reference to undefined rule 'S' in non-local ref '$S::i'\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:17: unknown attribute 'z' for rule 'a' in '$a::z'\n",
"$a", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference a in $a\n",
"$b", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference b in $b\n",
"$lab", "error(" + ErrorType.ISOLATED_RULE_REF.code + "): A.g4:10:14: missing attribute access on rule reference lab in $lab\n",
"$b::f", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:17: unknown attribute f for rule b in $b::f\n",
"$S", "error(" + ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE.code + "): A.g4:10:14: unknown attribute reference S in $S\n",
"$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule S in non-local ref $S::i\n",
"$S::i=$S::i", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule S in non-local ref $S::i\n" +
"error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:20: reference to undefined rule S in non-local ref $S::i\n",
"$a::z", "error(" + ErrorType.UNKNOWN_RULE_ATTRIBUTE.code + "): A.g4:10:17: unknown attribute z for rule a in $a::z\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule 'S' in non-local ref '$S::j'\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule 'S' in non-local ref '$S::j = 3;'\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule 'S' in non-local ref '$S::j = $S::k;'\n",
"$S::j", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule S in non-local ref $S::j\n",
"$S::j = 3;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule S in non-local ref $S::j = 3;\n",
"$S::j = $S::k;", "error(" + ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF.code + "): A.g4:10:14: reference to undefined rule S in non-local ref $S::j = $S::k;\n",
};
@Test public void testMembersActions() throws RecognitionException {

View File

@ -54,17 +54,17 @@ public class TestBasicSemanticErrors extends BaseTest {
"b : ( options { ick=bar; greedy=true; } : ID )+ ;\n" +
"c : ID<blue> ID<x=y> ;",
// YIELDS
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:2:10: unsupported option 'foo'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:2:19: unsupported option 'k'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:2:10: unsupported option foo\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:2:19: unsupported option k\n" +
"error(" + ErrorType.TOKEN_NAMES_MUST_START_UPPER.code + "): U.g4:5:8: token names must start with an uppercase letter: f\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:9:10: unsupported option 'x'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:9:10: unsupported option x\n" +
"error(" + ErrorType.REPEATED_PREQUEL.code + "): U.g4:9:0: repeated grammar prequel spec (options, tokens, or import); please merge\n" +
"error(" + ErrorType.REPEATED_PREQUEL.code + "): U.g4:8:0: repeated grammar prequel spec (options, tokens, or import); please merge\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:12:10: unsupported option 'blech'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:12:21: unsupported option 'greedy'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:15:16: unsupported option 'ick'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:15:25: unsupported option 'greedy'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:16:16: unsupported option 'x'\n",
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:12:10: unsupported option blech\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:12:21: unsupported option greedy\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:15:16: unsupported option ick\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:15:25: unsupported option greedy\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): U.g4:16:16: unsupported option x\n",
};
@Test public void testU() { super.testErrors(U, false); }
@ -82,7 +82,7 @@ public class TestBasicSemanticErrors extends BaseTest {
"";
String expected =
"error(" + ErrorType.LABEL_BLOCK_NOT_A_SET.code + "): T.g4:2:5: label 'op' assigned to a block which is not a set\n";
"error(" + ErrorType.LABEL_BLOCK_NOT_A_SET.code + "): T.g4:2:5: label op assigned to a block which is not a set\n";
testErrors(new String[] { grammar, expected }, false);
}
@ -97,16 +97,16 @@ public class TestBasicSemanticErrors extends BaseTest {
"expr : '=';\n";
String expected =
"error(" + ErrorType.ARG_CONFLICTS_WITH_RULE.code + "): T.g4:2:7: parameter 'expr' conflicts with rule with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_RULE.code + "): T.g4:2:26: return value 'expr' conflicts with rule with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_RULE.code + "): T.g4:3:12: local 'expr' conflicts with rule with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_ARG.code + "): T.g4:2:26: return value 'expr' conflicts with parameter with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_ARG.code + "): T.g4:3:12: local 'expr' conflicts with parameter with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_RETVAL.code + "): T.g4:3:12: local 'expr' conflicts with return value with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): T.g4:4:4: label 'expr' conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_ARG.code + "): T.g4:4:4: label 'expr' conflicts with parameter with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RETVAL.code + "): T.g4:4:4: label 'expr' conflicts with return value with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_LOCAL.code + "): T.g4:4:4: label 'expr' conflicts with local with same name\n";
"error(" + ErrorType.ARG_CONFLICTS_WITH_RULE.code + "): T.g4:2:7: parameter expr conflicts with rule with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_RULE.code + "): T.g4:2:26: return value expr conflicts with rule with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_RULE.code + "): T.g4:3:12: local expr conflicts with rule with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_ARG.code + "): T.g4:2:26: return value expr conflicts with parameter with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_ARG.code + "): T.g4:3:12: local expr conflicts with parameter with same name\n" +
"error(" + ErrorType.LOCAL_CONFLICTS_WITH_RETVAL.code + "): T.g4:3:12: local expr conflicts with return value with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): T.g4:4:4: label expr conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_ARG.code + "): T.g4:4:4: label expr conflicts with parameter with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RETVAL.code + "): T.g4:4:4: label expr conflicts with return value with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_LOCAL.code + "): T.g4:4:4: label expr conflicts with local with same name\n";
ST grammarST = new ST(grammarTemplate);
grammarST.add("args", "int expr");
grammarST.add("retvals", "int expr");

View File

@ -491,7 +491,7 @@ public class TestLeftRecursion extends BaseTest {
"ID : 'a'..'z'+ ;\n" +
"WS : (' '|'\\n') -> skip ;\n";
String expected =
"error(" + ErrorType.NO_NON_LR_ALTS.code + "): T.g4:3:0: left recursive rule 'a' must contain an alternative which is not left recursive\n";
"error(" + ErrorType.NO_NON_LR_ALTS.code + "): T.g4:3:0: left recursive rule a must contain an alternative which is not left recursive\n";
testErrors(new String[] { grammar, expected }, false);
}
@ -505,7 +505,7 @@ public class TestLeftRecursion extends BaseTest {
"ID : 'a'..'z'+ ;\n" +
"WS : (' '|'\\n') -> skip ;\n";
String expected =
"error(" + ErrorType.EPSILON_LR_FOLLOW.code + "): T.g4:3:0: left recursive rule 'a' contains a left recursive alternative which can be followed by the empty string\n";
"error(" + ErrorType.EPSILON_LR_FOLLOW.code + "): T.g4:3:0: left recursive rule a contains a left recursive alternative which can be followed by the empty string\n";
testErrors(new String[] { grammar, expected }, false);
}

View File

@ -32,6 +32,7 @@ package org.antlr.v4.test;
import org.antlr.v4.parse.ScopeParser;
import org.antlr.v4.tool.ErrorManager;
import org.antlr.v4.tool.Grammar;
import org.junit.Test;
import static org.junit.Assert.*;
@ -55,11 +56,12 @@ public class TestScopeParsing extends BaseTest {
"i,j, k", "{i=null i, j=null j, k=null k}",
};
@Test public void testArgs() {
@Test public void testArgs() throws Exception {
for (int i = 0; i < argPairs.length; i+=2) {
String input = argPairs[i];
String expected = argPairs[i+1];
String actual = ScopeParser.parseTypedArgList(null, input, new ErrorManager(null)).attributes.toString();
Grammar dummy = new Grammar("grammar T; a:'a';");
String actual = ScopeParser.parseTypedArgList(null, input, dummy).attributes.toString();
assertEquals(expected, actual);
}
}

View File

@ -238,7 +238,7 @@ public class TestSets extends BaseTest {
"a : A {System.out.println($A.text);} ;\n" +
"A : ~('a'|B) ;\n" +
"B : 'b' ;\n",
"error(" + ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET.code + "): T.g4:3:10: rule reference 'B' is not currently supported in a set\n"
"error(" + ErrorType.UNSUPPORTED_REFERENCE_IN_LEXER_SET.code + "): T.g4:3:10: rule reference B is not currently supported in a set\n"
};
super.testErrors(pair, true);
}

View File

@ -54,15 +54,15 @@ public class TestSymbolIssues extends BaseTest {
"\n" +
"ID : 'a'..'z'+ ID ;",
// YIELDS
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:5:1: redefinition of 'members' action\n" +
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:7:1: redefinition of 'header' action\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): A.g4:2:10: unsupported option 'opt'\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): A.g4:2:21: unsupported option 'k'\n" +
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:5:1: redefinition of 'members' action\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:9:27: implicit definition of token 'X' in parser\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:10:20: implicit definition of token 'Y' in parser\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:11:4: implicit definition of token 'FJKD' in parser\n" +
"error(" + ErrorType.RULE_HAS_NO_ARGS.code + "): A.g4:9:37: rule 'b' has no defined parameters\n" +
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:5:1: redefinition of members action\n" +
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:7:1: redefinition of header action\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): A.g4:2:10: unsupported option opt\n" +
"warning(" + ErrorType.ILLEGAL_OPTION.code + "): A.g4:2:21: unsupported option k\n" +
"error(" + ErrorType.ACTION_REDEFINITION.code + "): A.g4:5:1: redefinition of members action\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:9:27: implicit definition of token X in parser\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:10:20: implicit definition of token Y in parser\n" +
"warning(" + ErrorType.IMPLICIT_TOKEN_DEFINITION.code + "): A.g4:11:4: implicit definition of token FJKD in parser\n" +
"error(" + ErrorType.RULE_HAS_NO_ARGS.code + "): A.g4:9:37: rule b has no defined parameters\n" +
"error(" + ErrorType.MISSING_RULE_ARGS.code + "): A.g4:10:31: missing arguments(s) on rule reference: a\n"
};
@ -77,10 +77,10 @@ public class TestSymbolIssues extends BaseTest {
"\n" +
"s : FOO ;",
// YIELDS
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): B.g4:4:4: label 's' conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): B.g4:4:9: label 'b' conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_TOKEN.code + "): B.g4:4:15: label 'X' conflicts with token with same name\n" +
"error(" + ErrorType.LABEL_TYPE_CONFLICT.code + "): B.g4:6:9: label 'x' type mismatch with previous definition: TOKEN_LIST_LABEL!=TOKEN_LABEL\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): B.g4:4:4: label s conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_RULE.code + "): B.g4:4:9: label b conflicts with rule with same name\n" +
"error(" + ErrorType.LABEL_CONFLICTS_WITH_TOKEN.code + "): B.g4:4:15: label X conflicts with token with same name\n" +
"error(" + ErrorType.LABEL_TYPE_CONFLICT.code + "): B.g4:6:9: label x type mismatch with previous definition: TOKEN_LIST_LABEL!=TOKEN_LABEL\n" +
"error(" + ErrorType.IMPLICIT_STRING_DEFINITION.code + "): B.g4:4:20: cannot create implicit token for string literal in non-combined grammar: '.'\n"
};
@ -97,8 +97,8 @@ public class TestSymbolIssues extends BaseTest {
" : ID ;",
// YIELDS
"error(" + ErrorType.LABEL_CONFLICTS_WITH_ARG.code + "): D.g4:4:21: label 'j' conflicts with parameter with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_ARG.code + "): D.g4:6:22: return value 'i' conflicts with parameter with same name\n"
"error(" + ErrorType.LABEL_CONFLICTS_WITH_ARG.code + "): D.g4:4:21: label j conflicts with parameter with same name\n" +
"error(" + ErrorType.RETVAL_CONFLICTS_WITH_ARG.code + "): D.g4:6:22: return value i conflicts with parameter with same name\n"
};
static String[] E = {
@ -112,7 +112,7 @@ public class TestSymbolIssues extends BaseTest {
"a : A ;\n",
// YIELDS
"warning(" + ErrorType.TOKEN_NAME_REASSIGNMENT.code + "): E.g4:3:4: token name 'A' is already defined\n"
"warning(" + ErrorType.TOKEN_NAME_REASSIGNMENT.code + "): E.g4:3:4: token name A is already defined\n"
};
@Test public void testA() { super.testErrors(A, false); }
@ -147,7 +147,7 @@ public class TestSymbolIssues extends BaseTest {
"mode X;\n" +
"fragment B : 'b';",
"error(" + ErrorType.MODE_WITHOUT_RULES.code + "): L.g4:3:5: lexer mode 'X' must contain at least one non-fragment rule\n"
"error(" + ErrorType.MODE_WITHOUT_RULES.code + "): L.g4:3:5: lexer mode X must contain at least one non-fragment rule\n"
};
testErrors(test, false);
@ -162,8 +162,8 @@ public class TestSymbolIssues extends BaseTest {
" B : C;\n" +
" fragment C : A | (A C)?;",
"warning(" + ErrorType.EPSILON_TOKEN.code + "): L.g4:3:0: non-fragment lexer rule 'WS' can match the empty string\n" +
"warning(" + ErrorType.EPSILON_TOKEN.code + "): L.g4:5:2: non-fragment lexer rule 'B' can match the empty string\n"
"warning(" + ErrorType.EPSILON_TOKEN.code + "): L.g4:3:0: non-fragment lexer rule WS can match the empty string\n" +
"warning(" + ErrorType.EPSILON_TOKEN.code + "): L.g4:5:2: non-fragment lexer rule B can match the empty string\n"
};
testErrors(test, false);

View File

@ -40,7 +40,7 @@ public class TestToolSyntaxErrors extends BaseTest {
"grammar A;\n" +
"",
// YIELDS
"error(" + ErrorType.NO_RULES.code + "): A.g4::: grammar 'A' has no rules\n",
"error(" + ErrorType.NO_RULES.code + "): A.g4::: grammar A has no rules\n",
"A;",
"error(" + ErrorType.SYNTAX_ERROR.code + "): A.g4:1:0: syntax error: 'A' came as a complete surprise to me\n",
@ -274,8 +274,8 @@ public class TestToolSyntaxErrors extends BaseTest {
"X : 'foo' -> popmode;\n" + // "meant" to use -> popMode
"Y : 'foo' -> token(Foo);", // "meant" to use -> type(Foo)
"error(" + ErrorType.INVALID_LEXER_COMMAND.code + "): A.g4:4:13: lexer command 'popmode' does not exist or is not supported by the current target\n" +
"error(" + ErrorType.INVALID_LEXER_COMMAND.code + "): A.g4:5:13: lexer command 'token' does not exist or is not supported by the current target\n"
"error(" + ErrorType.INVALID_LEXER_COMMAND.code + "): A.g4:4:13: lexer command popmode does not exist or is not supported by the current target\n" +
"error(" + ErrorType.INVALID_LEXER_COMMAND.code + "): A.g4:5:13: lexer command token does not exist or is not supported by the current target\n"
};
super.testErrors(pair, true);
}
@ -288,8 +288,8 @@ public class TestToolSyntaxErrors extends BaseTest {
"X : 'foo' -> popMode(Foo);\n" + // "meant" to use -> popMode
"Y : 'foo' -> type;", // "meant" to use -> type(Foo)
"error(" + ErrorType.UNWANTED_LEXER_COMMAND_ARGUMENT.code + "): A.g4:4:13: lexer command 'popMode' does not take any arguments\n" +
"error(" + ErrorType.MISSING_LEXER_COMMAND_ARGUMENT.code + "): A.g4:5:13: missing argument for lexer command 'type'\n"
"error(" + ErrorType.UNWANTED_LEXER_COMMAND_ARGUMENT.code + "): A.g4:4:13: lexer command popMode does not take any arguments\n" +
"error(" + ErrorType.MISSING_LEXER_COMMAND_ARGUMENT.code + "): A.g4:5:13: missing argument for lexer command type\n"
};
super.testErrors(pair, true);
}
@ -304,7 +304,7 @@ public class TestToolSyntaxErrors extends BaseTest {
"A : 'a' ;\n" +
"B : 'b' ;\n",
"error(" + ErrorType.RULE_REDEFINITION.code + "): Oops.g4:4:0: rule 'ret_ty' redefinition; previous at line 3\n"
"error(" + ErrorType.RULE_REDEFINITION.code + "): Oops.g4:4:0: rule ret_ty redefinition; previous at line 3\n"
};
super.testErrors(pair, true);
}
@ -318,9 +318,9 @@ public class TestToolSyntaxErrors extends BaseTest {
+ "z1 : ('foo' | 'bar'? 'bar2'?)*;\n"
+ "z2 : ('foo' | 'bar' 'bar2'? | 'bar2')*;\n";
String expected =
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:3:0: rule 'y1' contains a closure with at least one alternative that can match an empty string\n" +
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:4:0: rule 'y2' contains a closure with at least one alternative that can match an empty string\n" +
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:5:0: rule 'z1' contains a closure with at least one alternative that can match an empty string\n";
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:3:0: rule y1 contains a closure with at least one alternative that can match an empty string\n" +
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:4:0: rule y2 contains a closure with at least one alternative that can match an empty string\n" +
"error(" + ErrorType.EPSILON_CLOSURE.code + "): A.g4:5:0: rule z1 contains a closure with at least one alternative that can match an empty string\n";
String[] pair = new String[] {
grammar,
@ -338,8 +338,8 @@ public class TestToolSyntaxErrors extends BaseTest {
+ "z1 : ('foo' | 'bar'? 'bar2'?)?;\n"
+ "z2 : ('foo' | 'bar' 'bar2'? | 'bar2')?;\n";
String expected =
"warning(" + ErrorType.EPSILON_OPTIONAL.code + "): A.g4:3:0: rule 'y' contains an optional block with at least one alternative that can match an empty string\n" +
"warning(" + ErrorType.EPSILON_OPTIONAL.code + "): A.g4:4:0: rule 'z1' contains an optional block with at least one alternative that can match an empty string\n";
"warning(" + ErrorType.EPSILON_OPTIONAL.code + "): A.g4:3:0: rule y contains an optional block with at least one alternative that can match an empty string\n" +
"warning(" + ErrorType.EPSILON_OPTIONAL.code + "): A.g4:4:0: rule z1 contains an optional block with at least one alternative that can match an empty string\n";
String[] pair = new String[] {
grammar,
@ -465,7 +465,7 @@ public class TestToolSyntaxErrors extends BaseTest {
" |<assoc=right> x '*' x // ok\n" +
" ;\n";
String expected =
"warning(" + ErrorType.UNRECOGNIZED_ASSOC_OPTION.code + "): A.g4:3:10: rule 'x' contains an 'assoc' terminal option in an unrecognized location\n";
"warning(" + ErrorType.UNRECOGNIZED_ASSOC_OPTION.code + "): A.g4:3:10: rule x contains an assoc terminal option in an unrecognized location\n";
String[] pair = new String[] {
grammar,
@ -493,8 +493,8 @@ public class TestToolSyntaxErrors extends BaseTest {
"Y2 : 'x' {more();} // warning 158\n" +
" ;\n";
String expected =
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:7:12: fragment rule 'X2' contains an action or command which can never be executed\n" +
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:10:9: fragment rule 'Y2' contains an action or command which can never be executed\n";
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:7:12: fragment rule X2 contains an action or command which can never be executed\n" +
"warning(" + ErrorType.FRAGMENT_ACTION_IGNORED.code + "): A.g4:10:9: fragment rule Y2 contains an action or command which can never be executed\n";
String[] pair = new String[] {
grammar,
@ -515,7 +515,7 @@ public class TestToolSyntaxErrors extends BaseTest {
"WS : ' ';\n" +
" EOF : 'a';\n";
String expected =
"error(" + ErrorType.RESERVED_RULE_NAME.code + "): A.g4:3:1: cannot declare a rule with reserved name 'EOF'\n";
"error(" + ErrorType.RESERVED_RULE_NAME.code + "): A.g4:3:1: cannot declare a rule with reserved name EOF\n";
String[] pair = new String[] {
grammar,