【发布时间】:2014-08-14 07:32:11
【问题描述】:
在 Haskell 中探索解析库我遇到了这个项目:haskell-parser-examples。运行一些示例,我发现运算符优先级存在问题。使用 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
即使运算符的优先级看起来定义明确。摘自parser:
%left '+' '-'
%left '*' '/'
%%
Exprs : Expr { $1 }
| Exprs Expr { App $1 $2 }
Expr : Exprs { $1 }
| let var '=' Expr in Expr end { App (Abs $2 $6) $4 }
| '\\' var '->' Expr { Abs $2 $4 }
| Expr op Expr { Op (opEnc $2) $1 $3 }
| '(' Expr ')' { $2 }
| int { Num $1 }
有什么提示吗? (前段时间我开了一个bug report,但没有回应)。
[使用 gch 7.6.3,alex 3.1.3,happy 1.19.4]
【问题讨论】:
-
我认为问题在于,即使为
+、-、*和/定义了优先级,它们根本不会影响生成的解析器。唯一适用的规则是Expr op Expr,因此基本上所有操作都具有相同的优先级。这可以通过在Expr中使用运算符作为标记来解决,而不是使用单独的opEnc规则。 -
@JohnL 您应该将其发布为答案。
标签: parsing haskell operator-precedence happy