繁体   English   中英

ANTLR4 空白处的令牌识别

[英]ANTLR4 Token recognition at whitespace

我是使用 ANTLR 解析器的新手。

这是我的语法:

grammar Commands;

file_ : expression EOF;
expression : Command WhiteSpace Shape ;

WhiteSpace : [\t]+ -> skip;
NewLine : ('\r'?'\n'|'\r') -> skip;
Shape : ('square'|'triangle'|'circle'|'hexagon'|'line');
Command : ('fill'|'draw'|'delete');

我正在尝试解析句子列表,例如:

draw circle;
draw triangle;
delete circle;

我越来越

token recognition error at:' '

谁能告诉我有什么问题? PS:我在 java 15 工作

更新

file_ : expressions EOF;
expressions 
            : expressions expression
            | expression 
            ;
expression : Command WhiteSpace Shape NewLine ;

WhiteSpace : [\t]+ -> skip;
NewLine : ('\r'?'\n'|'\r') -> skip;
Shape : ('square'|'triangle'|'circle'|'hexagon'|'line');
Command : ('fill'|'draw'|'delete');

添加了对多个表达式的支持。 我遇到了同样的错误。

更新

grammar Commands;

file_ : expressions EOF;
expressions
            : expressions expression
            | expression
            ;
expression : Command Shape;

WhiteSpace : [\t]+ -> skip;
NewLine : ('\r'?'\n'|'\r') -> skip;
Shape : ('square'|'triangle'|'circle'|'hexagon'|'line');
Command : ('fill'|'draw'|'delete');

即使我不包括 WhiteSpace,我也会收到相同的令牌识别错误。

好的,错误:

line 3:6 token recognition error at: ' '
line 3:13 token recognition error at: ';'

表示词法分析器遇到了空白字符(或分号),但没有匹配任何这些字符的词法分析器规则。 您必须将它们包含在您的语法中。 假设您像这样添加它们(注意:仍然不正确:):

Semi       : ';';
WhiteSpace : [ \t]+ -> skip;

尝试使用上述规则时,您会收到错误消息:

line 1:5 missing WhiteSpace at 'circle'

这意味着解析器无法匹配规则expression: Command WhiteSpace Shape; 到输入draw circle; . 这是因为在词法分析器中,您将skip ping 所有空白字符。 这意味着这些标记在解析器规则中不可用。 从解析器中删除它们。

您还会看到错误:

line 1:11 mismatched input ';' expecting <EOF>

这意味着输入包含一个Semi标记,而解析器没有预料到这一点。 expression规则中包含Semi标记:

grammar Commands;

file_ : expression EOF;
expression : Command Shape Semi;

Semi : ';';
WhiteSpace : [ \t]+ -> skip;
NewLine : ('\r'?'\n'|'\r') -> skip;
Shape : ('square'|'triangle'|'circle'|'hexagon'|'line');
Command : ('fill'|'draw'|'delete');

上面的语法适用于单个表达式。 如果你想匹配多个表达式,你可以这样做:

expressions
            : expressions expression
            | expression
            ;

但鉴于 ANTLR 生成LL 解析器(不是 ANTLR 名称所暗示的 LR) ,这样做更容易(并使解析树更容易在以后遍历):

expressions
 : expression+
 ;

如果您要跳过所有空白字符,您不妨删除NewLine规则并执行以下操作:

WhiteSpace : [ \t\r\n]+ -> skip;

还有一件事,词法分析器现在创建了具有相同类型的ShapeCommand标记。 我会做这样的事情:

shape    : Square | Triangle | ...;

Square   : 'square';
Triangle : 'triangle';
...

当您想要评估输入时(如果这是您要做的),这将使您在遍历解析树时更轻松。

我想 go 是这样的:

grammar Commands;

file_       : expressions EOF;
expressions : expression+;
expression  : command shape Semi;
shape       : Square | Traingle | Circle | Hexagon | Line;
command     : Fill | Draw | Delete;

Semi        : ';';
WhiteSpace  : [ \t\r\n]+ -> skip;
Square      : 'square';
Traingle    : 'triangle';
Circle      : 'circle';
Hexagon     : 'hexagon';
Line        : 'line';
Fill        : 'fill';
Draw        : 'draw';
Delete      : 'delete';

您的空白标记规则WhiteSpace仅允许制表符。 给它加一个空格。

WhiteSpace : [ \t]+ -> skip;

(通常,空格规则不止于此,但它应该可以解决您的直接问题。

你也没有考虑到';' 在您的输入中。 要么将其添加到规则中,要么暂时从测试输入中删除。

expression : Command Shape ';' ;

这可以解决它,但似乎它可能不是你真正需要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM