bison マニュアルの中間記法電卓
Parsec.Expr を使用
module Main where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr import Text.ParserCombinators.Parsec.Token( TokenParser, makeTokenParser, reservedOpNames ) import qualified Text.ParserCombinators.Parsec.Token as P import Text.ParserCombinators.Parsec.Language( haskellDef ) lexer :: TokenParser () lexer = makeTokenParser( haskellDef { reservedOpNames = ["*", "/", "+", "-", "^"] } ) symbol = P.symbol lexer parens = P.parens lexer integer = P.integer lexer float = P.float lexer reservedOp = P.reservedOp lexer calc = parseTest expr expr = expr1 expr1 = buildExpressionParser table prim prim = parens expr <|> try float <|> do { x <- integer; return (fromIntegral x) } table = [[op "^" (**) AssocRight] ,[preop "-" negate] ,[op "*" (*) AssocLeft, op "/" (/) AssocLeft] ,[op "+" (+) AssocLeft, op "-" (-) AssocLeft] ] where op s f assoc = Infix (do { reservedOp s; return f } <?> "operator") assoc preop s f = Prefix (do { reservedOp s; return f } <?> "operator")
で、
*Main> calc "1+2" Loading package parsec-2.0 ... linking ... done. 3.0 *Main> calc "1-2" -1.0 *Main> calc "2*3" 6.0 *Main> calc "10/3" 3.3333333333333335 *Main> calc "-56+2" -54.0 *Main> calc "-2 ^ 2" -4.0 *Main> calc "2^2^3" 256.0 *Main> calc "-(1+2*3)" -7.0 *Main> calc "1+-1" 1.0 *Main> calc "1+ -1" 0.0
なぜか一部うまく動作しない