Parsing bison/yacc语法消歧

Parsing bison/yacc语法消歧,parsing,compiler-construction,yacc,bison,lalr,Parsing,Compiler Construction,Yacc,Bison,Lalr,我有以下野牛语法(作为更复杂语法的一部分): 表达方式: 标识符 |常数 |LAMBDA匹配块 ; 匹配块: 模式“=”表达式 |匹配_块“|”模式“=”表达式 ; 模式: 标识符 |常数 ; 其中描述了包含标识符、常量和lambda函数的表达式,并使用模式匹配,如下所示: lambda 0=1 | 1 = 2 |x=x 问题是1个移位/减少冲突,由嵌套匹配的歧义引起,如下例所示: λ0=1 |x=λ1=2 |y=4 规则是匹配块和最近的函数相关,如上面示例中的缩进所示 我的问题是-如何

我有以下野牛语法(作为更复杂语法的一部分):

表达方式:
标识符
|常数
|LAMBDA匹配块
;
匹配块:
模式“=”表达式
|匹配_块“|”模式“=”表达式
;
模式:
标识符
|常数
;
其中描述了包含标识符、常量和lambda函数的表达式,并使用模式匹配,如下所示:
lambda 0=1
| 1 = 2
|x=x
问题是1个移位/减少冲突,由嵌套匹配的歧义引起,如下例所示:

λ0=1
|x=λ1=2
|y=4
规则是匹配块和最近的函数相关,如上面示例中的缩进所示


我的问题是-如何重写此语法以消除这种歧义(不使用%left%right yacc指令)?

如果您总是希望
绑定到最近的
LAMBDA
,这基本上只是意味着在
match_块的最后一个
子句中只能有
LAMBDA

non_lambda_expression:
    IDENTIFIER
    | CONST
;
expression:
    non_lambda_expression
    | LAMBDA match_block
;
non_lambda_match_block:
    pattern '=' non_lambda_expression
    | non_lambda_match_block '|' pattern '=' non_lambda_expression
;
match_block:
    pattern '=' expression
    | non_lambda_match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;

基本上,您可以将
expression
match_block
分为两个版本,一个允许lambdas,另一个不允许lambdas,并在每个位置使用适当的版本以避免歧义。

非常感谢!我在前面的《龙书》中看到了一个消除歧义的例子(对于“悬挂的其他”)但我不能用这个语法来做。@SJ:这与悬挂的其他语法基本上是相同的模式——上面的转换与《龙书》描述的相同,唯一的区别是在最终lambda之前可能有多个非lambda match_块 lambda 0 = 1 | 1 = 2 | x = x lambda 0 = 1 | x = lambda 1 = 2 | y = 4
non_lambda_expression:
    IDENTIFIER
    | CONST
;
expression:
    non_lambda_expression
    | LAMBDA match_block
;
non_lambda_match_block:
    pattern '=' non_lambda_expression
    | non_lambda_match_block '|' pattern '=' non_lambda_expression
;
match_block:
    pattern '=' expression
    | non_lambda_match_block '|' pattern '=' expression
;
pattern:
    IDENTIFIER
    | CONST
;