From f9ac80d948ecedcf9e04b94b5b529a31f23589a9 Mon Sep 17 00:00:00 2001 From: Alex AUVOLAT Date: Mon, 25 Nov 2013 15:06:21 +0100 Subject: Added localisation for expressions and statements. --- src/ast.ml | 30 ++++++++++++++++++++--------- src/parser.mly | 61 +++++++++++++++++++++++++++++++++++++++++++++------------- src/pretty.ml | 9 +++++---- 3 files changed, 74 insertions(+), 26 deletions(-) diff --git a/src/ast.ml b/src/ast.ml index f815c83..d23b573 100644 --- a/src/ast.ml +++ b/src/ast.ml @@ -12,6 +12,8 @@ let type_names = ref Sset.empty type ident = string type tident = string +type loc = Lexing.position * Lexing.position + type binop = | Equal | NotEqual | Lt | Le | Gt | Ge @@ -31,7 +33,10 @@ type var_type = | TRef of var_type | TIdent of tident -type expression = +type expression = { + e_loc: loc; + e_desc: expr_desc } +and expr_desc = | EInt of int | EBool of bool | ENull @@ -42,13 +47,19 @@ type expression = | EUnary of unop * expression | EBinary of expression * binop * expression | EMember of expression * ident - | ENew of ident * expression list + | ENew of tident * expression list -type str_expression = - | SEExpr of expression +type str_expression = { + se_loc: loc; + se_desc : se_desc } +and se_desc = + | SEExpr of expr_desc | SEStr of string -type statement = +type statement = { + s_loc: loc; + s_desc: s_desc } +and s_desc = | SEmpty | SExpr of expression | SIf of expression * statement * statement @@ -58,14 +69,15 @@ type statement = | SReturn of expression option | SDeclare of var_type * ident | SDeclareAssignExpr of var_type * ident * expression - | SDeclareAssignConstructor of var_type * ident * ident * expression list + | SDeclareAssignConstructor of var_type * ident * tident * expression list (* Type of variable, variable name, constructor class name, constructor arguments *) | SWriteCout of str_expression list and block = statement list type proto = { + p_loc : loc; p_name : ident; - p_class : ident option; (* p_class = none : standalone function *) + p_class : tident option; (* p_class = none : standalone function *) p_ret_type : var_type option; (* p_class = some and p_ret_type = none : constructor *) p_args : (var_type * ident) list; } @@ -76,8 +88,8 @@ type cls_mem = | CVirtualMethod of proto type cls = { - c_name : ident; - c_supers : ident list option; + c_name : tident; + c_supers : tident list option; c_members : cls_mem list; } diff --git a/src/parser.mly b/src/parser.mly index eb0a959..39fdf7d 100644 --- a/src/parser.mly +++ b/src/parser.mly @@ -111,10 +111,19 @@ member: cls_proto: | ident = typed_var LPAREN args = separated_list(COMMA, typed_var) RPAREN - { {p_ret_type = Some(fst ident); p_name = snd ident; p_class = None; p_args = args} } + { { + p_ret_type = Some(fst ident); + p_name = snd ident; + p_class = None; + p_args = args; + p_loc = $startpos, $endpos } } | cls = TIDENT LPAREN args = separated_list(COMMA, typed_var) RPAREN - { {p_ret_type = None; p_name = cls; p_class = Some cls; p_args = args} } + { {p_ret_type = None; + p_name = cls; + p_class = Some cls; + p_args = args; + p_loc = $startpos, $endpos } } ; proto: @@ -122,11 +131,11 @@ proto: LPAREN args = separated_list(COMMA, typed_var) RPAREN { let ty, cl, na = ident in - { p_ret_type = Some ty; p_name = na; p_class = cl; p_args = args} } + { p_ret_type = Some ty; p_name = na; p_class = cl; p_args = args; p_loc = $startpos, $endpos } } | cls = TIDENT DOUBLECOLON cls2 = TIDENT LPAREN args = separated_list(COMMA, typed_var) RPAREN { - {p_ret_type = None; p_name = cls2; p_class = Some cls; p_args = args} + {p_ret_type = None; p_name = cls2; p_class = Some cls; p_args = args; p_loc = $startpos, $endpos} } ; @@ -175,9 +184,12 @@ block: ; statement: +| d = statement_desc { { s_loc = $startpos, $endpos; s_desc = d } } +; +statement_desc: | k = common_statement { k } | IF LPAREN c = expression RPAREN s = statement - { SIf(c, s, SEmpty) } + { SIf(c, s, { s_loc = $startpos, $endpos; s_desc = SEmpty}) } | IF LPAREN c = expression RPAREN s = no_if_statement ELSE t = statement { SIf(c, s, t) } | WHILE LPAREN c = expression RPAREN s = statement @@ -190,6 +202,9 @@ statement: ; no_if_statement: +| d = no_if_statement_desc { { s_loc = $startpos, $endpos; s_desc = d } } +; +no_if_statement_desc: | WHILE LPAREN c = expression RPAREN s = no_if_statement { SWhile(c, s) } | FOR LPAREN k = separated_list(COMMA, expression) SEMICOLON @@ -221,10 +236,14 @@ common_statement: ; expression: +| e = expression_desc + { { e_loc = $startpos, $endpos; e_desc = e } } +| l = lunop { l } +; +expression_desc: | e1 = expression ASSIGN e2 = expression { EAssign(e1, e2) } | a = expression b = binop c = expression { EBinary(a, b, c) } | a = expression LPAREN arg = separated_list(COMMA, expression) RPAREN { ECall(a, arg) } -| a = lunop { a } | NEW c = TIDENT LPAREN args = separated_list(COMMA, expression) RPAREN { ENew(c, args) } ; @@ -245,24 +264,41 @@ expression: ; primary: +| LPAREN e = expression RPAREN + { { e_loc = $startpos, $endpos; e_desc = e.e_desc } } +| k = primary_desc + { { e_loc = $startpos, $endpos; e_desc = k } } +; +primary_desc: | NULL { ENull } | THIS { EThis } | i = INTVAL { EInt(i) } | TRUE { EBool(true) } | FALSE { EBool(false) } | i = IDENT { EIdent(i) } -| LPAREN e = expression RPAREN { e } -| a = primary RARROW b = IDENT { EMember(EUnary(Deref, a), b) } -| a = primary DOT b = IDENT { EMember(a, b) } +| a = primary RARROW b = IDENT + { EMember( + { e_loc = $startpos, $endpos; e_desc = EUnary(Deref, a)} + , b) } +| a = primary DOT b = IDENT + { EMember(a, b) } ; runop: -| e = primary { e } +| e = runop_desc { { e_loc = $startpos, $endpos; e_desc = e } } +| p = primary { p } +; +runop_desc: | e = runop INCR { EUnary(PostIncr, e) } | e = runop DECR { EUnary(PostDecr, e) } ; lunop: +| e = lunop_desc + { { e_loc = $startpos, $endpos; e_desc = e } } +| k = runop { k } +; +lunop_desc: | NOT e = lunop { EUnary(Not, e) } | MINUS e = lunop { EUnary(Minus, e) } | PLUS e = lunop { EUnary(Plus, e) } @@ -270,10 +306,9 @@ lunop: | TIMES e = lunop { EUnary(Deref, e) } | INCR e = lunop { EUnary(PreIncr, e) } | DECR e = lunop { EUnary(PreDecr, e) } -| e = runop { e } ; str_expression: -| e = expression { SEExpr(e) } -| s = STRVAL { SEStr(s) } +| e = expression { { se_loc = e.e_loc; se_desc = SEExpr(e.e_desc) } } +| s = STRVAL { { se_loc = $startpos, $endpos; se_desc = SEStr(s) } } ; diff --git a/src/pretty.ml b/src/pretty.ml index 1307bdf..e618bfa 100644 --- a/src/pretty.ml +++ b/src/pretty.ml @@ -84,7 +84,7 @@ let rec var_type_str = function | TVoid -> "void" | TInt -> "int" | TIdent(i) -> i | TPtr(k) -> "*" ^ (var_type_str k) | TRef(k) -> "&" ^ (var_type_str k) -let rec expr_string = function +let rec expr_string e = match e.e_desc with | EInt(i) -> string_of_int i | EBool(b) -> (if b then "true" else "false") | ENull -> "NULL" @@ -99,7 +99,7 @@ let rec expr_string = function let rec print_stmt l x = for i = 1 to l do print_string " " done; - match x with + match x.s_desc with | SEmpty -> print_string ";\n" | SExpr(e) -> print_string ((expr_string e) ^ "\n") | SIf(e, a, b) -> print_string ("if " ^ (expr_string e) ^ "\n"); @@ -124,8 +124,9 @@ let rec print_stmt l x = (i ^ " : " ^ (var_type_str t) ^ " = " ^ c ^ "(" ^ (csl expr_string a) ^ ")\n") | SWriteCout(k) -> print_string ("std::cout" ^ - (List.fold_left (fun x k -> x ^ " << " ^ (match k with - | SEExpr(k) -> expr_string k | SEStr("\n") -> "std::endl" | SEStr(s) -> "`" ^ s ^ "`")) "" k) ^ "\n") + (List.fold_left (fun x k -> x ^ " << " ^ (match k.se_desc with + | SEExpr(e) -> expr_string {e_loc = k.se_loc; e_desc = e} + | SEStr("\n") -> "std::endl" | SEStr(s) -> "`" ^ s ^ "`")) "" k) ^ "\n") and print_block n b = let prefix = String.make n ' ' in print_string (prefix ^ "{\n"); -- cgit v1.2.3