私は buildExpressionParser を使用して言語を解析しようとしてきましたが、ほとんどそれを持っています。Parsec.Exprのおかげで、私の大きな問題の 1 つを解決するためにサポートされていない Prefix/Postfix 演算子が繰り返されました。
このコード スニペットは、(私がなりたいもの) 私の最後の困難を示しています。
import Text.Parsec.Expr
import Text.Parsec
data Expr = Lit Char | A1 Expr | A2 Expr | B Expr Expr
deriving (Show)
expr :: Parsec String () Expr
expr = buildExpressionParser table (fmap Lit digit)
prefix p = Prefix . chainl1 p $ return (.)
table =
[ [prefix $ char ',' >> return A1]
, [Infix (char '*' >> return B) AssocNone]
, [prefix $ char '.' >> return A2]]
,,0
これは、..0
、.,0
、.0*0
、およびを正常に (そして正しく) 解析し,0*0
ます。ただし、解析することはできませ,.0
ん.0*.0
。これらの 2 つが解析されない理由はわかりますが、パーサーを変更して、成功したものを変更せず、2 つの失敗を解析する方法がわかりません。
これを「解決」する 1 つの方法は、 に変更(fmap Lit digit)
すること(fmap Lit Digit <|> expr)
ですが、パーサーはエラーになる代わりにループします。
アドバイス歓迎。
編集: 次の解析が重要です:
> parseTest expr ".0*0"
A2 (B (Lit '0') (Lit '0'))
> parseTest expr ",0*0"
B (A1 (Lit '0')) (Lit '0')