bison マニュアルの中間記法電卓
小数で
module Main where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Token( TokenParser, makeTokenParser ) import qualified Text.ParserCombinators.Parsec.Token as P import Text.ParserCombinators.Parsec.Language( haskellDef ) lexer :: TokenParser () lexer = makeTokenParser(haskellDef) symbol = P.symbol lexer parens = P.parens lexer integer = P.integer lexer float = P.float lexer calc = parseTest expr expr = expr1 expr1 = chainl1 expr2 addop expr2 = chainl1 expr3 mulop expr3 = neg <|> chainr1 prim powerop prim = parens expr <|> try float <|> do { x <- integer; return (fromIntegral x) } addop = do { symbol "+"; return (+) } <|> do { symbol "-"; return (-) } mulop = do { symbol "*"; return (*) } <|> do { symbol "/"; return (/) } neg = do { symbol "-"; x <- expr3; return (-x) } powerop = do { symbol "^"; return (**) }
で、
*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" 0.0 *Main> calc "4 + 4.5 - (34/(8*3+-3))" 6.880952380952381 *Main> calc "-10/3" -3.3333333333333335