]> ruin.nu Git - proglang.git/blobdiff - Parsyntax.y
hopefully compiles properly
[proglang.git] / Parsyntax.y
diff --git a/Parsyntax.y b/Parsyntax.y
new file mode 100644 (file)
index 0000000..6fef6ba
--- /dev/null
@@ -0,0 +1,160 @@
+-- This Happy file was machine-generated by the BNF converter
+{
+module Parsyntax where
+import Abssyntax
+import Lexsyntax
+import ErrM
+}
+
+%name pStms Stms
+%name pExp Exp
+
+-- no lexer declaration
+%monad { Err } { thenM } { returnM }
+%tokentype { Token }
+
+%token 
+ '=' { PT _ (TS "=") }
+ ';' { PT _ (TS ";") }
+ '{' { PT _ (TS "{") }
+ '}' { PT _ (TS "}") }
+ '(' { PT _ (TS "(") }
+ ')' { PT _ (TS ")") }
+ '++' { PT _ (TS "++") }
+ '--' { PT _ (TS "--") }
+ '-' { PT _ (TS "-") }
+ '<' { PT _ (TS "<") }
+ '<=' { PT _ (TS "<=") }
+ '>' { PT _ (TS ">") }
+ '>=' { PT _ (TS ">=") }
+ '==' { PT _ (TS "==") }
+ '!=' { PT _ (TS "!=") }
+ '+' { PT _ (TS "+") }
+ '*' { PT _ (TS "*") }
+ '/' { PT _ (TS "/") }
+ 'bool' { PT _ (TS "bool") }
+ 'else' { PT _ (TS "else") }
+ 'false' { PT _ (TS "false") }
+ 'if' { PT _ (TS "if") }
+ 'int' { PT _ (TS "int") }
+ 'print' { PT _ (TS "print") }
+ 'readBool' { PT _ (TS "readBool") }
+ 'readInt' { PT _ (TS "readInt") }
+ 'true' { PT _ (TS "true") }
+ 'while' { PT _ (TS "while") }
+
+L_ident  { PT _ (TV $$) }
+L_integ  { PT _ (TI $$) }
+L_err    { _ }
+
+
+%%
+
+Ident   :: { Ident }   : L_ident  { Ident $1 }
+Integer :: { Integer } : L_integ  { (read $1) :: Integer }
+
+Bool :: { Bool }
+Bool : 'true' { True } 
+  | 'false' { False }
+
+
+Stm :: { Stm }
+Stm : Type Ident '=' Exp ';' { SDecl $1 $2 $4 } 
+  | Type Ident ';' { decl_ $1 $2 }
+  | Exp ';' { SExp $1 }
+  | '{' ListStm '}' { SBlock (reverse $2) }
+  | 'if' '(' Exp ')' Stm { if_ $3 $5 }
+  | 'if' '(' Exp ')' Stm 'else' Stm { SIf $3 $5 $7 }
+  | 'while' '(' Exp ')' Stm { SWhile $3 $5 }
+  | 'print' Exp ';' { SPrint $2 }
+  | Stm ';' { $1 }
+
+
+Exp :: { Exp }
+Exp : Exp1 BOp Exp1 { BExp $1 $2 $3 } 
+  | Exp1 { $1 }
+
+
+Exp1 :: { Exp }
+Exp1 : Exp1 Op1 Exp2 { op1_ $1 $2 $3 } 
+  | Exp2 { $1 }
+
+
+Exp2 :: { Exp }
+Exp2 : Exp2 Op2 Exp3 { op2_ $1 $2 $3 } 
+  | Exp3 { $1 }
+
+
+Exp3 :: { Exp }
+Exp3 : Ident '++' { postIncr_ $1 } 
+  | Ident '--' { postDecr_ $1 }
+  | Ident { EVar $1 }
+  | Ident '=' Exp { EAss $1 $3 }
+  | Integer { EInt $1 }
+  | '-' Exp3 { ENeg $2 }
+  | Bool { EBool $1 }
+  | 'readInt' { EReadI }
+  | 'readBool' { EReadB }
+  | '(' Exp ')' { $2 }
+
+
+ListStm :: { [Stm] }
+ListStm : {- empty -} { [] } 
+  | ListStm Stm { flip (:) $1 $2 }
+
+
+Stms :: { Stms }
+Stms : ListStm { Program (reverse $1) } 
+
+
+BOp :: { BOp }
+BOp : '<' { Lt } 
+  | '<=' { ELt }
+  | '>' { Gt }
+  | '>=' { EGt }
+  | '==' { Eq }
+  | '!=' { NEq }
+
+
+Op1 :: { Op }
+Op1 : '+' { Plus } 
+  | '-' { Minus }
+
+
+Op2 :: { Op }
+Op2 : '*' { Times } 
+  | '/' { Div }
+
+
+Op :: { Op }
+Op : Op1 { $1 } 
+  | Op2 { $1 }
+
+
+Type :: { Type }
+Type : 'int' { TInt } 
+  | 'bool' { TBool }
+
+
+
+{
+
+returnM :: a -> Err a
+returnM = return
+
+thenM :: Err a -> (a -> Err b) -> Err b
+thenM = (>>=)
+
+happyError :: [Token] -> Err a
+happyError ts =
+  Bad $ "syntax error at " ++ tokenPos ts ++ if null ts then [] else (" before " ++ unwords (map prToken (take 4 ts)))
+
+myLexer = tokens
+decl_ t_ v_ = SDecl t_ v_ EDefault
+if_ e_ s_ = SIf e_ s_ SNoop
+op1_ e1_ o_ e2_ = OpExp e1_ o_ e2_
+op2_ e1_ o_ e2_ = OpExp e1_ o_ e2_
+postIncr_ i_ = EPost i_ Plus
+postDecr_ i_ = EPost i_ Minus
+}
+