我正在使用带有 c# 目标的 Antlr 4。这是我的语法的一个子集:
/*
* Parser Rules
*/
text : term+ EOF;
term : a1 a2 a3;
a1: ....
...
...
我想接受有效的数据块作为(术语),当存在错误时,我想搜索下一个有效术语并打印出导致错误的整个文本供用户手动分析。
如何将输入同步到下一个有效期限?以及如何获取被忽略的文本?
您需要为此创建自己的实现IAntlrErrorStrategy
,然后将该Parser.ErrorHandler
属性设置为错误策略的实例。Java 版本的ANTLRErrorStrategy
接口和默认实现的文档DefaultErrorStrategy
可能会为实现错误策略提供有用的信息,但我必须警告您,创建自定义错误策略是文档有限的高级功能。预计实现者已经是 ANTLR 4 实现自适应 LL(*) 解析算法的专家(我们正在谈论研究人员级别的理解)。
对于第一个问题(如何将输入同步到下一个有效术语?),我发现了一些有用的信息,这些信息使我找到了可接受的解决方案。
Antlr 为先前的语法生成下一个子代码:
public TextContext text() {
TextContext _localctx = new TextContext(_ctx, State);
EnterRule(_localctx, 0, RULE_text);
int _la;
try {
EnterOuterAlt(_localctx, 1);
State = 49;
_errHandler.Sync(this);
_la = _input.La(1);
do {
State = 48; term();
State = 51;
_errHandler.Sync(this);
_la = _input.La(1);
} while ( _la==KEYWORD );
State = 53; Match(EOF);
}
catch (RecognitionException re) {
_localctx.exception = re;
_errHandler.ReportError(this, re);
_errHandler.Recover(this, re);
}
finally {
ExitRule();
}
return _localctx;
}
调用'_errHandler.Sync(this);' 使解析器在输入流中前进以尝试找到下一个有效转弯(作为“term+”组件的结果)。为了阻止解析器在其他子规则中同步接受“术语”规则”,我将 DefaultErrorStrategy 类扩展为下一个:
public class MyErrorStrategy : Antlr4.Runtime.DefaultErrorStrategy
{
public EventErrorStrategy() : base()
{ }
public override void Sync(Antlr4.Runtime.Parser recognizer)
{
if(recognizer.Context is Dict.TextAnalyzer.DictionaryParser.TextContext)
base.Sync(recognizer);
}
}
然后将其提供给解析器:
parser.ErrorHandler = new MyErrorStrategy();