二元运算符解析的输入不匹配
Mismatched input with binary operator parsing
我正在尝试使用 Ruby 库 Parslet 解析 ANTLR 中的现有语言。
这是我的语法的精简版:
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 ':'
。
为什么这些输入没有被解析?
您的 STRING
规则匹配反斜杠或单引号以外的所有内容。所以它与除 QUOTED_STRING
之外的所有其他词法规则重叠。由于词法分析器将始终选择产生最长匹配的规则并且几乎总是 STRING
,因此您的词法分析器将产生一堆 STRING
个标记,而不会产生任何 CONDITION_SEPERATOR
个标记。
由于您从不在解析器规则中使用 STRING
,因此它不需要是实际类型的标记。事实上,您永远不想生成 STRING
标记,您只希望它作为 QUOTED_STRING
标记的一部分进行匹配。因此它应该是 fragment
.
我正在尝试使用 Ruby 库 Parslet 解析 ANTLR 中的现有语言。
这是我的语法的精简版:
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 ':'
。
为什么这些输入没有被解析?
您的 STRING
规则匹配反斜杠或单引号以外的所有内容。所以它与除 QUOTED_STRING
之外的所有其他词法规则重叠。由于词法分析器将始终选择产生最长匹配的规则并且几乎总是 STRING
,因此您的词法分析器将产生一堆 STRING
个标记,而不会产生任何 CONDITION_SEPERATOR
个标记。
由于您从不在解析器规则中使用 STRING
,因此它不需要是实际类型的标记。事实上,您永远不想生成 STRING
标记,您只希望它作为 QUOTED_STRING
标记的一部分进行匹配。因此它应该是 fragment
.