« Home

Appendix. 其他 expression combinator [cs-000F]

在這裏提到的所有程式都實作在我幫 lean 寫的一個解析器擴充程式庫 https://git.sr.ht/~dannypsnl/parsec-extra

右結合的 infix

partial def infixR (opList : List (Parsec (α → α → α))) (tm : Parsec α)
  : Parsec α := go #[]
  where
  go (ls : Array (α × (α → α → α))) : Parsec α := do
    let lhs ← tm
    for findOp in opList do
      match ← tryP findOp with
      | .some f => return ← go (ls.push (lhs, f))
      | .none => continue
    let rhs := lhs
    return ls.foldr (fun (lhs, bin) rhs => bin lhs rhs) rhs

prefix op tm

def «prefix» (opList : List $ Parsec (α → α)) (tm : Parsec α)
  : Parsec α := do
  let mut op := .none
  for findOp in opList do
    op ← tryP findOp
    if op.isSome then break
  match op with
  | .none => tm
  | .some f => return f (← tm)

postfix op tm

def «postfix» (opList : List $ Parsec (α → α)) (tm : Parsec α)
  : Parsec α := do
  let e ← tm
  let mut op := .none
  for findOp in opList do
    op ← tryP findOp
    if op.isSome then break
  match op with
  | .none => return e
  | .some f => return f e