module Parser where import Text.ParserCombinators.Parsec import qualified Text.ParserCombinators.Parsec.Token as Token import Text.ParserCombinators.Parsec.Language(javaStyle) tinyCStyle = javaStyle { Token.nestedComments = False , Token.reservedNames = ["if", "else", "while", "return", "int", "void"] , Token.reservedOpNames= [] } lexer :: Token.TokenParser () lexer = Token.makeTokenParser tinyCStyle whiteSpace :: Parser () whiteSpace = Token.whiteSpace lexer lexeme :: Parser a -> Parser a lexeme = Token.lexeme lexer symbol :: String -> Parser String symbol = Token.symbol lexer natural :: Parser Integer natural = Token.natural lexer identifier :: Parser String identifier = Token.identifier lexer reserved :: String -> Parser () reserved = Token.reserved lexer operator :: Parser String operator = Token.operator lexer reservedOp :: String -> Parser () reservedOp = Token.reservedOp lexer parens :: Parser a -> Parser a parens = Token.parens lexer braces :: Parser a -> Parser a braces = Token.braces lexer squares :: Parser a -> Parser a squares = Token.squares lexer semi :: Parser String semi = Token.semi lexer comma :: Parser String comma = Token.comma lexer runLex :: Show a => Parser a -> String -> IO () runLex p input = parseTest (do { whiteSpace ; x <- p ; eof ; return x }) input ---------------------------------------------------------------------- -- (Very Incomplete) Parser for Tiny C parseCompOperator = foldl1 (<|>) $ map (try . symbol) ["==", "!=", ">=", ">", "<=", "<"] parseAddSub = symbol "+" <|> symbol "-" parseMultDiv = symbol "*" <|> symbol "/" parseSignPart = symbol "+" <|> symbol "-" <|> return "+" parseFunName = identifier parseTypeName = do { reserved "int"; return "int" } <|> do { reserved "void"; return "void" } parseId = identifier parseIntConstant = natural -- no need to define parseIdTail, parseAlpha, parseDigit and parseConstTail. ---------------------------------------------------------------------- {- -- Example Parser for a very tiny language: -- S -> "(" L ")" -- | Id -- L -> S L' -- L' -> "," S L' -- | (empty) -} data S = List [S] | Id String deriving Show parseS =(do { l <- parens parseL; return (List l) }) <|> (do { x <- identifier; return (Id x) }) parseL = do { s <- parseS; l' <- parseL'; return (s:l') } parseL' = (do { comma; s <- parseS; l' <- parseL'; return (s:l') }) <|> return [] ---------------------------------------------------------------------- {- -- Abstract Syntax Tree for Tiny C -} type Expression = (SignPart, Term, ExpTail) type ExpTail = [(AddSub, Term)] type Term = (Factor, TermTail) type TermTail = [(MultDiv, Factor)] data Factor = MkIntConst Integer | MkVar Variable | MkExpr Expression deriving Show type Variable = (Id, SubscriptPart) type SubscriptPart = Maybe Expression type ConditionExp = (Expression, CompOperator, Expression) type CompOperator = String type AddSub = String type MultDiv = String type SignPart = String type Id = String