« Home

處理優先度相同的運算子 [cs-000E]

因為有些運算子優先級相同,所以我們還需要再修改上面的函數來正確的支援這個概念;而且上面的程式為了避免複雜化,只解析一次 operator 加上 tm 就退出了,會導致實際上 1 + 2 * 3 * 4 這種算式的 * 4 部分沒有被解析。要解決這個問題,我們需要貪婪解析右半邊 op tm 的部分。綜上所述我們得到的程式碼是

def infixL (opList : List (Parsec (α → α → α))) (tm : Parsec α)
  : Parsec α := do
  let l ← tm
  let rs ← many do
    for findOp in opList do
      match ← tryP findOp with
      | .some f => return (f, ← tm)
      | .none => continue
    fail "cannot match any operator"
  return rs.foldl (fun lhs (bin, rhs) => (bin lhs rhs)) l

首先我們有一串 operator 而非一個,其次在右邊能被解析成 op tm 時都進行解析,最後用 foldl 把結果轉換成壓縮後的 α