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

如何用Parsec在Haskell中解析Python式链式运算符?

使用Parsec解析链式表达式的可行性问题

我当前项目用Parsec构建表达式解析器,核心的运算符表代码如下:

opTable :: [[Operator Parser Expr]]
opTable =
  [ 
    -- ...
    [ InfixL $ binary (ArithOp . Exp) TokExp ]
  , [ InfixL $ binary (ArithOp . Mod) TokMod
    , InfixL $ binary (ArithOp . Mul) TokMul
    , InfixL $ binary (ArithOp . Div) TokDiv
    ]

  , [ InfixL $ binary (ArithOp . Add) TokAdd
    , InfixL $ binary (ArithOp . Sub) TokSub
    ]

  , [ InfixL $ binary (ArithOp . Max) TokMax
    , InfixL $ binary (ArithOp . Min) TokMin
    ]

    -- =
  , [ InfixL $ binary (ChainOp . EQ) TokEQ
    -- ~, <, <=, >, >=
    , InfixL $ binary (ChainOp . NEQ) TokNEQ
    , InfixL $ binary (ChainOp . NEQU) TokNEQU
    , InfixL $ binary (ChainOp . LT) TokLT
    , InfixL $ binary (ChainOp . LTE) TokLTE
    , InfixL $ binary (ChainOp . LTEU) TokLTEU
    , InfixL $ binary (ChainOp . GT) TokGT
    , InfixL $ binary (ChainOp . GTE) TokGTE
    , InfixL $ binary (ChainOp . GTEU) TokGTEU
    ]

    -- &&
  , [ InfixL $ binary (ArithOp . Conj) TokConj
    , InfixL $ binary (ArithOp . ConjU) TokConjU
    -- ||
    , InfixL $ binary (ArithOp . Disj) TokDisj
    , InfixL $ binary (ArithOp . DisjU) TokDisjU
    ]
    -- =>
  , [ InfixR $ binary (ArithOp . Implies) TokImpl
    , InfixR $ binary (ArithOp . ImpliesU) TokImplU
    -- <=>
    , InfixL $ binary (ChainOp . EQProp) TokEQProp
    , InfixL $ binary (ChainOp . EQPropU) TokEQPropU
    ]
  ]

说明:

  • 存在ArithOp和ChainOp两类运算符:
    • ArithOp是常规运算符
    • ChainOp是Python式链式运算符(支持a <= b < c这类写法),包含TokLT(<)、TokEQProp(<=>)等类型
  • 问题在于ArithOp与ChainOp的优先级是相互交错的

我希望将表达式解析为如下结构的语法树:

data Expr
  = Lit Lit
  | Var Name
  | Op Op
  | App Expr Expr
  | Chain Chain
  -- ...

-- ...

data Chain = Pure Expr | Ch Chain Op Expr

例如表达式1 <= 1 + 1 < 3应解析为:

Ch (
  Ch (
    Lit 1
  )
  ( Op "<=")
  (
    App (
      App (Op "+" ) (Lit 1)
    )
    (Lit 1)
  )
)
(Op "<")
(Lit 3)

(已省略部分构造器)

我想知道:能否基于现有的Parsec表达式解析器(即上述运算符表的方式)构建出这种带链式结构的语法树?我知道可以手动编写分层解析器,但用现有框架会更简便。之前尝试过chainl组合子,但似乎无法生成目标Chain结构。如果不可行,我就手动实现。


内容的提问来源于stack exchange,提问作者盛安安

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:51:11