module AEParser where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr import Text.ParserCombinators.Parsec.Token import Text.ParserCombinators.Parsec.Language import Char run :: Show a => Parser a -> String -> IO () run p input = case (parse p "" input) of Left err -> do{ putStr "parse error at " ; print err } Right x -> print x -- ----------------------------------------------------------- -- Arithmetic Expression Parser in Parsec -- ----------------------------------------------------------- -- E -> TH expr :: Parser [Int] expr = do lt <- term le <- hexpr return (1:(lt++le)) -- H -> +TH | eps hexpr = do char '+' lt <- term le <- hexpr return (2:lt++le) <|> return [3] -- T -> FG term = do lf <- factor lt <- hterm return (4:lf++lt) -- G -> *FG | eps hterm = do char '*' lf <- factor lt <- hterm return (5:lf++lt) <|> return [6] -- F -> (E) | a factor = do char '(' le <- expr char ')' return (7:le) <|> do char 'a' return [8] -- ---------------------------------------------------- -- production of syntax tree -- ---------------------------------------------------- data Expr = Plus Expr Expr | Mult Expr Expr | Factor | Empty deriving Show empty :: Expr -> Bool empty Empty = True empty _ = False -- E -> TH expr3 :: Parser Expr expr3 = do lt <- term3 le <- hexpr3 return (if empty le then lt else Plus lt le) -- H -> +TH | eps hexpr3 = (do c <- char '+' lt <- term3 le <- hexpr3 return (if empty le then lt else Plus lt le)) <|> return Empty -- T -> FG term3 = do lf <- factor3 lt <- hterm3 return (if empty lt then lf else Mult lf lt) -- G -> *FG | eps hterm3 = (do c <- char '*' lf <- factor3 lt <- hterm3 return (if empty lt then lf else Mult lf lt)) <|> return Empty -- F -> (E) | a factor3 = (do c <- char '(' le <- expr3 c <- char ')' return le) <|> (do c <- char 'a' return Factor) -- ----------------------------------------------------------- -- Using Parsec Expression Parser -- ----------------------------------------------------------- lang = makeTokenParser haskellStyle aExpr :: Parser Expr aExpr = buildExpressionParser operators factors operators = [ [ op "*" AssocLeft ] , [ op "+" AssocLeft ] ] where op s assoc = Infix (do{ symbol lang s; return (\x y -> makeExpr s x y)} "operator") assoc makeExpr :: String -> Expr -> Expr -> Expr makeExpr "+" x y = Plus x y makeExpr "*" x y = Mult x y makeExpr _ _ _ = Empty factors = choice [ parens lang aExpr , variable ] variable = do{ char 'a' ; return Factor }