Parsing 错误的运算符优先于Happy

Parsing 错误的运算符优先于Happy,parsing,haskell,operator-precedence,happy,Parsing,Haskell,Operator Precedence,Happy,在Haskell中探索解析库时,我遇到了以下项目:。运行一些示例时,我发现运算符优先级有问题。使用Parsec时,它可以正常工作: $ echo "3*2+1" | dist/build/lambda-parsec/lambda-parsec Op Add (Op Mul (Num 3) (Num 2)) (Num 1) Num 7 但不是与Happy/Alex: $ echo "3*2+1" | dist/build/lambda-happy-alex/lambda-happy-alex O

在Haskell中探索解析库时,我遇到了以下项目:。运行一些示例时,我发现运算符优先级有问题。使用Parsec时,它可以正常工作:

$ echo "3*2+1" | dist/build/lambda-parsec/lambda-parsec
Op Add (Op Mul (Num 3) (Num 2)) (Num 1)
Num 7
但不是与Happy/Alex:

$ echo "3*2+1" | dist/build/lambda-happy-alex/lambda-happy-alex
Op Mul (Num 3) (Op Add (Num 2) (Num 1))
Num 9
尽管运算符优先级似乎定义得很好。摘自:

有什么提示吗?(我前段时间打开了一个,但没有回应)


[使用gch 7.6.3、alex 3.1.3、happy 1.19.4]

这似乎是haskell解析器示例使用令牌优先级的一个错误。Happy的运算符优先级仅影响直接使用令牌的规则。在解析器中,我们希望将优先级应用于
Expr
规则,但这是唯一适用的规则

| Expr op Expr { Op (opEnc $2) $1 $3 }
不使用令牌本身,而是依赖
opEnc
来扩展它们。如果
opEnc
内联到
Expr

| Expr '*' Expr { Op Mul $1 $3 }
| Expr '+' Expr { Op Add $1 $3 }
| Expr '-' Expr { Op Sub $1 $3 }

它应该可以正常工作。

我认为问题在于,即使为
+
-
*
/
定义了优先级,这些都不会影响生成的解析器。唯一适用的规则是
Expr op Expr
,因此基本上所有操作都具有相同的优先级。这可能是通过在
Expr
中使用运算符作为标记,而不是使用单独的
opEnc
规则来解决的。@JohnL您应该将其作为答案发布。
| Expr '*' Expr { Op Mul $1 $3 }
| Expr '+' Expr { Op Add $1 $3 }
| Expr '-' Expr { Op Sub $1 $3 }