我正在尝试编写一个野牛解析器,并且上下文优先级似乎不起作用......
我的一个作品(简化和省略c代码)如下:
'''constant_inner_expression : constant_expression t_PLUS op_attribute_instance_list constant_expression %prec BIN_APLUS | constant_expression t_MINUS op_attribute_instance_list constant_expression %prec BIN_AMINUS | constant_expression t_ASTERISK op_attribute_instance_list constant_expression %prec BIN_AMULT | constant_expression t_SLASH op_attribute_instance_list constant_expression %prec BIN_ADIV | constant_expression t_PERCENT op_attribute_instance_list constant_expression %prec BIN_AMOD | constant_expression t_ISEQUAL op_attribute_instance_list constant_expression %prec BIN_LEQUALS | constant_expression t_NISEQUAL op_attribute_instance_list constant_expression %prec BIN_LNEQUALS | constant_expression t_CISEQUAL op_attribute_instance_list constant_expression %prec BIN_CEQUALS | constant_expression t_NCISEQUAL op_attribute_instance_list constant_expression %prec BIN_CNEQUALS | constant_expression t_WISEQUAL op_attribute_instance_list constant_expression %prec BIN_WEQUALS | constant_expression t_NWISEQUAL op_attribute_instance_list constant_expression %prec BIN_WNEQUALS | constant_expression t_DOUBLEAMPERSAND op_attribute_instance_list constant_expression %prec BIN_LAND | constant_expression t_DOUBLEPIPE op_attribute_instance_list constant_expression %prec BIN_LOR | constant_expression t_DOUBLEASTERISK op_attribute_instance_list constant_expression %prec BIN_AEXP | constant_expression t_LT op_attribute_instance_list constant_expression %prec BIN_RLT | constant_expression t_LE op_attribute_instance_list constant_expression %prec BIN_RLE | constant_expression t_GT op_attribute_instance_list constant_expression %prec BIN_RGT | constant_expression t_GE op_attribute_instance_list constant_expression %prec BIN_RGE | constant_expression t_AMPERSAND op_attribute_instance_list constant_expression %prec BIN_BAND | constant_expression t_PIPE op_attribute_instance_list constant_expression %prec BIN_BOR | constant_expression t_CARET op_attribute_instance_list constant_expression %prec BIN_BXOR | constant_expression t_NEGCARET op_attribute_instance_list constant_expression %prec BIN_BXNOR | constant_expression t_RSHIFT op_attribute_instance_list constant_expression %prec BIN_LRSHIFT | constant_expression t_LSHIFT op_attribute_instance_list constant_expression %prec BIN_LLSHIFT | constant_expression t_ARSHIFT op_attribute_instance_list constant_expression %prec BIN_ARSHIFT | constant_expression t_ALSHIFT op_attribute_instance_list constant_expression %prec BIN_ALSHIFT | constant_expression t_IMPLICATION op_attribute_instance_list constant_expression %prec BIN_LIMPLICATION | constant_expression t_EQUIVALENCE op_attribute_instance_list constant_expression %prec BIN_LEQUIVALENCE
正如您所看到的,constant_inner_expression可以是两个constant_expressions之间的操作,我需要优先考虑其他一些。
我的优先规则如下:
%precedence RANGE_SEPARATOR
%precedence BIN_ASSIGNMENT BIN_INCASSIGN BIN_DECASSIGN BIN_TIMESASSIGN
BIN_DIVASSIGN BIN_MODASSIGN BIN_BANDASSIGN BIN_BXORASSIGN BIN_BORASSIGN
BIN_LLSHIFTASSIGN BIN_LRSHIFTASSIGN BIN_ALSHIFTASSIGN BIN_ARSHIFTASSIGN
%left BIN_LIMPLICATION BIN_LEQUIVALENCE
%left CONDITIONAL_OPERATOR
%left BIN_LOR
%left BIN_LAND
%left BIN_BOR
%left BIN_BXOR BIN_BXNOR
%left BIN_BAND
%left BIN_LEQUALS BIN_LNEQUALS BIN_CEQUALS BIN_CNEQUALS BIN_WEQUALS
BIN_WNEQUALS
%left BIN_RLT BIN_RGT BIN_RLE BIN_RGE
%left BIN_LLSHIFT BIN_LRSHIFT BIN_ALSHIFT BIN_ARSHIFT
%left BIN_APLUS BIN_AMINUS
%left BIN_AMULT BIN_ADIV BIN_AMOD
%left BIN_AEXP
%precedence UNARY_PLUS UNARY_MINUS UNARY_LNOT UNARY_LRNOT UNARY_LRAND
UNARY_LRNAND UNARY_LROR UNARY_LRNOR UNARY_LRXOR UNARY_LRXNOR UNARY_INC
UNARY_DEC
%precedence PARENTHESIS BRACKETS SCOPE DOT
当我尝试使用GLR算法解析一个表达式,例如2 + 3 * 5时,我得到一个歧义错误,因为GLR解析器创建了两个分支而其中没有分支。注意我并不是说应该用%dprec丢弃一个,只需要创建一个分支来开始。
另一方面,如果我用优先级上下文标记替换实际标记,例如,我用t_PLUS替换BIN_APLUS而用t_ASTERISK替换BIN_AMULT然后解析器工作正常并且可以构建像2 + 3 * 5这样的潜在模糊表达式正确。然而,由于我的令牌可能具有不同的含义和优先级,取决于上下文我真的需要避免这种方法...这导致我相信我的规则很好......
有没有人遇到类似的情况?
编辑: 正如里奇指出这个问题已在这个问题上提出: Happy Context-Dependent Operator Precedence
很抱歉,但在发布我之前没有找到它