summary refs log tree commit diff
diff options
context:
space:
mode:
authorPaweł Dybiec <pdybiec@stud.cs.uni.wroc.pl>2018-11-07 11:47:16 +0100
committerPaweł Dybiec <pdybiec@stud.cs.uni.wroc.pl>2018-11-07 11:47:16 +0100
commitee27725c41749aa7bd52c450b1e0daa92ce4025c (patch)
treeaacd16e98c534258547ccfc850ec57de21bc5c24
parentFix ast rawprinter (diff)
Add semicolons, multi variable declaration. Fix returns
-rw-r--r--source/mod_student/lexer.mll2
-rw-r--r--source/mod_student/parser.mly51
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 <Xi_lib.Ast.module_definition> 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>STRING
 %token <char>CHAR
 %token <bool>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 ()} }
-*)
 
 (* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ----------------------------------------------------------------------------- *)