2011-05-24 81 views
1

我具有以下野牛语法(如更复杂的语法的一部分): 野牛/ yacc语法消歧

 
expression: 
    IDENTIFIER 
    | CONST 
    | LAMBDA match_block 
; 
match_block: 
    pattern '=' expression 
    | match_block '|' pattern '=' expression 
; 
pattern: 
    IDENTIFIER 
    | CONST 
; 
,其描述了含有标识符,常量以及与模式匹配,它看起来像这样λ-函数的表达式:
lambda 0 = 1 
    | 1 = 2 
    | x = x
问题是由嵌套匹配引起的歧义性引起的1个移位/减少冲突,如以下示例所示:
 
lambda 0 = 1 
    | x = lambda 1 = 2 
       | y = 4 
规则是匹配块与最接近的函数相关,如上面示例中的缩进所示。

我的问题是 - 我怎样才能重写这个语法来消除这种模糊性(不使用%left%right yacc指令)?

回答

2

如果你总是希望|绑定到最接近LAMBDA,基本上只是意味着你只能在最后|子句match_block中有一个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 
; 

基本上,你分割expressionmatch_block分成两个版本 - 一个允许lambdas和一个不 - 并在每个地方使用适当的一个以避免模糊。

+0

非常感谢!我看到龙书中早些时候消除歧义的一个例子(“dangling else”),但是我无法用这个语法来完成。 – 2011-05-25 10:30:16

+0

@SJ:这个模式与悬空其他模式基本完全相同 - 上面的转换与Dragon Book描述的相同,唯一的区别是在最后一个lambda之前可能会有多个非lambda match_blocks – 2011-05-25 22:20:44