(* BNF for MiniOberon * (UPDATED) * * This version removes the user-defined types and type-bound * procedure structures. This is the grammar for Assignment #7 * * [ NOTE: Lines following "777" are additions or changes to the * TinyObe grammar ] * * This language is based on, but *not* entirely compatible * with the Oberon-2 language designed by N. Wirth. * * written by mike slattery - Feb 2005 * modified - apr 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 . 777 (* DeclSeq *) decl_seq -> var_seq proc_or_forward_seq 777 (* TypeVarList containing TVEntries, each of which is either a TypeEntry or a VarEntry - In this version, we only ever use VarEntry's *) var_seq -> var_seq VAR var_list -> (* 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 777 (* ProcList *) proc_or_forward_seq -> proc_or_forward_seq proc_decl ; -> proc_or_forward_seq forward_decl ; -> 777 (* ProcDecl (with a null body) *) forward_decl -> PROCEDURE^ ID opt_parens -> PROCEDURE^ ID ( opt_formal_list ) : element_type 777 (* ProcDecl *) proc_decl -> PROCEDURE ID opt_parens ; proc_body ID -> PROCEDURE ID ( opt_formal_list ) : element_type ; proc_body ID 777 (* VarList *) opt_parens -> ( opt_formal_list ) -> 777 (* VarList *) opt_formal_list -> formal_list -> 777 (* VarList *) formal_list -> formal_list ; formal_decl -> formal_decl 777 (* VarDecl *) formal_decl -> id_list : formal_type 777 (* Type *) formal_type -> element_type (* Use ArrayType with size of 0 or -1 *) -> ARRAY OF element_type 777 (* ProcBody - Although the grammar allows it, we won't be expecting any procedures defined inside other procedures *) 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 *) -> 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 777 -> ID opt_params (* CallStmt *) 777 -> RETURN opt_expr (* Expr *) opt_by -> BY expr -> 777 (* Expr *) opt_expr -> expr -> 777 (* ExprList *) opt_params -> ( opt_expr_list ) -> 777 (* ExprList *) opt_expr_list -> expr_list -> 777 (* ExprList *) expr_list -> expr_list , expr -> expr (* All the following are subclasses of Expr *) expr -> NUM -> ID -> ID [ expr ] 777 -> 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 *) -> ( expr ) -> LEN ( expr ) -> TRUE -> FALSE