我尝试编写一个语法来逐行解析文件。
我的语法看起来像这样:
grammar simple;
parse: (line NL)* EOF
line
: statement1
| statement2
| // empty line
;
statement1 : KW1 (INT|FLOAT);
statement2 : KW2 INT;
...
NL : '\r'? '\n';
WS : (' '|'\t')-> skip; // toss out whitespace
如果输入文件中的最后一行不有换行符,我会收到以下错误消息:
line xx:37 missing NL at <EOF>
有人可以解释一下,如何编写一个实际上接受最后一行而没有换行的语法
答案 0 :(得分:1)
在最后NL
之后,不要求line
失败。此表单是有效的,并且基于line
可以匹配空序列(基本上是最后line
将总是为空行)的事实进行简化。
// best if `line` can be empty
parse
: line (NL line)* EOF
;
如果不允许line
为空,则以下规则有效并执行相同的操作:
// best if `line` cannot be empty
parse
: (line (NL line)* NL?)? EOF
;
以下规则与line
不能为空但效率低得多的情况相同。我之所以包含它是因为我经常看到人们在这种形式下编写规则,很容易看出,作为可选项的特定NL
令牌是最后一个line
之后的令牌
// INEFFICIENT!
parse
: (line NL)* (line NL?)? EOF
;