// LL(1) grammar for Rz language 1 May 2001

// lexical 
// terminal symbols , ; ( ) [ ] { } + - * /  
//    ! & && || < <= == != >= > 
//    IF ELSE WHILE RETURN PRINT EOF
// special   
//    ID identifier, NUM number, STRING string "..." ,
//    Arglist argument list, nil

// pass1 generate tempfile and table of global name

pass1 -> ps1
ps1 -> dcl ps1 | EOF
dcl -> ID dcl2
dcl2 -> ; | [ NUM ] ; | ( Arglist ) block

// pass2 read tempfile and generate code

pass2 -> ps2
ps2 -> NUM locals NUM block ps2 | EOF
locals -> ID locals | nil
block -> { stmts }

stmt -> block | stmt1
stmts -> stmt1 stmts | nil
stmt1 -> ; | IF ( expr ) stmt elsest |
  WHILE ( expr ) stmt |
  RETURN returnst |
  PRINT ( p1 prlist ) ; |
  * ID = expr ; |
  ID stmt2

elsest -> ELSE stmt | nil
returnst -> ; | expr ;
prlist -> , p1 prlist | nil
p1 -> STRING | expr
stmt2 -> = expr ; |
  [ expr ] = expr ; |
  ( Arglist ) ;

expr -> term exprs
exprs -> || term exprs | nil

term -> f1 terms
terms -> && f1 terms | nil

f1 -> f2 f1s
f1s -> < f2 f1s | <= f2 f1s | == f2 f1s |
  != f2 f1s | >= f2 f1s | > f2 f1s | nil

f2 -> f3 f2s
f2s -> + f3 f2s | - f3 f2s | nil

f3 -> item f3s
f3s -> * item f3s | / item f3s | nil

item -> - t1 | ! t1 | * t1 | & ID mod2 | t1
t1 -> ID mod | NUM | ( expr )
mod -> [ expr ] | ( Arglist ) | nil
mod2 -> [ expr ] | nil
