首页 文章

ANTLR相当于野牛REJECT行动?

提问于
浏览
0

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

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

dude=sweet

解析器将 whole 输入与'Value'令牌匹配(并抛出 MismatchedTokenException ) .

在野牛中,有可能将状态分配给令牌(或者这只是针对非终结符号?),以便它们在显式转换到该状态后才会成为匹配的'eligible' .

编辑思考它,这也不适用于野牛 - 令牌分裂已经发生(在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 回答

  • 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对之间使用某种分隔符吗?

相关问题