ANTLR4:我可以';我不明白
我对ANTLR4非常陌生,正在尝试构建自己的语言。所以我的语法从ANTLR4:我可以';我不明白,antlr,antlr4,Antlr,Antlr4,我对ANTLR4非常陌生,正在尝试构建自己的语言。所以我的语法从 program: <EOF> | statement | functionDef | statement program | functionDef program; 及 现在的问题是,当我根据selectionStatement或statement测试一段代码时,它通过了测试,但当我根据程序测试它时,它无法识别。有人能帮我吗?多谢各位 编辑:我用于测试的代码如下: if (x == 2) {} 它通过了对选择语
program: <EOF> | statement | functionDef | statement program | functionDef program;
及
现在的问题是,当我根据selectionStatement
或statement
测试一段代码时,它通过了测试,但当我根据程序测试它时,它无法识别。有人能帮我吗?多谢各位
编辑:我用于测试的代码如下:
if (x == 2) {}
它通过了对选择语句
和语句
的测试,但在程序
中失败。似乎程序
仅接受if…else
if (x == 2) {} else {}
编辑2:
我收到的错误消息是
<unknown>: Incorrect error: no viable alternative at input 'if(x==2){}'
:错误:输入'if(x==2){}'时没有可行的替代方案
无法回答您的问题,因为提供的信息不完整:语句规则是部分的,而compoundStatement规则缺失
尽管如此,您应该使用两种技巧自己回答此类问题(除了单元测试)
首先,确保lexer按预期工作。显示如何直接转储令牌流
第二,使用定制的ErrorListener为每个遇到的错误提供有意义/详细的解析路径描述。例如:
public class JavaErrorListener extends BaseErrorListener {
public int lastError = -1;
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
Parser parser = (Parser) recognizer;
String name = parser.getSourceName();
TokenStream tokens = parser.getInputStream();
Token offSymbol = (Token) offendingSymbol;
int thisError = offSymbol.getTokenIndex();
if (offSymbol.getType() == -1 && thisError == tokens.size() - 1) {
Log.debug(this, name + ": Incorrect error: " + msg);
return;
}
String offSymName = JavaLexer.VOCABULARY.getSymbolicName(offSymbol.getType());
List<String> stack = parser.getRuleInvocationStack();
// Collections.reverse(stack);
Log.error(this, name);
Log.error(this, "Rule stack: " + stack);
Log.error(this, "At line " + line + ":" + charPositionInLine + " at " + offSymName + ": " + msg);
if (thisError > lastError + 10) {
lastError = thisError - 10;
}
for (int idx = lastError + 1; idx <= thisError; idx++) {
Token token = tokens.get(idx);
if (token.getChannel() != Token.HIDDEN_CHANNEL) Log.error(this, token.toString());
}
lastError = thisError;
}
}
公共类JavaErrorListener扩展了BaseErrorListener{
public int lastError=-1;
@凌驾
public void syntaxError(识别器识别器、对象违规符号、int-line、int-charPositionInLine、,
字符串消息,识别异常(e){
解析器=(解析器)识别器;
String name=parser.getSourceName();
TokenStream tokens=parser.getInputStream();
Token offSymbol=(Token)offingsymbol;
int thisrerror=offSymbol.getTokenIndex();
if(offSymbol.getType()=-1&&thisError==tokens.size()-1){
Log.debug(此,名称+”:错误:“+msg”);
返回;
}
字符串offSymName=JavaLexer.词汇表.getSymbolicName(offSymbol.getType());
List stack=parser.getRuleInvocationStack();
//集合。反向(堆栈);
Log.error(此,名称);
Log.error(此“规则堆栈:“+stack”);
Log.error(这是“在行”+line+:“+charPositionInLine+”在“+offSymName+”:“+msg”);
如果(此错误>上次错误+10){
lastError=此错误-10;
}
对于(int idx=lastError+1;idx感谢您的帮助。我编辑了此问题,使其包含compoundStatement的实现。我已确认lexer按预期工作,并将从errorListener
收到的错误放在上次编辑中。我仍然找不到问题的解释或解决方案。您可以吗看看我?基于不完整的信息仍然无法回答。什么是完整的语句规则?什么是完整的错误消息(错误侦听器发出更多有价值的信息)?什么是完整的令牌流转储?基于您自己对这些信息的分析,您自己的问题和结论是什么?
<unknown>: Incorrect error: no viable alternative at input 'if(x==2){}'
public class JavaErrorListener extends BaseErrorListener {
public int lastError = -1;
@Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int line, int charPositionInLine,
String msg, RecognitionException e) {
Parser parser = (Parser) recognizer;
String name = parser.getSourceName();
TokenStream tokens = parser.getInputStream();
Token offSymbol = (Token) offendingSymbol;
int thisError = offSymbol.getTokenIndex();
if (offSymbol.getType() == -1 && thisError == tokens.size() - 1) {
Log.debug(this, name + ": Incorrect error: " + msg);
return;
}
String offSymName = JavaLexer.VOCABULARY.getSymbolicName(offSymbol.getType());
List<String> stack = parser.getRuleInvocationStack();
// Collections.reverse(stack);
Log.error(this, name);
Log.error(this, "Rule stack: " + stack);
Log.error(this, "At line " + line + ":" + charPositionInLine + " at " + offSymName + ": " + msg);
if (thisError > lastError + 10) {
lastError = thisError - 10;
}
for (int idx = lastError + 1; idx <= thisError; idx++) {
Token token = tokens.get(idx);
if (token.getChannel() != Token.HIDDEN_CHANNEL) Log.error(this, token.toString());
}
lastError = thisError;
}
}