我正在尝试解析 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 回答
你在CONTINUOUS_VALUE和IDENTIFIER之间有一些重叠(IDENTIFIER中的字符是CONTINUOUS_VALUE的一个子集 . 可能有几种方法可以解决这个问题 . 一种方法是用'='启动CONTINUOUS_VALUE然后将它从中删除在CSharp中,它看起来像这样:
然后从命令参数规则中取出'=' .
第二种方法是制作IDENTIFIER和CONTINUOUS_VALUE解析器规则(小写至少是第一个字母),然后你有上下文来确定哪一个应该匹配 . 你也许能够创建它们并在commandParam中引用它们,但是我不确定你是否可以嵌套片段,因为你已经有了ALL_WS片段 .
另外,你不需要在NameValue对之间使用某种分隔符吗?