使用Antlr解析单行C风格注释

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 标记,但这并没有起作用。

我不确定,但如果将换行符变为可选的,即将“+”改为“?”或者“*”,会发生什么呢? - nijoakim
不如去掉贪婪选项(它们似乎只适用于+),并将加号改为问号,您觉得怎么样? - Joop Eggen
2个回答

4
您不需要使用greedy=...选项:通常只有在规则中使用.*.+时才需要使用它。并且由于您已经在WS规则中将换行符放在了隐藏通道中,因此可以将其从SINGLELINE_COMMENT规则中删除:
SINGLELINE_COMMENT
 : '//' ~('\r' | '\n')* {$channel=HIDDEN;}
 ;

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

3

通常,解决“没有终止的NL”问题需要进行很多曲折的语法更改,以满足这种边缘条件。只需在输入流的末尾添加一个NL即可,这样您就可以确保有一个终止的NL,而不必担心语法问题。在这方面,UNIX是正确的,而Windows则不是。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接