ANTLR相当于野牛REJECT行动?

时间:2009-05-18 06:47:18

标签: antlr grammar bison

我正在尝试解析Name=Value对的列表,其中值可以包含除空格之外的任何内容(即值可以包含等号)。
该名称仅限于通常的标识符字符。

问题是,'Value'标记匹配所有内容。例如,输入:

dude=sweet

解析器会将整个输入与“值”标记匹配(并抛出MismatchedTokenException)。

bison 中,有可能将状态分配给令牌(或者这只是针对非终结符?),以便它们在显式转换到该状态后才“匹配”匹配。

编辑考虑到这一点,这在 bison 中也不起作用 - 已经发生了令牌拆分(在 flex 中);但是,我认为有一种方法可以 REJECT 令牌,迫使 flex 尝试第二好的匹配。

这是我的ANTLR语法。

grammar command_string;

start   
    :    commandParam* EOF
    ;
commandParam 
    :   IDENTIFIER '=' CONTINUOUS_VALUE 
    ;
IDENTIFIER 
    :   ('-'|'_'|'a'..'z'|'A'..'Z'|'0'..'9')+ 
    ;
CONTINUOUS_VALUE
    :   ~( ALL_WS )+
    ;
WS
    :   (ALL_WS) +      { $channel = HIDDEN; }
    ;
fragment ALL_WS     
    :   ' ' | '\t' | '\r' | '\n' 
    ;

1 个答案:

答案 0 :(得分:1)

你在CONTINUOUS_VALUE和IDENTIFIER之间有一些重叠(IDENTIFIER中的字符是CONTINUOUS_VALUE的子集。可能有几种方法可以解决这个问题。一种方法是用'='启动CONTINUOUS_VALUE然后去掉它在文本中。在CSharp中,它看起来像这样:

CONTINUOUS_VALUE
    :   '=' ~( ALL_WS )+ { Text = Text.Substring(1, Text.Length - 1); }
    ;

然后从命令参数规则中取出'='。

第二种方法是制作IDENTIFIER和CONTINUOUS_VALUE解析器规则(小写至少是第一个字母),然后你有上下文来确定哪一个应该匹配。您也许可以将它们作为片段并在commandParam中引用它们,但我不确定您是否可以嵌套片段,因为您已经拥有ALL_WS片段。

另外,你不需要在NameValue对之间使用某种分隔符吗?