@hammar が指摘してText.Parsec.Expr
いるように、この種のものには使用する必要があります。しかし、これは宿題なので、一生懸命やる必要があるかもしれません。
問題は にparseArithmetic
あります。演算子になることを許可しますが、anyChar
case ステートメントでは、、、、、、および のみを許可します。がを解析しようとすると、最初の を演算子として使用しますが、2 番目の から を解析できず、モナドで失敗し、case ステートメントに到達する前にバックトラックします。ただし、 を解析しようとすると、その部分が取得されますが、は演算子であり、は変数の名前であるという算術式があると見なされるため、大文字と小文字が区別され、ブームになります。+
-
*
/
%
^
parseArithmetic
i == 0
=
intExp2
=
i == 0 AND j == 0
i ==
0 A ND
A
ND
ちなみに、パーサーを使用して文字列を照合し、次に case ステートメントを使用してもう一度照合する代わりに、パーサーに文字列の代わりに関数を返させ、関数を直接適用することができます。
parseOp :: String -> a -> Parser a
parseOp op a = string op >> spaces >> return a
parseLogic :: Parser BoolExp
parseLogic = do
boolExp1 <- parseBoolExp
spaces
operator <- choice [ try $ parseOp "AND" And
, parseOp "OR" Or
, parseOp "XOR" XOr
]
boolExp2 <- parseBoolExp
return $ operator boolExp1 boolExp2
parseBoolean :: Parser BoolExp
parseBoolean = do
intExp1 <- parseIntExp
spaces
operator <- choice [ try $ parseOp "==" Main.EQ
, parseOp "=>" GTorEQ
, parseOp "<=" LTorEQ
]
intExp2 <- parseIntExp
return $ operator intExp1 intExp2