module Parser where import ParserCombinators import Lexer import Absy -- Our parser parses tokens type Parser a = Parse Token a -- Char recognises the token given by the character char :: Char-> Parser Token char = token. TokChar -- -- Parsing expressions. -- pExpr :: Parser Expr pExpr = pTerm >* char '+' >*> pExpr `use2` Apply Plus `alt` pTerm >* char '-' >*> pExpr `use2` Apply Minus `alt` token TokIf *> pBExpr >* token TokThen >*> pExpr >* token TokElse >*> pExpr `use` (\((c,p), q)-> Conditional c p q) `alt` pTerm pTerm :: Parser Expr pTerm = pFactor >* char '*' >*> pTerm `use2` Apply Times `alt` pFactor >* char '/' >*> pTerm `use2` Apply Div `alt` pFactor pFactor :: Parser Expr pFactor = spot isNumToken `use` (\(TokNum i)-> Number i) `alt` pVariable `use2` Variable `alt` char '-' *> pFactor `use` UMinus `alt` char '(' *> pExpr >* char ')' `alt` token TokSum *> pRange `use` ApplyRange Sum `alt` token TokMult *> pRange `use` ApplyRange Mult `alt` token TokCount *> pRange `use` ApplyRange Count pVariable :: Parser (String, Int) pVariable = spot isVarToken `use` (\(TokVar i n) -> (i, n)) pRange :: Parser Range pRange = char '(' *> pVariable >* char ':' >*> pVariable >* char ')' `use` \((fv, fi), (tv, ti))-> Range fv fi tv ti -- -- Parsing boolean expressions. -- pBExpr :: Parser BoolExpr pBExpr = pConj >* char '|' >*> pBExpr `use2` BApply Or `alt` pConj pConj :: Parser BoolExpr pConj = pComp >* char '&' >*> pConj `use2` BApply And `alt` pComp pComp :: Parser BoolExpr pComp = char '!' *> pComp `use` Negate `alt` char '(' *> pBExpr >* char ')' `alt` pExpr >* char '=' >*> pExpr `use2` Compare Eq `alt` pExpr >* char '<' >*> pExpr `use2` Compare Less -- -- Main function -- parse :: String-> [Expr] parse str = -- filter out all parses which do not comsume the whole input map fst (filter (null. snd) (pExpr (lexer str)))