使用ANTLR忽略最后一行C#

时间:2018-02-15 13:03:49

标签: c# antlr

我们使用ANTLR的C#4.6.4版来解析我们工具中使用的代码片段。语法类似于类似Pascal的PLC语言IEC61131。当有人输入一个片段并忘记分号结束最后一行时,解析器会忽略这一行。我该怎么做才能得到一些反馈?我至少需要向用户发送错误消息。

我已经有一个错误处理程序:

class ErrorListener : IAntlrErrorListener<IToken>
{
    public void SyntaxError(IRecognizer recognizer, IToken offendingSymbol, int line, int charPositionInLine, string msg, RecognitionException e)
    {
        _errorLine = offendingSymbol.Line;
        _errorColumn = offendingSymbol.Column + 1;
        _errorText = "Error on line " + _errorLine + ", column " + _errorColumn;
    }
}

我的词法分析器和解析器函数是:

public CommonTokenStream Lex(string stLike)
{
    AntlrInputStream input = new AntlrInputStream(stLike);
    IEC61131Lexer lexer = new IEC61131Lexer(input);
    CommonTokenStream tokenStream = new CommonTokenStream(lexer);

    return tokenStream;
}

public IParseTree Parse(CommonTokenStream tokenStream)
{
    IEC61131Parser parser = new IEC61131Parser(tokenStream);
    ErrorListener listener = new ErrorListener();
    parser.AddErrorListener((IAntlrErrorListener<IToken>)listener);

    return parser.iec_source();
}

他们被这样称呼:

    CommonTokenStream tokenStream = Lex(stLike);
    IParseTree tree = Parse(tokenStream);

    // If parsing went OK, _errorText will be empty
    if (_errorText == "")
    {
        // Walk the tree to create code
        IEC61131PlcVisitor visitor = new IEC61131PlcVisitor(theClass, tokenStream, target);
        visitor.Indent = indent;
        result = visitor.Visit(tree);
    }
    else
    {
        result = "<" + _errorText + ">";
    }

当我解析末尾缺少分号的代码片段时,词法分析器会为其生成标记,但解析器会在最后一个分号处停止。

Lexer contents

Parser debug

1 个答案:

答案 0 :(得分:1)

EOF规则的末尾添加iec_source令牌。

这样解析器就会知道它必须到达输入的末尾,并且如果在最后识别的语句之后找不到文件结尾,则会发出错误。