You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell中有理数与算术表达式二元运算Parser实现问题

问题核心原因

  1. 分支匹配顺序错误:你的term定义中把Lit <$> rational放在了乘法匹配分支前面,Parsec的<|>运算符是左优先的,只要前面的分支匹配成功就会直接返回结果,不会向后尝试其他分支。你解析10/1 * x时,10/1作为合法Rational匹配到了Lit分支,解析器直接返回结果,不会检查后面的*和x。
  2. 不需要修改现有数据结构,也不需要调整运算符表,只要调整分支顺序就能解决问题。

修复方案

仅需调换term中乘法分支和Lit分支的顺序,保留原有所有逻辑不变:

aexp :: Parser AExp
aexp = buildExpressionParser table term 
 where term =  -- 优先匹配「系数 * 表达式」结构,匹配失败再回退到纯字面量解析
               try ((:*:) <$> (rational <* reservedOp "*") <*> aexp)
           <|> Lit  <$> rational
           <|> Var <$> identifier
           <|> try (parens aexp)
       table = [ [ binary "+" (:+:)]]

验证结果

修复后运行测试用例:

Main>regularParse aexp "10/1 * x"
Right (10 % 1 :*: Var "x")

符合预期,同时纯字面量、加法、括号表达式的解析逻辑不受影响。

扩展说明

如果后续需要支持更复杂的嵌套乘法场景(比如2/1 * (3/1 * x + 1/1)),现有逻辑已经天然支持,不需要额外修改,因为乘法分支的右操作数直接调用了aexp解析器,可以匹配任意合法的线性表达式。

内容的提问来源于stack exchange,提问作者Shenkok Kotoro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 20:57:03