Antlr4如何检测无法识别的令牌和给定的句子无效
Antlr4 how to detect unrecognized token and given sentence is invalid
我正在尝试使用 Antlr 开发一种新语言。这是我的语法文件:
grammar test;
program : vr'.' to'.' e
;
e: be
| be'.' top'.' be
;
be: 'fg'
| 'fs'
| 'mc'
;
to: 'n'
| 'a'
| 'ev'
;
vr: 'er'
| 'fp'
;
top: 'b'
| 'af'
;
Whitespace : [ \t\r\n]+ ->skip
;
Main.java
String expression = "fp.n.fss";
//String expression = "fp.n.fs.fs";
ANTLRInputStream input = new ANTLRInputStream(expression);
testLexer lexer = new testLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
testParser parser = new testParser(tokens);
//remove listener and add listener does not work
ParseTree parseTree = parser.program();
一切都适合有效的句子。但我想捕获无法识别的标记和无效句子,以便 return 有意义的消息。这是我的问题的两个测试用例。
fp.n.fss => anltr gives this error token recognition error at: 's' but i could not handle this error. There are same example error handler class which use BaseErrorListener but in my case it does not work.
fp.n.fs.fs => this sentence is invalid for my grammar but i could not catch. How can i catch invalidations like this sentence?
首先欢迎来到 SO,也欢迎来到 ANTLR 部分!错误处理似乎是经常被问到的话题之一,这里有一个关于 Java/ANTLR4.
中错误处理的非常好的话题
您很可能希望扩展 defaultErrorStrategy 的功能来处理特定问题,并以不同的方式处理它们,即仅在 's' 处打印错误行 1:12 令牌识别错误。
为此,您可以实施您自己的默认错误策略版本 class:
Parser parser = new testParser(tokens);
parser.setErrorHandler(new DefaultErrorStrategy()
{
@Override
public void recover(Parser recognizer, RecognitionException e) {
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
@Override
public Token recoverInline(Parser recognizer)
throws RecognitionException
{
InputMismatchException e = new InputMismatchException(recognizer);
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
});
parser.program(); //back to first rule in your grammar
我还想建议将解析器和词法分析器语法分开,如果不是为了可读性,也是因为许多用于分析 .g4 文件的工具(尤其是 ANTLRWORKS 2)会抱怨隐式声明。
对于您的示例,可以将其修改为以下结构:
grammar test;
program : vr DOT to DOT e
;
e: be
| be DOT top DOT be
;
be: FG
| FS
| MC
;
to: N
| A
| EV
;
vr: ER
| FP
;
top: B
| AF
;
Whitespace : [ \t\r\n]+ ->skip
;
DOT : '.'
;
A: 'A'|'a'
;
AF: 'AF'|'af'
;
N: 'N'|'n'
;
MC: 'MC'|'mc'
;
EV:'EV'|'ev'
;
FS: 'FS'|'fs'
;
FP: 'FP'|'fp'
;
FG: 'FG'|'fg'
;
ER: 'ER'|'er'
;
B: 'B'|'b'
;
您还可以找到所有可用于 defaultErrorStrategy Class here 的方法,并通过将这些方法添加到您的 "new" 错误策略实现来处理您需要的任何异常。
希望这对您有所帮助,祝您项目顺利!
我正在尝试使用 Antlr 开发一种新语言。这是我的语法文件:
grammar test;
program : vr'.' to'.' e
;
e: be
| be'.' top'.' be
;
be: 'fg'
| 'fs'
| 'mc'
;
to: 'n'
| 'a'
| 'ev'
;
vr: 'er'
| 'fp'
;
top: 'b'
| 'af'
;
Whitespace : [ \t\r\n]+ ->skip
;
Main.java
String expression = "fp.n.fss";
//String expression = "fp.n.fs.fs";
ANTLRInputStream input = new ANTLRInputStream(expression);
testLexer lexer = new testLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
testParser parser = new testParser(tokens);
//remove listener and add listener does not work
ParseTree parseTree = parser.program();
一切都适合有效的句子。但我想捕获无法识别的标记和无效句子,以便 return 有意义的消息。这是我的问题的两个测试用例。
fp.n.fss => anltr gives this error token recognition error at: 's' but i could not handle this error. There are same example error handler class which use BaseErrorListener but in my case it does not work.
fp.n.fs.fs => this sentence is invalid for my grammar but i could not catch. How can i catch invalidations like this sentence?
首先欢迎来到 SO,也欢迎来到 ANTLR 部分!错误处理似乎是经常被问到的话题之一,这里有一个关于 Java/ANTLR4.
中错误处理的非常好的话题您很可能希望扩展 defaultErrorStrategy 的功能来处理特定问题,并以不同的方式处理它们,即仅在 's' 处打印错误行 1:12 令牌识别错误。
为此,您可以实施您自己的默认错误策略版本 class:
Parser parser = new testParser(tokens);
parser.setErrorHandler(new DefaultErrorStrategy()
{
@Override
public void recover(Parser recognizer, RecognitionException e) {
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
@Override
public Token recoverInline(Parser recognizer)
throws RecognitionException
{
InputMismatchException e = new InputMismatchException(recognizer);
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
});
parser.program(); //back to first rule in your grammar
我还想建议将解析器和词法分析器语法分开,如果不是为了可读性,也是因为许多用于分析 .g4 文件的工具(尤其是 ANTLRWORKS 2)会抱怨隐式声明。
对于您的示例,可以将其修改为以下结构:
grammar test;
program : vr DOT to DOT e
;
e: be
| be DOT top DOT be
;
be: FG
| FS
| MC
;
to: N
| A
| EV
;
vr: ER
| FP
;
top: B
| AF
;
Whitespace : [ \t\r\n]+ ->skip
;
DOT : '.'
;
A: 'A'|'a'
;
AF: 'AF'|'af'
;
N: 'N'|'n'
;
MC: 'MC'|'mc'
;
EV:'EV'|'ev'
;
FS: 'FS'|'fs'
;
FP: 'FP'|'fp'
;
FG: 'FG'|'fg'
;
ER: 'ER'|'er'
;
B: 'B'|'b'
;
您还可以找到所有可用于 defaultErrorStrategy Class here 的方法,并通过将这些方法添加到您的 "new" 错误策略实现来处理您需要的任何异常。
希望这对您有所帮助,祝您项目顺利!