5

我为一种理解 C 风格单行注释的小语言编写了一个语法,例如。

  // this is a comment

这是我为这种语言编写的语法片段,使用 antlr v3.0.1

  SINGLELINE_COMMENT
:   '/' '/' (options {greedy=false;} : ~('\r' | '\n'))* ('\r' | '\n' )+ {$channel=HIDDEN;};

  WS      :      (' '|'\r'|'\t'|'\u000C'|'\n')+ {$channel=HIDDEN;};

这几乎是一种工作,除了当注释在脚本中最后并且没有终止 NL/CR 时,我从 antlr 收到一条烦人的消息(在运行时):

 line 1:20 required (...)+ loop did not match anything at character '<EOF>'

我怎样才能摆脱这个消息?我尝试将EOF令牌添加到(..)+表达式中,但这不起作用。

4

2 回答 2

4

您不需要该greedy=...选项:当您拥有.*.+在您的规则中时,您通常需要它。而且由于您已经在规则中的隐藏通道上放置了换行符WS,您可以将其从您的SINGLELINE_COMMENT:

SINGLELINE_COMMENT
 : '//' ~('\r' | '\n')* {$channel=HIDDEN;}
 ;

WS 
 : (' '|'\r'|'\t'|'\u000C'|'\n')+ {$channel=HIDDEN;}
 ;
于 2012-12-08T09:11:50.987 回答
3

一般来说,解决“没有终止的 NL”问题会涉及到很多曲折的语法更改以适应这种边缘条件。只在输入流的末尾添加一个 NL 总是更简单,这意味着您可以保证有一个终止的 NL 而不必担心语法中的它。UNIX 在这方面是正确的,而 Windows 则不然。

不是针对您的特定问题的解决方案,而是您最初编码规则的方式暴露了这个问题。

于 2012-12-10T03:18:59.753 回答