buildExpressionParser
Parsecでparserの自動生成の過程でExpressionParserを生成する
Text.ParserCombinators.Parsec.Exprモジュールにある関数
buildExpressionParser :: Stream s m t => OperatorTable s u m a -> ParsecT s u m a -> ParsecT s u m a
document
準備しておくもの
事前に言語の構文規則を定義
2つの引数を取る
演算の規則のテーブル
type OperatorTable s u m a = [[Operator s u m a]]
構文規則をテーブルに落とし込む
Assocで左結合か右結合を定義 ref
演算子の優先順位はリストの前後関係で定義
優先順位が高いものを上の方に書く
演算子の指定 ref
Infix
中置演算子
Prefix
前置演算子
++1とか、-3とか
Postfix
後置演算子
2--とか
factorを決めたパーサー
?
思考の手順
BNF記法を用いて文法規則を決める
左結合のもの
Rytlの生成規則みたいな
これらを一つずつParsecのコンビネータを使って作っていくこともできるが面倒
なのでbuildExpressionParserを使う
どう使うか?
演算子の優先順位などをテーブルで表現する
例
githubに書いた
code:hs
-- Expression Parserの作成
exprparser :: Parser Expr
exprparser = buildExpressionParser table term <?> "expression"
table =
[ Prefix (m_reservedOp "~" >> return (Uno Not))
, Infix (m_reservedOp "&" >> return (Duo And)) AssocLeft
, Infix (m_reservedOp "=" >> return (Duo Iff)) AssocLeft
]
term =
m_parens exprparser
<|> fmap Var m_identifier
<|> (m_reserved "true" >> return (Con True))
<|> (m_reserved "false" >> return (Con False))
#??
<?>ってなに
docs
label関数と同じらしい
https://tnomura9.exblog.jp/27732301/
参考
Parsec 式の定義 buildExpressionParser : tnomuraのブログ