ANTLR4识别空白处的标记
ANTLR4识别空白处的标记
我对使用ANTLR解析器的工作还不熟悉。\n这是我的语法:\ngrammar Commands;\nfile_ : expression EOF;\nexpression : Command WhiteSpace Shape ;\nWhiteSpace : [\\t]+ -> skip;\nNewLine : (\'\\r\'?\'\\n\'|\'\\r\') -> skip;\nShape : (\'square\'|\'triangle\'|\'circle\'|\'hexagon\'|\'line\');\nCommand : (\'fill\'|\'draw\'|\'delete\');\n
\n我试图解析一系列类似的句子:\ndraw circle;\ndraw triangle;\ndelete circle;\n
\n我得到的错误是:\n
在' '处出现了令牌识别错误
\n有人能告诉我问题出在哪里吗?\n附:我使用的是Java 15。\n
更新
\nfile_ : expressions EOF;\nexpressions \n : expressions expression\n | expression \n ;\nexpression : Command WhiteSpace Shape NewLine ;\nWhiteSpace : [\\t]+ -> skip;\nNewLine : (\'\\r\'?\'\\n\'|\'\\r\') -> skip;\nShape : (\'square\'|\'triangle\'|\'circle\'|\'hexagon\'|\'line\');\nCommand : (\'fill\'|\'draw\'|\'delete\');\n
\n增加了对多个表达式的支持。\n我得到了相同的错误。\n
更新
\ngrammar Commands;\nfile_ : expressions EOF;\nexpressions\n : expressions expression\n | expression\n ;\nexpression : Command Shape;\nWhiteSpace : [\\t]+ -> skip;\nNewLine : (\'\\r\'?\'\\n\'|\'\\r\') -> skip;\nShape : (\'square\'|\'triangle\'|\'circle\'|\'hexagon\'|\'line\');\nCommand : (\'fill\'|\'draw\'|\'delete\');\n
\n即使我不包含WhiteSpace,我仍然得到相同的令牌识别错误。
ANTLR4 Token recognition at whitespace问题的出现原因是因为在代码中的Whitespace规则只允许使用制表符(tabs),而没有包括空格。这导致在识别空格时出现了问题。解决方法是在Whitespace规则中添加一个空格。
具体的解决方法是将原来的Whitespace规则代码修改为:WhiteSpace : [ \t]+ -> skip;
。这样就允许代码中出现空格,并且识别时会忽略空格。
除了上述问题,还存在一个问题是输入中的';'没有被正确识别。为了解决这个问题,可以将';'符号添加到一个规则中,或者在测试输入中暂时删除这个符号。
例如,可以将原来的expression规则修改为:expression : Command Shape ';' ;
。这样就可以正确识别输入中的';'符号。
要解决ANTLR4 Token recognition at whitespace问题,需要在Whitespace规则中添加空格,并且将';'符号添加到相应的规则中。这样就可以正确识别空格和';'符号,解决这个问题。
ANTLR4 Token recognition at whitespace问题的原因是词法分析器遇到了空格字符或分号,但是没有与这些字符匹配的词法规则。解决方法是在语法中添加相应的规则来匹配这些字符,并根据需要进行skip。
首先,将分号和空格字符添加到语法中:
Semi : ';';
WhiteSpace : [ \t]+ -> skip;
然后,你会遇到错误提示缺少WhiteSpace:
line 1:5 missing WhiteSpace at 'circle'
这是因为在词法分析器中,你使用了skip来忽略所有的空格字符,所以这些token在语法规则中不可用。从语法规则中删除它们。
然后,你会看到以下错误提示:
line 1:11 mismatched input ';' expecting
这意味着输入中包含了一个Semi token,而解析器并不期望它。在expression规则中包含Semi token:
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;
另外,词法分析器现在创建具有相同类型的Shape和Command token。可以使用以下方法进行改进:
shape : Square | Triangle | ...; Square : 'square'; Triangle : 'triangle'; ...
最终,完整的语法可以是这样的:
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';