ANTLR:如何调试错误识别的令牌
ANTLR: how to debug a misidentified token
我正在尝试在 Antlr4 中为一个简单的模板引擎实现一个语法。该引擎由 3 个不同的子句组成:
IF ANSWERED ( variable )
END IF
Variable
变量可以是任何大写或小写字母,包括空格。 IF ANSWERED
和 END IF
都是大写。
到目前为止,我已经编写了以下 grammar/lexer 规则,但我的问题是 IF ANSWERED
一直被识别为变量,而不是 2 个标记 IF
和 ANSWERED
.
grammar program;
/**grammar */
command: (ifStart | ifEnd | VARIABLE ) EOF;
ifStart: IF ANSWERED '(' VARIABLE ')';
ifEnd: 'END IF';
/** lexer */
IF: 'IF';
ANSWERED: 'ANSWERED';
TEXT: (LOWERCASE | UPPERCASE | NUMBER) ;
VARIABLE: (TEXT | [ \t\r\n])+;
fragment LOWERCASE: [a-z];
fragment UPPERCASE: [A-Z];
fragment NUMBER: [0-9];
如果我尝试解析 IF ANSWERED ( FirstName )
,我会得到以下输出:
[@0,0:10='IF ANSWERED',**<VARIABLE>**,1:0]
[@1,11:11='(',<'('>,1:11]
[@2,12:25='Execution date',<VARIABLE>,1:12]
[@3,26:26=')',<')'>,1:26]
[@4,27:26='<EOF>',<EOF>,1:27]
line 1:0 mismatched input 'IF ANSWERED' expecting 'IF'
我读到 Antlr4 是贪婪的,并试图匹配最大可能的标记,但我不明白什么是正确的方法,或者如何思考问题以找到解决方案。
正确:ANTLR 的词法分析器是贪婪的,并尝试尽可能多地消费。这就是为什么 IF ANSWERED
被标记为 TEXT
标记而不是 2 个单独的关键字。您需要更改 TEXT
使其不匹配空格。
像这样的东西可以让你开始:
parse
: command* EOF
;
command
: (ifStatement | variable)+
;
ifStatement
: IF ANSWERED '(' variable ')' command* END IF
;
variable
: TEXT
;
IF : 'IF';
END : 'END';
ANSWERED : 'ANSWERED';
TEXT : [a-zA-Z0-9]+;
SPACES : [ \t\r\n]+ -> skip;
我正在尝试在 Antlr4 中为一个简单的模板引擎实现一个语法。该引擎由 3 个不同的子句组成:
IF ANSWERED ( variable )
END IF
Variable
变量可以是任何大写或小写字母,包括空格。 IF ANSWERED
和 END IF
都是大写。
到目前为止,我已经编写了以下 grammar/lexer 规则,但我的问题是 IF ANSWERED
一直被识别为变量,而不是 2 个标记 IF
和 ANSWERED
.
grammar program;
/**grammar */
command: (ifStart | ifEnd | VARIABLE ) EOF;
ifStart: IF ANSWERED '(' VARIABLE ')';
ifEnd: 'END IF';
/** lexer */
IF: 'IF';
ANSWERED: 'ANSWERED';
TEXT: (LOWERCASE | UPPERCASE | NUMBER) ;
VARIABLE: (TEXT | [ \t\r\n])+;
fragment LOWERCASE: [a-z];
fragment UPPERCASE: [A-Z];
fragment NUMBER: [0-9];
如果我尝试解析 IF ANSWERED ( FirstName )
,我会得到以下输出:
[@0,0:10='IF ANSWERED',**<VARIABLE>**,1:0]
[@1,11:11='(',<'('>,1:11]
[@2,12:25='Execution date',<VARIABLE>,1:12]
[@3,26:26=')',<')'>,1:26]
[@4,27:26='<EOF>',<EOF>,1:27]
line 1:0 mismatched input 'IF ANSWERED' expecting 'IF'
我读到 Antlr4 是贪婪的,并试图匹配最大可能的标记,但我不明白什么是正确的方法,或者如何思考问题以找到解决方案。
正确:ANTLR 的词法分析器是贪婪的,并尝试尽可能多地消费。这就是为什么 IF ANSWERED
被标记为 TEXT
标记而不是 2 个单独的关键字。您需要更改 TEXT
使其不匹配空格。
像这样的东西可以让你开始:
parse
: command* EOF
;
command
: (ifStatement | variable)+
;
ifStatement
: IF ANSWERED '(' variable ')' command* END IF
;
variable
: TEXT
;
IF : 'IF';
END : 'END';
ANSWERED : 'ANSWERED';
TEXT : [a-zA-Z0-9]+;
SPACES : [ \t\r\n]+ -> skip;