From ee27725c41749aa7bd52c450b1e0daa92ce4025c Mon Sep 17 00:00:00 2001 From: Paweł Dybiec Date: Wed, 7 Nov 2018 11:47:16 +0100 Subject: Add semicolons, multi variable declaration. Fix returns --- source/mod_student/lexer.mll | 2 ++ source/mod_student/parser.mly | 51 +++++++++++-------------------------------- 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/source/mod_student/lexer.mll b/source/mod_student/lexer.mll index 2a4b116..bfc279a 100644 --- a/source/mod_student/lexer.mll +++ b/source/mod_student/lexer.mll @@ -89,6 +89,7 @@ let implode l = | '"' str as e '"' { STRING (unescape e) } | "'" (chr as e) "'" { CHAR (unescape_chr e) } | "," { COMMA } + | ";" { SEMICOLON } | "(" { LPAREN } | ")" { RPAREN } | "{" { LBRACKET } @@ -118,6 +119,7 @@ let implode l = | "length" { LENGTH } | "int" { T_INT } | "bool" { T_BOOL } + | "_" { UNDERSCORE } | identifier as id { IDENTIFIER id } | integer as i { INT (int_of_string i) } diff --git a/source/mod_student/parser.mly b/source/mod_student/parser.mly index b039478..b55622b 100644 --- a/source/mod_student/parser.mly +++ b/source/mod_student/parser.mly @@ -1,6 +1,3 @@ -(* - * Menhir wygeneruje funkcję o nazwie file - *) %start file %{ @@ -8,7 +5,6 @@ open Xi_lib open Ast open Parser_utils -(* Generator znaczników *) let mkTag = let i = ref 0 in fun () -> @@ -16,21 +12,13 @@ let mkTag = incr i; NodeTag tag -(* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - * Miejsce na twój kod w Ocamlu - *) - -(* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - ----------------------------------------------------------------------------- *) %} -(* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv - * Miejsce na dyrektywy - *) %token EOF %token COMMA +%token SEMICOLON %token LPAREN %token RPAREN %token LBRACKET @@ -63,20 +51,13 @@ let mkTag = %token STRING %token CHAR %token BOOL +%token UNDERSCORE %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 } } @@ -90,6 +71,9 @@ func: var_decl: | id = identifier COLON t=typ { VarDecl {loc=mkLocation $startpos;id=id;tp=t} } +option_var_decl: + | decl=var_decl { Some decl } + | UNDERSCORE { None } return_type: | return = option(preceded(COLON,separated_list(COMMA,typ) ) ) { match return with @@ -192,8 +176,8 @@ expression_length: { EXPR_Length { tag=mkTag (); loc=mkLocation $startpos; arg=argument } } statement_block: - | LBRACKET body=list(statement) RBRACKET { STMTBlock { - loc=mkLocation $startpos;body=body } } + | LBRACKET body=append(terminated(separated_list(semicolons,statement),semicolons),loption(terminated(return_stmt,semicolons))) RBRACKET + { STMTBlock { loc=mkLocation $startpos;body=body } } statement: | left=lvalue ASSIGN right=expression { STMT_Assign {loc=mkLocation $startpos; lhs=left;rhs=right} } @@ -206,8 +190,11 @@ statement: | IF cond=expression then_branch=statement else_branch=option(preceded(ELSE,statement)) { STMT_If {loc=mkLocation $startpos;cond=cond;then_branch=then_branch; else_branch=else_branch } } + | head=option_var_decl COMMA tail=separated_nonempty_list(COMMA, option_var_decl) ASSIGN call=call + { STMT_MultiVarDecl {loc=mkLocation $startpos; vars= (*head::*)tail; init=call } } +return_stmt: | RETURN values=separated_list(COMMA,expression) - { STMT_Return {loc=mkLocation $startpos;values=values } } + { [STMT_Return { loc=mkLocation $startpos; values=values }] } call: | callee=identifier LPAREN arguments=separated_list(COMMA,expression) RPAREN { Call { tag=mkTag (); loc=mkLocation $startpos; @@ -216,24 +203,12 @@ call: lvalue: | id=identifier {LVALUE_Id {loc=mkLocation $startpos;id=id} } (* TODO lvalue index *) - +semicolons: + | list(SEMICOLON) {} 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 ()} } -*) (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ----------------------------------------------------------------------------- *) -- cgit 1.4.1