{ module Parser where import Lexer import Data.Char } %name parse %tokentype { Token } %error { parseError } %token "from:" { TokenFrom _ } ',' { TokenComma _ } display_name { TokenDisplayName _ $$ } angle_addr { TokenAngleAddress _ $$ } addr_spec { TokenAddressSpecification _ $$ } %% From : "from:" MailboxList { From $2 } MailboxList : Mailbox { [$1] } | MailboxList ',' Mailbox { $3 : $1 } Mailbox : DisplayName AngleAddress { LongMailbox $1 $2 } | AngleAddress { AngleMailbox $1 } | AddressSpecification { ShortMailbox $1 } DisplayName : display_name { DisplayName (tail (init $1)) } AngleAddress : angle_addr { AngleAddress (tail (init $1)) } AddressSpecification : addr_spec { AddressSpecification $1 } { tokenPosn (TokenFrom p) = p tokenPosn (TokenComma p) = p tokenPosn (TokenDisplayName p s) = p tokenPosn (TokenAngleAddress p s) = p tokenPosn (TokenAddressSpecification p s) = p tokenStr (TokenFrom p) = "From:" tokenStr (TokenComma p) = "," tokenStr (TokenDisplayName p s) = s tokenStr (TokenAngleAddress p s) = s tokenStr (TokenAddressSpecification p s) = s getLineNum :: AlexPosn -> Int getLineNum (AlexPn offset lineNum colNum) = lineNum getColumnNum :: AlexPosn -> Int getColumnNum (AlexPn offset lineNum colNum) = colNum parseError :: [Token] -> a parseError tokenList = let pos = tokenPosn(head(tokenList)) s = tokenStr(head(tokenList)) in error ("parse error at line " ++ show(getLineNum(pos)) ++ " and column " ++ show(getColumnNum(pos)) ++ ". Error occurred at " ++ s) data From = From MailboxList deriving Show type MailboxList = [ Mailbox ] data Mailbox = LongMailbox DisplayName AngleAddress | AngleMailbox AngleAddress | ShortMailbox AddressSpecification deriving Show data DisplayName = DisplayName String deriving Show data AngleAddress = AngleAddress String deriving Show data AddressSpecification = AddressSpecification String deriving Show }