计算器!
我正在使用antlr4来解析输入。 我有我的XXXX.g4语法文件和antlr4 maven插件在构建时生成一些解析器代码。 我正在使用该代码解析输入:
XXXXParser parser = new XXXXParser(new CommonTokenStream(
new XXXXLexer(new ANTLRInputStream(currentInput))));
parser.command();
在上面的代码中,“command”是我语法中规则的名称。每次启动此代码时,如果currentInput字符串不符合语法,我会在控制台中收到错误消息。我希望能够捕获这些消息并使用它们。问题是如何实现这一目标?
答案 0 :(得分:3)
您可以编写一个实现IAntlrErrorListener<T>
的类,然后调用parser.AddErrorListener()
并传入您的自定义错误列表器。这是我自己的代码(我实际上继承自DiagnosticErrorListener
)的一个例子:
public class CustomErrorListener : DiagnosticErrorListener
{
private readonly List<string> _errorMessages = new List<string>();
public IList<string> ErrorMessages { get { return _errorMessages; } }
private readonly List<string> _warningMessages = new List<string>();
public IList<string> WarningMessages { get { return _warningMessages; } }
public bool HasErrors { get { return _errorMessages.Count > 0; } }
public bool HasWarnings { get { return _warningMessages.Count > 0; } }
private readonly bool _captureDiagnostics;
public CustomErrorListener(bool captureDiagnosticWarnings)
{
_captureDiagnostics = captureDiagnosticWarnings;
}
public override void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
{
_errorMessages.Add(string.Format("line {0}:{1} {2} at: {3}", line, charPositionInLine, msg, offendingSymbol.Text));
}
public override void ReportAmbiguity(Parser recognizer, Antlr4.Runtime.Dfa.DFA dfa, int startIndex, int stopIndex, bool exact, Sharpen.BitSet ambigAlts, Antlr4.Runtime.Atn.ATNConfigSet configs)
{
if (_captureDiagnostics)
{
_warningMessages.Add(string.Format("reportAmbiguity d={0}: ambigAlts={1}, input='{2}'", GetDecisionDescription(recognizer, dfa), GetConflictingAlts(ambigAlts, configs), ((ITokenStream)recognizer.InputStream).GetText(Interval.Of(startIndex, stopIndex))));
}
}
public override void ReportAttemptingFullContext(Parser recognizer, Antlr4.Runtime.Dfa.DFA dfa, int startIndex, int stopIndex, Sharpen.BitSet conflictingAlts, Antlr4.Runtime.Atn.SimulatorState conflictState)
{
if (_captureDiagnostics)
{
_warningMessages.Add(string.Format("reportAttemptingFullContext d={0}, input='{1}'", GetDecisionDescription(recognizer, dfa), ((ITokenStream)recognizer.InputStream).GetText(Interval.Of(startIndex, stopIndex))));
}
}
public override void ReportContextSensitivity(Parser recognizer, Antlr4.Runtime.Dfa.DFA dfa, int startIndex, int stopIndex, int prediction, Antlr4.Runtime.Atn.SimulatorState acceptState)
{
if (_captureDiagnostics)
{
_warningMessages.Add(string.Format("reportContextSensitivity d={0}, input='{1}'", GetDecisionDescription(recognizer, dfa), ((ITokenStream)recognizer.InputStream).GetText(Interval.Of(startIndex, stopIndex))));
}
}
}
然后你可以写这样的代码:
XXXXParser parser = new XXXXParser(new CommonTokenStream(
new XXXXLexer(new ANTLRInputStream(currentInput))));
CustomErrorListener errorListener = new CustomErrorListener(false);
parser.AddErrorListener(errorListener);
parser.command();