Compare commits

...

2 Commits

Author SHA1 Message Date
Arnaud DABY-SEESARAM
8ef4d035a3 Reject programs with var initialized twice 2022-12-13 10:26:55 +01:00
Arnaud DABY-SEESARAM
ef0effeb1f improvement over error messages (with code ;) ) 2022-12-13 10:26:55 +01:00
4 changed files with 52 additions and 18 deletions

4
src/config.ml Normal file
View File

@ -0,0 +1,4 @@
(** Maximum Number of variabnles declared in a sngle node.
* This corresponds to the sum of the number of local, input and output
* variables. *)
let maxvar = 100

View File

@ -65,19 +65,21 @@ let _ =
(** Main functionality below *) (** Main functionality below *)
print_verbose "Parsing the source file..."; print_verbose "Parsing the source file...";
let ast = let ast =
let inchan = open_in !source_file in
try try
begin begin
let inchan = open_in !source_file in
let res = Parser.main Lexer.token (Lexing.from_channel inchan) in let res = Parser.main Lexer.token (Lexing.from_channel inchan) in
close_in inchan; res close_in inchan; res
end end
with with
| Lexer.Lexing_error s -> | Lexer.Lexing_error s ->
(exit_error (Format.sprintf "Error code:\n\t%s\n\n" s); exit 0) (close_in_noerr inchan;
exit_error (Format.sprintf "Error code:\n\t%s\n\n" s); exit 0)
| Utils.MyParsingError (s, l) -> | Utils.MyParsingError (s, l) ->
begin begin
close_in_noerr inchan;
Format.printf "Syntax error at %a: %s\n\n" Format.printf "Syntax error at %a: %s\n\n"
Pp.pp_loc l s; Pp.pp_loc (l, !source_file) s;
exit 0 exit 0
end in end in

View File

@ -4,9 +4,9 @@
let current_location () = symbol_start_pos (), symbol_end_pos () let current_location () = symbol_start_pos (), symbol_end_pos ()
let defined_nodes : (ident, t_node) Hashtbl.t = Hashtbl.create 100 let defined_nodes : (ident, t_node) Hashtbl.t = Hashtbl.create Config.maxvar
let defined_vars : (ident, t_var) Hashtbl.t = Hashtbl.create 100 let defined_vars : (ident, t_var * bool) Hashtbl.t = Hashtbl.create Config.maxvar
let fetch_node (n: ident) = let fetch_node (n: ident) =
match Hashtbl.find_opt defined_nodes n with match Hashtbl.find_opt defined_nodes n with
@ -20,7 +20,19 @@
| None -> | None ->
raise (MyParsingError raise (MyParsingError
("The var "^n^" does not exist.", current_location())) ("The var "^n^" does not exist.", current_location()))
| Some var -> var | Some (var, _) -> var
let fetch_var_def (n: ident) : t_var =
match Hashtbl.find_opt defined_vars n with
| None ->
raise (MyParsingError
("The var "^n^" does not exist.", current_location()))
| Some (var, true) ->
raise (MyParsingError
("The variable "^n^" is defined for the second time.",
current_location()))
| Some (var, false) ->
(Hashtbl.replace defined_vars n (var, true) ; var)
let concat_varlist (t1, e1) (t2, e2) = (t1 @ t2, e1 @ e2) let concat_varlist (t1, e1) (t2, e2) = (t1 @ t2, e1 @ e2)
@ -205,11 +217,14 @@ param:
(list_repeat (List.length idents) typ, (list_repeat (List.length idents) typ,
match typ with match typ with
| TBool -> | TBool ->
List.map (fun s -> Hashtbl.add defined_vars s (BVar s); BVar s) idents List.map (fun s ->
Hashtbl.add defined_vars s (BVar s, false); BVar s) idents
| TReal -> | TReal ->
List.map (fun s -> Hashtbl.add defined_vars s (RVar s); RVar s) idents List.map (fun s ->
Hashtbl.add defined_vars s (RVar s, false); RVar s) idents
| TInt -> | TInt ->
List.map (fun s -> Hashtbl.add defined_vars s (IVar s); IVar s) idents) } List.map (fun s ->
Hashtbl.add defined_vars s (IVar s, false); IVar s) idents) }
; ;
ident_comma_list: ident_comma_list:
@ -233,12 +248,12 @@ equation:
pattern: pattern:
| IDENT | IDENT
{ let v = fetch_var $1 in (type_var v, [v]) } { let v = fetch_var_def $1 in (type_var v, [v]) }
| LPAREN ident_comma_list_patt RPAREN { $2 }; | LPAREN ident_comma_list_patt RPAREN { $2 };
ident_comma_list_patt: ident_comma_list_patt:
| IDENT { make_ident (fetch_var $1) } | IDENT { make_ident (fetch_var_def $1) }
| IDENT COMMA ident_comma_list_patt { add_ident (fetch_var $1) $3 } | IDENT COMMA ident_comma_list_patt { add_ident (fetch_var_def $1) $3 }
expr: expr:
/* Note: EQUAL does not follow the nomenclature CMP_, ... */ /* Note: EQUAL does not follow the nomenclature CMP_, ... */

View File

@ -6,12 +6,25 @@ open Ast
| TBool :: t -> Format.fprintf fmt "bool %a" debug_type_pp t | TBool :: t -> Format.fprintf fmt "bool %a" debug_type_pp t
| TReal :: t -> Format.fprintf fmt "real %a" debug_type_pp t | TReal :: t -> Format.fprintf fmt "real %a" debug_type_pp t
let pp_loc fmt (start, stop) = let pp_loc fmt ((start, stop), file) =
Lexing.( let spos, epos =
Format.fprintf fmt "%s: <l: %d, c: %d> -- <l: %d, c: %d>" Lexing.(start.pos_cnum, stop.pos_cnum) in
start.pos_fname let f = open_in file in
start.pos_lnum start.pos_cnum try
stop.pos_lnum stop.pos_cnum) begin
let rec aux linenum curpos =
let line = input_line f in
let nextpos = curpos + (String.length line) + 1 in
if nextpos >= epos then
Format.fprintf fmt "<line %d: %s >" linenum line
else
aux (linenum + 1) nextpos
in
aux 1 0;
close_in f
end
with e ->
(close_in_noerr f; Format.fprintf fmt "???")
let rec pp_varlist fmt : t_varlist -> unit = function let rec pp_varlist fmt : t_varlist -> unit = function
| ([], []) -> () | ([], []) -> ()