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


calc  = parseTest expr

expr  = expr1
expr1 = chainl1 expr2 addop
expr2 = chainl1 expr3 mulop
expr3 = neg <|> chainr1 prim  powerop
prim  = parens expr <|> integer


addop   =   do { symbol "+"; return (+) }
        <|> do { symbol "-"; return (-) }

mulop   =   do { symbol "*"; return (*)   }
        <|> do { symbol "/"; return (div) }

neg     =   do { symbol "-"; x <- expr3; return (-x) }

powerop =   do { symbol "^"; return (^) }

で、

*Main> calc "1+2"
Loading package parsec-2.0 ... linking ... done.
3
*Main> calc "1-2"
-1
*Main> calc "2*3"
6
*Main> calc "10/3"
3
*Main> calc "-56+2"
-54
*Main> calc "-2 ^ 2"
-4
*Main> calc "2^2^3"
256
*Main> calc "-(1+2*3)"
-7
*Main> calc "1+-1"
0