在
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,快乐1.19.4]
最佳答案 这似乎是haskell-parser-examples使用令牌优先级的一个错误. 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 }
它应该正常工作.