packages feed

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
}