1

我有一个简单的语法试图解析两种类型的文本,该行以“#include”和其他开头。这是我的语法:

cmds
    : cmd+
    ;

cmd
    : include_cmd |  other_cmd
    ;

include_cmd
    : INCLUDE  DOUBLE_QUOTE  FILE_NAME  DOUBLE_QUOTE
    ;

other_cmd
    : (~'#')+
    ;


INCLUDE
    : '#include'
    ;

DOUBLE_QUOTE
    : '"'
    ;

FILE_NAME
    : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')+
    ;

New_Line 
    : ('\r' | '\n')+   
    ;

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

但我收到这样的警告:

Decision can match input such as "INCLUDE DOUBLE_QUOTE FILE_NAME DOUBLE_QUOTE" using multiple alternatives: 1, 2

As a result, alternative(s) 2 were disabled for that input

我不知道如何解释这个警告。其中的示例“INCLUDE DOUBLE_QUOTE FILE_NAME DOUBLE_QUOTE”应该只匹配 include_cmd,因为“other_cmd”不以“#”开头。

你能帮忙看看这里发生了什么吗?

我正在使用antlr3.4。

更新 - 感谢 graydet 的建议,在将 other_cmd 规则更改为 (~INCLUDE)+ 后,该警告消失了。但实际上还有另一个警告,

Decision can match input such as "{DOUBLE_QUOTE..FILE_NAME, New_Line..WS}" using multiple alternatives: 1, 2

As a result, alternative(s) 2 were disabled for that input

现在我猜这是因为双引号可以同时匹配 other_cmd 规则和 DOUBLE_QUOTE 规则,但我想在这里,一个是解析器规则,另一个是词法分析器规则,这个警告有意义吗?我根本不能使用 DOUBLE_QUOTE,而是直接在解析器规则 include_cmd 中使用“,但这并不容易阅读。

任何帮助清除此警告?

一个附带问题 - 警告消息只是说替代 1,2,但我并不清楚什么是 1,什么是 2,有没有办法让 antlr 提供更直接的替代方案?

4

1 回答 1

1

other_cmd规则将匹配每个不以标记开头的标记序列#
该规则将匹配以标记include_cmd开头的序列。#include

由于##include是两个不同的标记,因此以标记开头的标记序列#include匹配两个规则。

尝试以下规则:

other_cmd
    : (~INCLUDE)+
    ;
于 2013-02-01T16:44:54.603 回答