-- File generated by the BNF Converter. -- Parser definition for use with Happy. { {-# OPTIONS_GHC -fno-warn-incomplete-patterns -fno-warn-overlapping-patterns #-} {-# LANGUAGE PatternSynonyms #-} module ParCalc ( happyError , myLexer , pExp , pExp1 , pExp2 ) where import Prelude import qualified AbsCalc import LexCalc } %name pExp_internal Exp %name pExp1_internal Exp1 %name pExp2_internal Exp2 %monad { Err } { (>>=) } { return } %tokentype {Token} %token '(' { PT _ (TS _ 1) } ')' { PT _ (TS _ 2) } '*' { PT _ (TS _ 3) } '+' { PT _ (TS _ 4) } '-' { PT _ (TS _ 5) } '/' { PT _ (TS _ 6) } L_integ { PT _ (TI _)} %% Integer :: { (AbsCalc.BNFC'Position, Integer) } Integer : L_integ { (uncurry AbsCalc.BNFC'Position (tokenLineCol $1), (read (tokenText $1) ) :: Integer) } Exp :: { (AbsCalc.BNFC'Position, AbsCalc.Exp) } Exp : Exp '+' Exp1 { (fst $1, AbsCalc.EAdd (fst $1) (snd $1) (snd $3)) } | Exp '-' Exp1 { (fst $1, AbsCalc.ESub (fst $1) (snd $1) (snd $3)) } | Exp1 { (fst $1, (snd $1)) } Exp1 :: { (AbsCalc.BNFC'Position, AbsCalc.Exp) } Exp1 : Exp1 '*' Exp2 { (fst $1, AbsCalc.EMul (fst $1) (snd $1) (snd $3)) } | Exp1 '/' Exp2 { (fst $1, AbsCalc.EDiv (fst $1) (snd $1) (snd $3)) } | Exp2 { (fst $1, (snd $1)) } Exp2 :: { (AbsCalc.BNFC'Position, AbsCalc.Exp) } Exp2 : '(' Exp ')' { (uncurry AbsCalc.BNFC'Position (tokenLineCol $1), (snd $2)) } | Integer { (fst $1, AbsCalc.EInt (fst $1) (snd $1)) } { type Err = Either String happyError :: [Token] -> Err a happyError ts = Left $ "syntax error at " ++ tokenPos ts ++ case ts of [] -> [] [Err _] -> " due to lexer error" t:_ -> " before `" ++ (prToken t) ++ "'" myLexer :: String -> [Token] myLexer = tokens -- Entrypoints pExp :: [Token] -> Err AbsCalc.Exp pExp = fmap snd . pExp_internal pExp1 :: [Token] -> Err AbsCalc.Exp pExp1 = fmap snd . pExp1_internal pExp2 :: [Token] -> Err AbsCalc.Exp pExp2 = fmap snd . pExp2_internal }