我正在尝试解析ANTLR中的现有语言,该语言当前正在使用Ruby库Parslet进行解析。
这是我的语法的精简版:
grammar FilterMin;
filter : condition_set;
condition_set: condition_set_type (property_condition)?;
condition_set_type: '=' | '^=';
property_condition: property_lhs CONDITION_SEPARATOR property_rhs;
property_lhs: QUOTED_STRING;
property_rhs: entity_rhs | contains_rhs;
contains_rhs: CONTAINS_OP '(' contains_value ')';
contains_value: QUOTED_STRING;
entity_rhs: NOT_OP? MATCH_OP? QUOTED_STRING;
// operators
MATCH_OP: '~';
NOT_OP: '^';
CONTAINS_OP: 'contains';
QUOTED_STRING: QUOTE STRING QUOTE;
STRING: (~['\\])*;
QUOTE: '\'';
CONDITION_SEPARATOR: ':';
此解析无法使用相同的='foo':'bar'
或='foo':contains('bar')
来解析mismatched input ':' expecting ':'
和mismatched input ':contains(' expecting ':'
。
为什么这些输入不解析?
答案 0 :(得分:1)
您的STRING
规则匹配所有不是反斜杠或单引号的内容。因此,它与QUOTED_STRING
以外的所有其他词汇规则重叠。由于词法分析器将始终选择产生最长匹配项的规则,并且几乎总是STRING
,因此您的词法分析器将生成一堆STRING
标记,而不会产生任何CONDITION_SEPERATOR
标记。
由于您从未在解析器规则中使用STRING
,因此它不必是令牌的实际类型。实际上,您永远不希望生成STRING
令牌,只希望将其作为QUOTED_STRING
令牌的一部分进行匹配。因此,它应该是fragment
。