为什么规则不匹配最大的输入?
Why rule isn't matching the largest input?
我有以下语法:
myg : line+ EOF ;
line : ( command params | for_loop ) NEWLINE;
for_loop : 'for' WORD INT 'do' NEWLINE stmt_body;
stmt_body: line+ 'end';
params : ( param | WHITESPACE)*;
param : WORD | INT;
command : WORD;
fragment LOWERCASE : [a-z] ;
fragment UPPERCASE : [A-Z] ;
fragment DIGIT : [0-9] ;
WORD : (LOWERCASE | UPPERCASE | DIGIT | [_."'/\-])+ (DIGIT)* ;
INT : DIGIT+ ;
WHITESPACE : (' ' | '\t')+ ;
NEWLINE : ('\r'? '\n' | '\r')+ ;
尝试以下操作时:
>java org.antlr.v4.gui.TestRig Myg myg -tokens
command with parameter for 90 seconds
^Z
[@0,0:6='command',<WORD>,1:0]
[@1,7:7=' ',<WHITESPACE>,1:7]
[@2,8:11='with',<WORD>,1:8]
[@3,12:12=' ',<WHITESPACE>,1:12]
[@4,13:21='parameter',<WORD>,1:13]
[@5,22:22=' ',<WHITESPACE>,1:22]
[@6,23:25='for',<'for'>,1:23]
[@7,26:26=' ',<WHITESPACE>,1:26]
[@8,27:28='90',<WORD>,1:27]
[@9,29:29=' ',<WHITESPACE>,1:29]
[@10,30:36='seconds',<WORD>,1:30]
[@11,37:38='\r\n',<NEWLINE>,1:37]
[@12,39:38='<EOF>',<EOF>,2:0]
line 1:23 missing NEWLINE at 'for'
line 1:26 extraneous input ' ' expecting WORD
line 1:29 mismatched input ' ' expecting {WORD, INT, WHITESPACE, NEWLINE}
由于我不明白的原因,'for' 匹配为 'for',我的期望是 "command" 规则应该匹配整个输入行,因为规则应该匹配最大的输入。
或者换句话说,命令规则应该是贪婪的并且匹配整行。
此外,for_loop 是一个解析器规则(以小写字母开头),那么为什么它在生成令牌的过程中没有被忽略?
您的 command
规则匹配单个 WORD
标记,因此问题变成了为什么 WORD
不匹配整行。答案是 WORD
不匹配 space,所以它只能匹配第一个 space,而不是整个规则。但是 'for' 也匹配第一个 space 并且当两个规则产生相同长度的匹配时文字优先。
Also for_loop is a parser rule(start with lower case) so why it hasn't been ignored during the production of the tokens?
for_loop
是一个解析器规则(它确实被词法分析忽略了——你不会在输出中看到任何 for_loop
标记),但 'for' 不是。所有文字都是词法分析器规则(否则它们永远无法匹配)。
我有以下语法:
myg : line+ EOF ;
line : ( command params | for_loop ) NEWLINE;
for_loop : 'for' WORD INT 'do' NEWLINE stmt_body;
stmt_body: line+ 'end';
params : ( param | WHITESPACE)*;
param : WORD | INT;
command : WORD;
fragment LOWERCASE : [a-z] ;
fragment UPPERCASE : [A-Z] ;
fragment DIGIT : [0-9] ;
WORD : (LOWERCASE | UPPERCASE | DIGIT | [_."'/\-])+ (DIGIT)* ;
INT : DIGIT+ ;
WHITESPACE : (' ' | '\t')+ ;
NEWLINE : ('\r'? '\n' | '\r')+ ;
尝试以下操作时:
>java org.antlr.v4.gui.TestRig Myg myg -tokens
command with parameter for 90 seconds
^Z
[@0,0:6='command',<WORD>,1:0]
[@1,7:7=' ',<WHITESPACE>,1:7]
[@2,8:11='with',<WORD>,1:8]
[@3,12:12=' ',<WHITESPACE>,1:12]
[@4,13:21='parameter',<WORD>,1:13]
[@5,22:22=' ',<WHITESPACE>,1:22]
[@6,23:25='for',<'for'>,1:23]
[@7,26:26=' ',<WHITESPACE>,1:26]
[@8,27:28='90',<WORD>,1:27]
[@9,29:29=' ',<WHITESPACE>,1:29]
[@10,30:36='seconds',<WORD>,1:30]
[@11,37:38='\r\n',<NEWLINE>,1:37]
[@12,39:38='<EOF>',<EOF>,2:0]
line 1:23 missing NEWLINE at 'for'
line 1:26 extraneous input ' ' expecting WORD
line 1:29 mismatched input ' ' expecting {WORD, INT, WHITESPACE, NEWLINE}
由于我不明白的原因,'for' 匹配为 'for',我的期望是 "command" 规则应该匹配整个输入行,因为规则应该匹配最大的输入。
或者换句话说,命令规则应该是贪婪的并且匹配整行。
此外,for_loop 是一个解析器规则(以小写字母开头),那么为什么它在生成令牌的过程中没有被忽略?
您的 command
规则匹配单个 WORD
标记,因此问题变成了为什么 WORD
不匹配整行。答案是 WORD
不匹配 space,所以它只能匹配第一个 space,而不是整个规则。但是 'for' 也匹配第一个 space 并且当两个规则产生相同长度的匹配时文字优先。
Also for_loop is a parser rule(start with lower case) so why it hasn't been ignored during the production of the tokens?
for_loop
是一个解析器规则(它确实被词法分析忽略了——你不会在输出中看到任何 for_loop
标记),但 'for' 不是。所有文字都是词法分析器规则(否则它们永远无法匹配)。