definition
module TIL-calls
imports TIL-expressions TIL-statements
exports
  context-free syntax
    Id "(" {Exp ","}* ")"     -> Exp  {cons("FunCall")}
    Id "(" {Exp ","}* ")" ";" -> Stat {cons("ProcCall")}

module TIL-types
imports TIL-literals
exports 
 sorts Type
  context-free syntax
    Id -> Type {cons("TypeName")}

module TIL-statements
imports TIL-expressions TIL-types
exports 
  sorts Stat
  context-free syntax
    "var" Id ";"			                    -> Stat {cons("Declaration")}
    "var" Id ":" Type ";"			            -> Stat {cons("DeclarationTyped")}
    Id ":=" Exp ";"                             -> Stat {cons("Assign")}
    "begin" Stat* "end"                         -> Stat {cons("Block")}
    "if" Exp "then" Stat* "end"                 -> Stat {cons("IfThen")}
    "if" Exp "then" Stat* "else" Stat* "end"    -> Stat {cons("IfElse")}
    "while" Exp "do" Stat* "end"                -> Stat {cons("While")}
    "for" Id ":=" Exp "to" Exp "do" Stat* "end" -> Stat {cons("For")}

module TIL-expressions
imports TIL-literals
exports 
  sorts Exp
  context-free syntax
    "true"       -> Exp {cons("True")}
    "false"      -> Exp {cons("False")}
    Id           -> Exp {cons("Var")}
    Int          -> Exp {cons("Int")}
    String       -> Exp {cons("String")}
    Exp "*" Exp  -> Exp {cons("Mul"),assoc}
    Exp "/" Exp  -> Exp {cons("Div"),assoc}
    Exp "%" Exp  -> Exp {cons("Mod"),non-assoc}
    Exp "+" Exp  -> Exp {cons("Add"),assoc}
    Exp "-" Exp  -> Exp {cons("Sub"),left}
    Exp "<" Exp  -> Exp {cons("Lt"),non-assoc}
    Exp ">" Exp  -> Exp {cons("Gt"),non-assoc}
    Exp "<=" Exp -> Exp {cons("Leq"),non-assoc}
    Exp ">=" Exp -> Exp {cons("Geq"),non-assoc}
    Exp "=" Exp  -> Exp {cons("Equ"),non-assoc}
    Exp "!=" Exp -> Exp {cons("Neq"),non-assoc}
    Exp "&" Exp  -> Exp {cons("And"),assoc}
    Exp "|" Exp  -> Exp {cons("Or"),assoc}
    "(" Exp ")"  -> Exp {bracket}
  context-free priorities
    {left: 
       Exp "*" Exp -> Exp 
       Exp "/" Exp -> Exp }
  > {left: 
       Exp "+" Exp -> Exp 
       Exp "-" Exp -> Exp }
  > {non-assoc: 
       Exp "<" Exp  -> Exp 
       Exp ">" Exp  -> Exp
       Exp "<=" Exp -> Exp 
       Exp ">=" Exp -> Exp
       Exp "="  Exp -> Exp 
       Exp "!=" Exp -> Exp }
  > Exp "&" Exp  -> Exp
  > Exp "|" Exp  -> Exp


module TIL-literals
exports 
  sorts Id Int String StrChar
  lexical syntax
    [A-Za-z][A-Za-z0-9]* -> Id
    [0-9]+               -> Int
    "\"" StrChar* "\""   -> String
    ~[\"\\\n]            -> StrChar
    [\\][\"\\n]          -> StrChar
  lexical restrictions
    Id  -/- [A-Za-z0-9]
    Int -/- [0-9]

module TIL-layout
exports 
  lexical syntax
    [\ \t\n\r]    -> LAYOUT
    "//" ~[\n\r]* -> LAYOUT
  context-free restrictions
    LAYOUT? -/- [\ \t\n\r]

module TIL
imports TIL-layout TIL-literals TIL-expressions TIL-statements TIL-calls
exports 
  sorts Program
  context-free syntax
    Stat* -> Program {cons("Program")}

  context-free start-symbols Program