bison マニュアルの中間記法電卓

コマンドラインからの入力

module Main where

import System
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
        <|> expr4
expr4 = 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 = do args <- getArgs
          case parse expr "" (head args) of
            Left err -> do { putStr "parse error at "
                           ; print err
                           }
            Right x  -> print x

で、

$ runghc 20090427_parsec00.hs "4 + 4.5 - (34/(8*3+-3))"
6.880952380952381