ANTLR4 匹配词法分析器规则而不是解析器规则

问题描述 投票:0回答:1

这是我简短的 ANTLR4 语言:

grammar test;

prog: (decl | expr)+
;
decl: doc | quiz
;

doc: '%doc' paramlist
;

quiz: '%quiz' paramlist STR? '%quiz' ENDL
;
paramlist: '(' VAR '=' PARAMVAL {, VAR '=' PARAMVAL}')'
;
expr:expr '\*' expr
|expr '+' expr
|expr '-' expr
|DOC
;

// tokens
DOC: 'doc';
PERCENT: '%';
VAR:  \[a-zA-Z\_\]\[a-zA-Z0-9\_\]\* ;
PARAMVAL: \[^,\]+|'"'\[^"\]\*'"' ;
STR: (\~\["\\\\r\\n\] | EscapeSequence)+ ;
fragment EscapeSequence:
'\\' 'u005c'? \[btnfr"'\\\]
| '\\' 'u005c'? (\[0-3\]? \[0-7\])? \[0-7\]
| '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit;
fragment HexDigit: \[0-9a-fA-F\];
ENDL: '\n' ;
WS: [ \t\n]+ -> skip;

为了使用 doc 解析器规则,我编写了“%doc”,ANTLR 根据此屏幕截图识别它。

%doc

但是,当我尝试填写缺失的 PARAMVAL 时,解析树会将所有内容识别为 STR。

%doc(
%doc(v=^)

与测验相同的情况。
%quiz
%quiz(

当您在 STR 规则周围添加分隔符时,它会起作用。不过,我想使用不带分隔符的 STR 规则。

为什么当任何解析器规则都没有使用 STR 时,STR 规则却被识别? (除了测验,但这恰恰是规则的中间部分。

parsing antlr antlr4 grammar lexer
1个回答
0
投票

正如评论中的500 - 内部服务器错误所提到的:词法分析器独立于解析器工作。词法分析器遵循 2 条规则:

  1. 尝试为词法分析器规则消耗尽可能多的字符
  2. 当 2 个(或更多)词法分析器规则匹配相同字符时,让第一个定义的规则“获胜”

由于第一条规则,很明显输入

"%doc(v=^)"
变成了
STR
标记。

其他一些不正确的事情,或者工作方式与您想象的不同:在解析器规则中定义文字标记时,ANTLR 会自动创建词法分析器规则。这意味着如果您这样做:

doc
 : '%doc' paramlist
 ;

DOC     : 'doc';
PERCENT : '%';

ANTLR 将在幕后创建此内容:

doc
 : T__0 paramlist
 ;

T__0    : '%doc';
DOC     : 'doc';
PERCENT : '%';

并且由于规则 1,输入“%doc”将始终成为

T__0
标记,而永远不会成为
PERCENT
DOC
标记。

此外,

[^,]
不匹配逗号以外的任何字符:它匹配
^
,
。您的意思可能是
~[,]
。但要小心:执行
~[,]+
会再次(如
STR
)匹配太多字符。

© www.soinside.com 2019 - 2024. All rights reserved.