调用 Antlr4 词法分析器后'more'意外行为



在我的lexer语法规则之一中有'more'命令。因此,单个字符标记匹配多个字符文本,这一定不会发生,或者我错过了一些东西。语法如下:

lexer grammar MyLexer;
    StartQuote
        : '"'
        -> pushMode(BeforeTextMode)
        ;
mode BeforeTextMode;
    SwitchToTextMode
        : .
        -> more, mode(TextMode)
        ;
mode TextMode;
    Text
        : ~'"'+
        ;
    EndQuote
        : '"'
        -> popMode
        ;

下面是测试程序:

class Program
{
    static string InputText1 = ""x"";
    static string InputText2 = ""xy"";
    static string[] TokenTypeNames = new string[] { "StartQuote", "Text", "EndQuote" };
    static void Main(string[] args)
    {
        string TokenSequence1 = GetTokenSequence(InputText1);
        string TokenSequence2 = GetTokenSequence(InputText2);
        Console.WriteLine(TokenSequence1);
        Console.WriteLine(TokenSequence2);
    }
    static string GetTokenSequence(string InputText)
    {
        var Lexer = new MyLexer(new AntlrInputStream(InputText));
        string TokenSequence = "";
        for (var Token = Lexer.NextToken(); Token.Type != -1; Token = Lexer.NextToken())
            TokenSequence += TokenTypeNames[Token.Type - 1] + "(" + Token.Text + ")" + " ";
        return TokenSequence;
    }
}
输出:

StartQuote(") EndQuote(x")
StartQuote(") Text(xy) EndQuote(")
从程序的输出中可以看到,单个字符的EndQuote匹配多个字符的文本。只有当输入文本在引号之间包含单个字符时才会发生这种情况。

你能看一看,看看我是否遗漏了什么,如果这确实是一个bug在Antlr4。

more命令将匹配的内容添加到实际生成的下一个令牌的内容中。对于输入"x",点匹配并消耗来自输入的x;没有额外的输入让Text规则有效匹配,所以没有Text令牌。

点匹配之后的第一个标记是结束引号标记,因此以内容x"结束。

顺便说一句,此行为允许遵循more命令的连续规则匹配将内容累积到最终生成的令牌中。

最新更新