在我的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
命令的连续规则匹配将内容累积到最终生成的令牌中。