使用ANTLR3解析换行符EOF作为语句结束标记

| 我的问题是关于在ANTLRWorks中运行以下语法:
INT :(\'0\'..\'9\')+;
SEMICOLON: \';\';
NEWLINE: (\'\\r\\n\'|\'\\n\'|\'\\r\');
STMTEND: (SEMICOLON (NEWLINE)*|NEWLINE+);

statement
    : STMTEND
    | INT STMTEND
    ;

program: statement+;
无论选择哪个换行NL(CR / LF / CRLF)或整数,我都可以通过以下输入(以程序作为开始规则)获得以下结果: \“; NL \”或\“ 32; NL \”解析没有错误。 \“; \”或\“ 45; \”(不包含换行符)会导致EarlyExitException。 \“ NL \”本身解析没有错误。 \“ 456 NL \”(不带分号)将导致MismatchedTokenException。 我想要的是一个语句以换行符,分号或分号后跟换行符来终止,并且我希望解析器在终止符上能吃掉尽可能多的连续换行符,因此“ ;; NL NL NL NL \”只是一个终止,而不是四个或五个。另外,我希望文件结尾的情况也可以是有效的终止,但是我还不知道该怎么做。 那么这是怎么回事,如何使它在EOF终止呢?我对解析,ANTLR和EBNF完全陌生,并且在简单的计算器示例和参考之间的某个水平上,我还没有发现太多要阅读的材料(我有The Definitive ANTLR Reference,但这确实是参考,我可以从ANTLRWorks之外的其他地方快速入门,所以任何阅读建议(除了Wirth的1977 ACM论文)也将有所帮助。谢谢!     
已邀请:
在输入诸如“ 1”或“ 2”的情况下,将永远不会创建令牌“ 3”。
\";\"
将创建一个令牌:
SEMICOLON
\"45;\"
将产生:
INT SEMICOLON
。 您(可能)想要的是
SEMICOLON
NEWLINE
从未真正成为真实代币,但它们始终是
STMTEND
。您可以通过使其成为所谓的“片段”规则来做到这一点:
program: statement+;

statement
 : STMTEND
 | INT STMTEND
 ;

INT     : \'0\'..\'9\'+;
STMTEND : SEMICOLON NEWLINE* | NEWLINE+;

fragment SEMICOLON : \';\';
fragment NEWLINE   : \'\\r\' \'\\n\' | \'\\n\' | \'\\r\';
片段规则仅可用于其他词法分析器规则,因此它们永远不会以解析器(生产)规则结尾。要强调的是:上面的语法只会创建
INT
STMTEND
令牌。     

要回复问题请先登录注册