中置演算子memoつづき

PersecのbuildExpressionParserのしくみ(Pre/Postfixは除く)

  • 優先順位ごとにパーザーを作る
    • 高い順位: factorParser
    • 演算子パーザー複数
    • パーザー例:
buildOpsParser factorParser opParsers = do 
  lVal <- factorParser
  opList <- many do
    opFunc, assoc <- chioce opParsers
    rVal <- factorParser
    return (opFunc, assoc, rVal)
  return (relation lVal opList)
      • パーズ結果はlVal, [(opFunc, assoc, rVal),...]
    • パーズ結果を右結合左結合に応じてopFunc実行
    • 例:
relation lVal [] 
  = lVal
relation lVal [(opFunc, Left, rVal)| rest]
  = relation (opFunc lVal rVal) rest
relation lVal [(opFunc, Right, rVal)| rest]
  = opFunc lVal (relation rVal rest)
  • 優先順位でパーザーを組み合わせる(結合度が強いのが頭)
    • パーザー例:
{- opTable :: [[Parser (a->a->a, Assoc)]] -}
buildExprParser opTable factorParser 
 = foldM buildOpsParser factorParser opTable