(* BNF for MiniOberon * * This language is based on, but *not* entirely compatible * with the Oberon-2 language designed by N. Wirth. * * written by mike slattery - Feb 2005 * * To help with Assignment #4, I've listed the suggested * tree class to use for each non-terminal (just * above each production) *) (* ID, NUM, STRING are terminals with attribs *) (* Module *) module -> MODULE ID ; decl_seq END ID . (* DeclSeq *) decl_seq -> type_or_var_seq proc_or_forward_seq (* TypeVarList containing TVEntries, each of which is either a TypeEntry or a VarEntry *) type_or_var_seq -> type_or_var_seq TYPE type_list -> type_or_var_seq VAR var_list -> (* TypeList *) type_list -> type_list type_decl ; -> type_decl ; (* TypeDecl *) type_decl -> ID = RECORD field_list END (* VarList *) field_list -> field_list var_decl ; -> var_decl ; (* VarList *) var_list -> var_list var_decl ; -> var_decl ; (* VarDecl *) var_decl -> id_list : type (* IdList *) id_list -> id_list , ID -> ID (* Type *) type -> element_type (* ArrayType *) -> ARRAY NUM OF element_type (* IntegerType *) element_type -> INTEGER (* BooleanType *) -> BOOLEAN (* RecordType *) -> ID (* ProcList *) proc_or_forward_seq -> proc_or_forward_seq proc_decl ; -> proc_or_forward_seq forward_decl ; -> (* ProcDecl (with a null body) *) forward_decl -> PROCEDURE^ receiver ID opt_parens -> PROCEDURE^ receiver ID ( opt_formal_list ) : element_type (* ProcDecl *) proc_decl -> PROCEDURE receiver ID opt_parens ; proc_body ID -> PROCEDURE receiver ID ( opt_formal_list ) : element_type ; proc_body ID (* Receiver *) receiver -> ( ID : ID ) -> (* VarList *) opt_parens -> ( opt_formal_list ) -> (* VarList *) opt_formal_list -> formal_list -> (* VarList *) formal_list -> formal_list ; formal_decl -> formal_decl (* VarDecl *) formal_decl -> id_list : formal_type (* Type *) formal_type -> element_type (* Use ArrayType with size of 0 or -1 *) -> ARRAY OF element_type (* ProcBody *) proc_body -> decl_seq BEGIN stmt_seq END (* StmtList *) stmt_seq -> stmt_seq ; stmt -> stmt (* All the following are subclasses of Stmt *) stmt -> ID := expr -> ID [ expr ] := expr (* ArrayAssign *) -> ID . ID := expr (* FieldAssign *) -> Out.String ( STRING ) -> Out.Int ( expr) -> Out.Ln -> FOR ID := expr TO expr opt_by DO stmt_seq END -> IF expr THEN stmt_seq END -> IF expr THEN stmt_seq ELSE stmt_seq END -> WHILE expr DO stmt_seq END -> ID opt_params (* CallStmt *) -> RETURN opt_expr -> NEW ( ID ) (* Expr *) opt_by -> BY expr -> (* Expr *) opt_expr -> expr -> (* ExprList *) opt_params -> ( opt_expr_list ) -> (* ExprList *) opt_expr_list -> expr_list -> (* ExprList *) expr_list -> expr_list , expr -> expr (* All the following are subclasses of Expr *) expr -> NUM -> ID -> expr [ expr ] -> expr . ID opt_params -> ID ( opt_expr_list ) (* CallExpr *) -> expr + expr -> expr - expr -> - expr -> expr * expr -> expr DIV expr -> expr MOD expr -> expr = expr -> expr # expr (* NotEqual *) -> expr < expr -> expr <= expr -> expr > expr -> expr >= expr -> expr OR expr -> expr & expr (* And *) -> ~ expr (* Not *) -> LEN ( expr ) -> TRUE -> FALSE -> NIL