ewe-0.1.0.23: src/Language/EWE/Parser.y
{
{-# OPTIONS -w #-}
module Language.EWE.Parser(pEWE) where
import Language.EWE.Token(Tkns,Tkn(..))
import Language.EWE.Scanner
import Language.EWE.AbsSyn
}
%name parse
%tokentype { Tkn }
%error { parseError }
%monad { Alex }
%lexer { lexwrap } { TknEOF }
%token int { TknInt $$ }
str { TknStr $$ }
-- label { TknLabel $$ }
id { TknId $$ }
':=' { TknAssgn }
':' { TknColon }
'(' { TknLPar }
')' { TknRPar }
'[' { TknLBrk }
']' { TknRBrk }
',' { TknComma }
'+' { TknOper '+' }
'-' { TknOper '-' }
'*' { TknOper '*' }
'/' { TknOper '/' }
'%' { TknOper '%' }
'<>' { TknCond "<>" }
'=' { TknCond "=" }
'<' { TknCond "<" }
'<=' { TknCond "<=" }
'>' { TknCond ">" }
'>=' { TknCond ">=" }
'PC' { TknResWrd "PC" }
'M' { TknResWrd "M" }
'readInt' { TknResWrd "readInt" }
'writeInt' { TknResWrd "writeInt" }
'readStr' { TknResWrd "readStr" }
'writeStr' { TknResWrd "writeStr" }
'goto' { TknResWrd "goto" }
'if' { TknResWrd "if" }
'then' { TknResWrd "then" }
'halt' { TknResWrd "halt" }
'break' { TknResWrd "break" }
'equ' { TknResWrd "equ" }
%%
EweProg : Executable Equates { Prg $1 $2 }
Executable : LabelInstr { [$1] }
| LabelInstr Executable { $1:$2 }
LabelInstr : id ':' LabelInstr { addLabel $1 $3 }
| Instr { Stmt [] $1 }
Instr : MemRef ':=' int { IMMI $1 $3 }
| MemRef ':=' str { IMMS $1 $3 }
| MemRef ':=' 'PC' '+' int { IMRPC $1 $5 }
| 'PC' ':=' MemRef { SPC $3 }
| MemRef ':=' MemRef { IMMM $1 $3 }
| MemRef ':=' MemRef '+' MemRef { IAdd $1 $3 $5 }
| MemRef ':=' MemRef '-' MemRef { ISub $1 $3 $5 }
| MemRef ':=' MemRef '*' MemRef { IMul $1 $3 $5 }
| MemRef ':=' MemRef '/' MemRef { IDiv $1 $3 $5 }
| MemRef ':=' MemRef '%' MemRef { IMod $1 $3 $5 }
| MemRef ':=' 'M' '[' MemRef '+' int ']' { IMRI $1 $5 $7 }
| 'M' '[' MemRef '+' int ']' ':=' MemRef { IMMR $3 $5 $8 }
| 'readInt' '(' MemRef ')' { IRI $3 }
| 'writeInt' '(' MemRef ')' { IWI $3 }
| 'readStr' '(' MemRef ',' MemRef ')' { IRS $3 $5 }
| 'writeStr' '(' MemRef ')' { IWS $3 }
| 'goto' int { IGI $2 }
| 'goto' id { IGS $2 }
| 'if' MemRef Cond MemRef 'then' 'goto' int { IFI $2 $3 $4 $7 }
| 'if' MemRef Cond MemRef 'then' 'goto' id { IFS $2 $3 $4 $7 }
| 'halt' { IH }
| 'break' { IB }
Equates : { [] }
| 'equ' id 'M' '[' int ']' Equates { ($2,$5):$7 }
MemRef : 'M' '[' int ']' { MRefI $3 }
| id { MRefId $1 }
Cond : '>=' { CLET }
| '>' { CLT }
| '<=' { CGET }
| '<' { CGT }
| '=' { CE }
| '<>' { CNE }
{
lexwrap :: (Tkn -> Alex a) -> Alex a
lexwrap cont = do
t <- alexMonadScan
cont t
addLabel :: String -> Stmt -> Stmt
addLabel s (Stmt ss i) = Stmt (s:ss) i
parseError :: Tkn -> Alex a
parseError t = do
(l,c) <- getPosn
fail (show l ++ ":" ++ show c ++ ": Parser error on Token: " ++ show t ++ "\n")
pEWE :: String -> Either String Prog
pEWE s = runAlex s parse
}