|
Packit |
2cbdf3 |
-- An example demonstrating how to connect a Happy parser to an Alex lexer.
|
|
Packit |
2cbdf3 |
{
|
|
Packit |
2cbdf3 |
import Tokens_posn
|
|
Packit |
2cbdf3 |
}
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
%name calc
|
|
Packit |
2cbdf3 |
%tokentype { Token }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
%token let { Let _ }
|
|
Packit |
2cbdf3 |
in { In _ }
|
|
Packit |
2cbdf3 |
int { Int _ $$ }
|
|
Packit |
2cbdf3 |
var { Var _ $$ }
|
|
Packit |
2cbdf3 |
'=' { Sym _ '=' }
|
|
Packit |
2cbdf3 |
'+' { Sym _ '+' }
|
|
Packit |
2cbdf3 |
'-' { Sym _ '-' }
|
|
Packit |
2cbdf3 |
'*' { Sym _ '*' }
|
|
Packit |
2cbdf3 |
'/' { Sym _ '/' }
|
|
Packit |
2cbdf3 |
'(' { Sym _ '(' }
|
|
Packit |
2cbdf3 |
')' { Sym _ ')' }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
%%
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
Exp :: { Exp }
|
|
Packit |
2cbdf3 |
Exp : let var '=' Exp in Exp { LetE $2 $4 $6 }
|
|
Packit |
2cbdf3 |
| Exp1 { $1 }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
Exp1 : Exp1 '+' Term { PlusE $1 $3 }
|
|
Packit |
2cbdf3 |
| Exp1 '-' Term { MinusE $1 $3 }
|
|
Packit |
2cbdf3 |
| Term { $1 }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
Term : Term '*' Factor { TimesE $1 $3 }
|
|
Packit |
2cbdf3 |
| Term '/' Factor { DivE $1 $3 }
|
|
Packit |
2cbdf3 |
| Factor { $1 }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
Factor : '-' Atom { NegE $2 }
|
|
Packit |
2cbdf3 |
| Atom { $1 }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
Atom : int { IntE $1 }
|
|
Packit |
2cbdf3 |
| var { VarE $1 }
|
|
Packit |
2cbdf3 |
| '(' Exp ')' { $2 }
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
{
|
|
Packit |
2cbdf3 |
data Exp =
|
|
Packit |
2cbdf3 |
LetE String Exp Exp |
|
|
Packit |
2cbdf3 |
PlusE Exp Exp |
|
|
Packit |
2cbdf3 |
MinusE Exp Exp |
|
|
Packit |
2cbdf3 |
TimesE Exp Exp |
|
|
Packit |
2cbdf3 |
DivE Exp Exp |
|
|
Packit |
2cbdf3 |
NegE Exp |
|
|
Packit |
2cbdf3 |
IntE Int |
|
|
Packit |
2cbdf3 |
VarE String
|
|
Packit |
2cbdf3 |
deriving Show
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
main:: IO ()
|
|
Packit |
2cbdf3 |
main = interact (show.runCalc)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
runCalc :: String -> Exp
|
|
Packit |
2cbdf3 |
runCalc = calc . alexScanTokens
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
happyError :: [Token] -> a
|
|
Packit |
2cbdf3 |
happyError tks = error ("Parse error at " ++ lcn ++ "\n")
|
|
Packit |
2cbdf3 |
where
|
|
Packit |
2cbdf3 |
lcn = case tks of
|
|
Packit |
2cbdf3 |
[] -> "end of file"
|
|
Packit |
2cbdf3 |
tk:_ -> "line " ++ show l ++ ", column " ++ show c
|
|
Packit |
2cbdf3 |
where
|
|
Packit |
2cbdf3 |
AlexPn _ l c = token_posn tk
|
|
Packit |
2cbdf3 |
}
|