我'm extending a JavaScript ANTLR grammar that uses the C target to handle JScript'的条件编译注释,即 /*@cc_on ... @*/ .

这些需要与正常的块注释分开处理,因为 /*@cc_on /* hello */ @*/ 会导致单个条件编译注释延伸到第二个注释结束标记 .

我从熟悉的词法分析器规则开始:

Comment
  : '/' '*' (options {greedy=false;} : .)* '*' '/' { $channel=HIDDEN; }
  ;

我正在添加一个新的词法分析器规则来使用条件编译块:

Comment
  : '/' '*@cc_on' (options {greedy=false;} : .)* '@*' '/' { $channel=HIDDEN; }
  | '/' '*' (options {greedy=false;} : .)* '*' '/' { $channel=HIDDEN; }
  ;

当生成的词法分析器看到条件编译打开 /*@cc_on 但在文件的其余部分找不到结束语句 @*/ 时,它就会这样做 - 看起来当它看到 /*@cc_cond 时它会扫描文件的其余部分 @*/ 并抛出当它找不到它而不是回溯时出错 .

因此,解析

var a = /*@cc_on /* ends here */ 1, b = 2

投掷而不是成功:(错误打印代码是我的,可能是错误的,我相信在这种情况下它应该指向 2

Lexer Error: <input>(1) : error 1 : Unexpected character, Line: 1, Col: 40, Token Text: <<</*@cc_on /* ends here */ 1, b = 2>>>
Lexer Error location:
var a = /*@cc_on /* ends here */ 1, b = 2
----------------------------------------^

Parser Error: -end of input-(1) : error 3 : , at offset -1 , at <EOF>
 : cannot match to any predicted input...

如何编辑我的评论规则以获得我需要的行为?语法已经 backtrack=true .

编辑:添加 options { backtrack=true; k=1; } 到规则就行了 . 为什么呢? backtrack 已经为整个语法启用了 .