(* * Menhir wygeneruje funkcję o nazwie file *) %start file %{ open Xi_lib open Ast open Parser_utils (* Generator znaczników *) let mkTag = let i = ref 0 in fun () -> let tag = !i in incr i; NodeTag tag (* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv * Miejsce na twój kod w Ocamlu *) (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------------------------------------------------- *) %} (* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv * Miejsce na dyrektywy *) %token EOF %token COMMA %token LPAREN %token RPAREN %token LBRACKET %token RBRACKET %token LSBRACKET %token RSBRACKET %token COLON %token OP_PLUS %token OP_MINUS %token OP_MULT %token OP_DIV %token OP_REM %token OP_AND %token OP_OR %token OP_EQ %token OP_NEQ %token OP_LE %token OP_GE %token OP_LT %token OP_GT %token OP_NOT %token ASSIGN %token IF %token ELSE %token WHILE %token RETURN %token LENGTH %token INT %token IDENTIFIER %token CHAR %token BOOL %token T_BOOL %token T_INT (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------------------------------------------------- *) %% (* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv * Miejsce na gramatykę *) (* Obecnie potrafimy sparsować tylko pusty plik (wymagamy od razu tokena EOF) *) file: | declarations= list(func) EOF { ModuleDefinition {global_declarations=declarations } } | EOF { ModuleDefinition {global_declarations=[] } } func: | id=identifier LPAREN parameters=separated_list(COMMA,argument) RPAREN return=separated_list(COMMA,typ) body=option(statement_block) { GDECL_Function { loc=mkLocation $startpos; id=id;formal_parameters=parameters; return_types=return;body=body} } argument: | id = identifier COLON t=typ { VarDecl {loc=mkLocation $startpos;id=id;tp=t} } typ: | t=base_type { t } | t=typ LSBRACKET dim=option(expression) RSBRACKET { TEXPR_Array { loc=mkLocation $startpos; sub=t;dim=dim } } base_type: | T_INT {TEXPR_Int {loc=mkLocation $startpos} } | T_BOOL {TEXPR_Bool {loc=mkLocation $startpos} } expression: | node=expression_or {node} expression_or: | node=expression_and {node} | left=expression_or OP_OR right=expression_and {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Or;lhs=left;rhs=right } } expression_and: | node=expression_eq {node} | left=expression_and OP_AND right=expression_eq {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_And;lhs=left;rhs=right } } expression_eq: | node=expression_rel {node} | left=expression_eq OP_EQ right=expression_rel {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Eq;lhs=left;rhs=right } } | left=expression_eq OP_NEQ right=expression_rel {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Ne;lhs=left;rhs=right } } expression_rel: | node=expression_add {node} | left=expression_rel OP_LE right=expression_add {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Le;lhs=left;rhs=right } } | left=expression_rel OP_GE right=expression_add {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Ge;lhs=left;rhs=right } } | left=expression_rel OP_LT right=expression_add {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Lt;lhs=left;rhs=right } } | left=expression_rel OP_GT right=expression_add {EXPR_Relation {tag=mkTag ();loc=mkLocation $startpos; op=RELOP_Gt;lhs=left;rhs=right } } expression_add: | node=expression_mult { node } | left=expression_add OP_PLUS right=expression_mult {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Add;lhs=left;rhs=right } } | left=expression_add OP_MINUS right=expression_mult {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Sub;lhs=left;rhs=right } } expression_mult: | node=expression_unary { node } | left=expression_mult OP_MULT right=expression_unary {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Mult;lhs=left;rhs=right } } | left=expression_mult OP_DIV right=expression_unary {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Div;lhs=left;rhs=right } } | left=expression_mult OP_REM right=expression_unary {EXPR_Binop {tag=mkTag ();loc=mkLocation $startpos; op=BINOP_Rem;lhs=left;rhs=right } } expression_unary: | node=expression_highest { node } | OP_MINUS right=expression_unary {EXPR_Unop {tag=mkTag ();loc=mkLocation $startpos; op=UNOP_Neg;sub=right } } | OP_NOT right=expression_unary {EXPR_Unop {tag=mkTag ();loc=mkLocation $startpos; op=UNOP_Not;sub=right } } expression_highest: | node=expression_integer { node } | node=expression_identifier { node } (* TODO Add calls and arrays and other constants *) expression_integer: | value=INT { EXPR_Int {tag= mkTag ();loc=mkLocation $startpos; value=Int32.of_int value} } expression_identifier: | id=identifier { EXPR_Id {tag= mkTag ();loc=mkLocation $startpos; id=id} } statement_block: | LBRACKET body=list(statement) RBRACKET { STMTBlock { loc=mkLocation $startpos;body=body } } statement: | block=statement_block {STMT_Block block } identifier: | IDENTIFIER { Identifier $1 } (* ** przykład użycia mkLocation use_declaration: | USE suffix(identifier, opt(SEMICOLON)) { GDECL_Use {loc=mkLocation $startpos; id=$2} } ** przykład użycia mkTag atomic_expression: | identifier { EXPR_Id {loc=mkLocation $startpos; id=$1; tag=mkTag ()} } *) (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------------------------------------------------- *)