diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 1997-08-22 08:55:41 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 1997-08-22 08:55:41 +0000 |
commit | 579e1523e94f7fef3d11346207161beea667b9dc (patch) | |
tree | c41dd7d0041ef03ce58e40772b3a3ac612c9e7f7 | |
parent | 23686e53207f43ee1b913095acc964063a36281f (diff) |
Meilleures erreurs de syntaxe pour les parentheses mal fermees, etc
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@1689 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r-- | .depend | 43 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | Makefile.Mac | 4 | ||||
-rw-r--r-- | Makefile.nt | 3 | ||||
-rw-r--r-- | driver/compile.ml | 2 | ||||
-rw-r--r-- | driver/errors.ml | 5 | ||||
-rw-r--r-- | driver/optcompile.ml | 2 | ||||
-rw-r--r-- | driver/opterrors.ml | 5 | ||||
-rw-r--r-- | parsing/parse.ml | 12 | ||||
-rw-r--r-- | parsing/parse.mli | 1 | ||||
-rw-r--r-- | parsing/parser.mly | 56 | ||||
-rw-r--r-- | parsing/syntaxerr.ml | 47 | ||||
-rw-r--r-- | parsing/syntaxerr.mli | 22 | ||||
-rw-r--r-- | tools/Makefile | 2 | ||||
-rw-r--r-- | tools/Makefile.Mac | 2 | ||||
-rw-r--r-- | tools/Makefile.nt | 2 | ||||
-rw-r--r-- | tools/ocamlprof.ml | 5 |
17 files changed, 172 insertions, 44 deletions
@@ -15,11 +15,12 @@ utils/tbl.cmx: utils/tbl.cmi utils/terminfo.cmo: utils/terminfo.cmi utils/terminfo.cmx: utils/terminfo.cmi parsing/lexer.cmi: parsing/parser.cmi -parsing/parse.cmi: parsing/parsetree.cmi +parsing/parse.cmi: parsing/parsetree.cmi parsing/syntaxerr.cmi parsing/parser.cmi: parsing/parsetree.cmi parsing/parsetree.cmi: parsing/asttypes.cmi parsing/location.cmi \ parsing/longident.cmi parsing/pstream.cmi: parsing/parsetree.cmi +parsing/syntaxerr.cmi: parsing/location.cmi parsing/lexer.cmo: utils/misc.cmi parsing/parser.cmi parsing/lexer.cmi parsing/lexer.cmx: utils/misc.cmx parsing/parser.cmx parsing/lexer.cmi parsing/linenum.cmo: utils/misc.cmi parsing/linenum.cmi @@ -31,9 +32,9 @@ parsing/location.cmx: parsing/linenum.cmx utils/terminfo.cmx \ parsing/longident.cmo: utils/misc.cmi parsing/longident.cmi parsing/longident.cmx: utils/misc.cmx parsing/longident.cmi parsing/parse.cmo: parsing/lexer.cmi parsing/location.cmi parsing/parser.cmi \ - parsing/parse.cmi + parsing/syntaxerr.cmi parsing/parse.cmi parsing/parse.cmx: parsing/lexer.cmx parsing/location.cmx parsing/parser.cmx \ - parsing/parse.cmi + parsing/syntaxerr.cmx parsing/parse.cmi parsing/parser.cmo: parsing/asttypes.cmi utils/clflags.cmo \ parsing/location.cmi parsing/longident.cmi parsing/parsetree.cmi \ parsing/pstream.cmi parsing/parser.cmi @@ -44,6 +45,8 @@ parsing/pstream.cmo: parsing/asttypes.cmi parsing/location.cmi \ parsing/longident.cmi parsing/parsetree.cmi parsing/pstream.cmi parsing/pstream.cmx: parsing/asttypes.cmi parsing/location.cmx \ parsing/longident.cmx parsing/parsetree.cmi parsing/pstream.cmi +parsing/syntaxerr.cmo: parsing/location.cmi parsing/syntaxerr.cmi +parsing/syntaxerr.cmx: parsing/location.cmx parsing/syntaxerr.cmi typing/btype.cmi: typing/path.cmi typing/types.cmi typing/ctype.cmi: parsing/asttypes.cmi typing/env.cmi typing/ident.cmi \ typing/types.cmi @@ -361,8 +364,6 @@ asmcomp/selectgen.cmi: asmcomp/arch.cmo asmcomp/cmm.cmi typing/ident.cmi \ asmcomp/selection.cmi: asmcomp/cmm.cmi asmcomp/mach.cmi asmcomp/spill.cmi: asmcomp/mach.cmi asmcomp/split.cmi: asmcomp/mach.cmi -asmcomp/arch.cmo: utils/config.cmi -asmcomp/arch.cmx: utils/config.cmx asmcomp/asmgen.cmo: utils/clflags.cmo asmcomp/closure.cmi asmcomp/cmm.cmi \ asmcomp/cmmgen.cmi asmcomp/coloring.cmi utils/config.cmi asmcomp/emit.cmi \ asmcomp/emitaux.cmi asmcomp/interf.cmi asmcomp/linearize.cmi \ @@ -435,12 +436,12 @@ asmcomp/compilenv.cmx: asmcomp/clambda.cmx utils/config.cmx typing/env.cmx \ typing/ident.cmx utils/misc.cmx asmcomp/compilenv.cmi asmcomp/emit.cmo: asmcomp/arch.cmo asmcomp/cmm.cmi asmcomp/compilenv.cmi \ utils/config.cmi asmcomp/emitaux.cmi asmcomp/linearize.cmi \ - parsing/location.cmi asmcomp/mach.cmi utils/misc.cmi utils/nativeint.cmi \ - asmcomp/proc.cmi asmcomp/reg.cmi asmcomp/emit.cmi + asmcomp/mach.cmi utils/misc.cmi utils/nativeint.cmi asmcomp/proc.cmi \ + asmcomp/reg.cmi asmcomp/emit.cmi asmcomp/emit.cmx: asmcomp/arch.cmx asmcomp/cmm.cmx asmcomp/compilenv.cmx \ utils/config.cmx asmcomp/emitaux.cmx asmcomp/linearize.cmx \ - parsing/location.cmx asmcomp/mach.cmx utils/misc.cmx utils/nativeint.cmx \ - asmcomp/proc.cmx asmcomp/reg.cmx asmcomp/emit.cmi + asmcomp/mach.cmx utils/misc.cmx utils/nativeint.cmx asmcomp/proc.cmx \ + asmcomp/reg.cmx asmcomp/emit.cmi asmcomp/emitaux.cmo: utils/nativeint.cmi asmcomp/emitaux.cmi asmcomp/emitaux.cmx: utils/nativeint.cmx asmcomp/emitaux.cmi asmcomp/interf.cmo: asmcomp/mach.cmi asmcomp/proc.cmi asmcomp/reg.cmi \ @@ -479,8 +480,10 @@ asmcomp/proc.cmx: asmcomp/arch.cmx utils/ccomp.cmx asmcomp/cmm.cmx \ asmcomp/mach.cmx utils/misc.cmx asmcomp/reg.cmx asmcomp/proc.cmi asmcomp/reg.cmo: asmcomp/cmm.cmi asmcomp/reg.cmi asmcomp/reg.cmx: asmcomp/cmm.cmx asmcomp/reg.cmi -asmcomp/reload.cmo: asmcomp/reloadgen.cmi asmcomp/reload.cmi -asmcomp/reload.cmx: asmcomp/reloadgen.cmx asmcomp/reload.cmi +asmcomp/reload.cmo: asmcomp/arch.cmo asmcomp/cmm.cmi asmcomp/mach.cmi \ + asmcomp/reg.cmi asmcomp/reloadgen.cmi asmcomp/reload.cmi +asmcomp/reload.cmx: asmcomp/arch.cmx asmcomp/cmm.cmx asmcomp/mach.cmx \ + asmcomp/reg.cmx asmcomp/reloadgen.cmx asmcomp/reload.cmi asmcomp/reloadgen.cmo: asmcomp/mach.cmi utils/misc.cmi asmcomp/reg.cmi \ asmcomp/reloadgen.cmi asmcomp/reloadgen.cmx: asmcomp/mach.cmx utils/misc.cmx asmcomp/reg.cmx \ @@ -489,10 +492,8 @@ asmcomp/schedgen.cmo: asmcomp/arch.cmo asmcomp/cmm.cmi asmcomp/linearize.cmi \ asmcomp/mach.cmi utils/misc.cmi asmcomp/reg.cmi asmcomp/schedgen.cmi asmcomp/schedgen.cmx: asmcomp/arch.cmx asmcomp/cmm.cmx asmcomp/linearize.cmx \ asmcomp/mach.cmx utils/misc.cmx asmcomp/reg.cmx asmcomp/schedgen.cmi -asmcomp/scheduling.cmo: asmcomp/arch.cmo asmcomp/mach.cmi \ - asmcomp/schedgen.cmi asmcomp/scheduling.cmi -asmcomp/scheduling.cmx: asmcomp/arch.cmx asmcomp/mach.cmx \ - asmcomp/schedgen.cmx asmcomp/scheduling.cmi +asmcomp/scheduling.cmo: asmcomp/schedgen.cmi asmcomp/scheduling.cmi +asmcomp/scheduling.cmx: asmcomp/schedgen.cmx asmcomp/scheduling.cmi asmcomp/selectgen.cmo: asmcomp/arch.cmo asmcomp/cmm.cmi typing/ident.cmi \ asmcomp/mach.cmi utils/misc.cmi utils/nativeint.cmi asmcomp/proc.cmi \ asmcomp/reg.cmi utils/tbl.cmi asmcomp/selectgen.cmi @@ -500,10 +501,10 @@ asmcomp/selectgen.cmx: asmcomp/arch.cmx asmcomp/cmm.cmx typing/ident.cmx \ asmcomp/mach.cmx utils/misc.cmx utils/nativeint.cmx asmcomp/proc.cmx \ asmcomp/reg.cmx utils/tbl.cmx asmcomp/selectgen.cmi asmcomp/selection.cmo: asmcomp/arch.cmo asmcomp/cmm.cmi asmcomp/mach.cmi \ - utils/misc.cmi asmcomp/reg.cmi asmcomp/selectgen.cmi \ + utils/misc.cmi asmcomp/proc.cmi asmcomp/reg.cmi asmcomp/selectgen.cmi \ asmcomp/selection.cmi asmcomp/selection.cmx: asmcomp/arch.cmx asmcomp/cmm.cmx asmcomp/mach.cmx \ - utils/misc.cmx asmcomp/reg.cmx asmcomp/selectgen.cmx \ + utils/misc.cmx asmcomp/proc.cmx asmcomp/reg.cmx asmcomp/selectgen.cmx \ asmcomp/selection.cmi asmcomp/spill.cmo: asmcomp/mach.cmi asmcomp/proc.cmi asmcomp/reg.cmi \ asmcomp/spill.cmi @@ -527,13 +528,13 @@ driver/compile.cmx: bytecomp/bytegen.cmx utils/ccomp.cmx utils/clflags.cmx \ typing/typedtree.cmx typing/typemod.cmx driver/compile.cmi driver/errors.cmo: bytecomp/bytelibrarian.cmi bytecomp/bytelink.cmi \ typing/env.cmi typing/includemod.cmi parsing/lexer.cmi \ - parsing/location.cmi parsing/parse.cmi bytecomp/symtable.cmi \ + parsing/location.cmi bytecomp/symtable.cmi parsing/syntaxerr.cmi \ bytecomp/translcore.cmi typing/typeclass.cmi typing/typecore.cmi \ typing/typedecl.cmi typing/typemod.cmi typing/typetexp.cmi \ driver/errors.cmi driver/errors.cmx: bytecomp/bytelibrarian.cmx bytecomp/bytelink.cmx \ typing/env.cmx typing/includemod.cmx parsing/lexer.cmx \ - parsing/location.cmx parsing/parse.cmx bytecomp/symtable.cmx \ + parsing/location.cmx bytecomp/symtable.cmx parsing/syntaxerr.cmx \ bytecomp/translcore.cmx typing/typeclass.cmx typing/typecore.cmx \ typing/typedecl.cmx typing/typemod.cmx typing/typetexp.cmx \ driver/errors.cmi @@ -556,13 +557,13 @@ driver/optcompile.cmx: asmcomp/asmgen.cmx utils/ccomp.cmx utils/clflags.cmx \ driver/opterrors.cmo: asmcomp/asmgen.cmi asmcomp/asmlibrarian.cmi \ asmcomp/asmlink.cmi asmcomp/compilenv.cmi typing/env.cmi \ typing/includemod.cmi parsing/lexer.cmi parsing/location.cmi \ - parsing/parse.cmi bytecomp/translcore.cmi typing/typeclass.cmi \ + parsing/syntaxerr.cmi bytecomp/translcore.cmi typing/typeclass.cmi \ typing/typecore.cmi typing/typedecl.cmi typing/typemod.cmi \ typing/typetexp.cmi driver/opterrors.cmi driver/opterrors.cmx: asmcomp/asmgen.cmx asmcomp/asmlibrarian.cmx \ asmcomp/asmlink.cmx asmcomp/compilenv.cmx typing/env.cmx \ typing/includemod.cmx parsing/lexer.cmx parsing/location.cmx \ - parsing/parse.cmx bytecomp/translcore.cmx typing/typeclass.cmx \ + parsing/syntaxerr.cmx bytecomp/translcore.cmx typing/typeclass.cmx \ typing/typecore.cmx typing/typedecl.cmx typing/typemod.cmx \ typing/typetexp.cmx driver/opterrors.cmi driver/optmain.cmo: asmcomp/asmlibrarian.cmi asmcomp/asmlink.cmi \ @@ -23,7 +23,8 @@ UTILS=utils/misc.cmo utils/tbl.cmo utils/config.cmo \ OPTUTILS=$(UTILS) utils/nativeint.cmo PARSING=parsing/linenum.cmo parsing/location.cmo parsing/longident.cmo \ - parsing/pstream.cmo parsing/parser.cmo parsing/lexer.cmo parsing/parse.cmo + parsing/syntaxerr.cmo parsing/pstream.cmo parsing/parser.cmo \ + parsing/lexer.cmo parsing/parse.cmo TYPING=typing/ident.cmo typing/path.cmo \ typing/primitive.cmo typing/types.cmo \ diff --git a/Makefile.Mac b/Makefile.Mac index 9cca910f4..3a5636919 100644 --- a/Makefile.Mac +++ b/Makefile.Mac @@ -19,8 +19,8 @@ UTILS = :utils:misc.cmo :utils:tbl.cmo :utils:config.cmo ¶ :utils:clflags.cmo :utils:terminfo.cmo :utils:ccomp.cmo PARSING = :parsing:linenum.cmo :parsing:location.cmo :parsing:longident.cmo ¶ - :parsing:pstream.cmo :parsing:parser.cmo :parsing:lexer.cmo ¶ - :parsing:parse.cmo + :parsing:syntaxerr.cmo :parsing:pstream.cmo :parsing:parser.cmo ¶ + :parsing:lexer.cmo :parsing:parse.cmo TYPING = :typing:ident.cmo :typing:path.cmo ¶ :typing:primitive.cmo :typing:types.cmo ¶ diff --git a/Makefile.nt b/Makefile.nt index 872ab87d6..1d5705f78 100644 --- a/Makefile.nt +++ b/Makefile.nt @@ -21,7 +21,8 @@ UTILS=utils\misc.cmo utils\tbl.cmo utils\config.cmo \ OPTUTILS=$(UTILS) utils\nativeint.cmo PARSING=parsing\linenum.cmo parsing\location.cmo parsing\longident.cmo \ - parsing\pstream.cmo parsing\parser.cmo parsing\lexer.cmo parsing\parse.cmo + parsing\syntaxerr.cmo parsing\pstream.cmo parsing\parser.cmo \ + parsing\lexer.cmo parsing\parse.cmo TYPING=typing\ident.cmo typing\path.cmo \ typing\primitive.cmo typing\types.cmo \ diff --git a/driver/compile.ml b/driver/compile.ml index 285db4743..d79101792 100644 --- a/driver/compile.ml +++ b/driver/compile.ml @@ -77,7 +77,7 @@ let parse_file inputfile parse_fun ast_magic = else false with Outdated_version -> - failwith "Ocaml and preprocessor have incompatible versions" + fatal_error "Ocaml and preprocessor have incompatible versions" | _ -> false in let ast = diff --git a/driver/errors.ml b/driver/errors.ml index c93f6f3eb..6b032f782 100644 --- a/driver/errors.ml +++ b/driver/errors.ml @@ -24,9 +24,8 @@ let report_error exn = Lexer.Error(err, start, stop) -> Location.print {loc_start = start; loc_end = stop}; Lexer.report_error err - | Parse.Error(start, stop) -> - Location.print {loc_start = start; loc_end = stop}; - print_string "Syntax error" + | Syntaxerr.Error err -> + Syntaxerr.report_error err | Env.Error err -> Env.report_error err | Typecore.Error(loc, err) -> diff --git a/driver/optcompile.ml b/driver/optcompile.ml index 7d1e67a94..897f03910 100644 --- a/driver/optcompile.ml +++ b/driver/optcompile.ml @@ -74,7 +74,7 @@ let parse_file inputfile parse_fun ast_magic = else false with Outdated_version -> - failwith "Ocaml and preprocessor have incompatible versions" + fatal_error "Ocaml and preprocessor have incompatible versions" | _ -> false in let ast = diff --git a/driver/opterrors.ml b/driver/opterrors.ml index 01b3f4dd4..a5910355d 100644 --- a/driver/opterrors.ml +++ b/driver/opterrors.ml @@ -24,9 +24,8 @@ let report_error exn = Lexer.Error(err, start, stop) -> Location.print {loc_start = start; loc_end = stop}; Lexer.report_error err - | Parse.Error(start, stop) -> - Location.print {loc_start = start; loc_end = stop}; - print_string "Syntax error" + | Syntaxerr.Error err -> + Syntaxerr.report_error err | Env.Error err -> Env.report_error err | Typecore.Error(loc, err) -> diff --git a/parsing/parse.ml b/parsing/parse.ml index 02a9a56fa..a04571f01 100644 --- a/parsing/parse.ml +++ b/parsing/parse.ml @@ -13,7 +13,8 @@ (* Entry points in the parser *) -exception Error of int * int (* Syntax error *) +open Location + (* Skip tokens to the end of the phrase *) let rec skip_phrase lexbuf = @@ -43,12 +44,15 @@ let wrap parsing_fun lexbuf = | Lexer.Error(_, _, _) as err -> if !Location.input_name = "" then skip_phrase lexbuf; raise err + | Syntaxerr.Error _ as err -> + if !Location.input_name = "" then maybe_skip_phrase lexbuf; + raise err | Parsing.Parse_error -> - let start = Lexing.lexeme_start lexbuf - and stop = Lexing.lexeme_end lexbuf in + let loc = { loc_start = Lexing.lexeme_start lexbuf; + loc_end = Lexing.lexeme_end lexbuf } in if !Location.input_name = "" then maybe_skip_phrase lexbuf; - raise(Error(start, stop)) + raise(Syntaxerr.Error(Syntaxerr.Other loc)) let implementation = wrap Parser.implementation and interface = wrap Parser.interface diff --git a/parsing/parse.mli b/parsing/parse.mli index ddd58daa1..2becb1271 100644 --- a/parsing/parse.mli +++ b/parsing/parse.mli @@ -18,4 +18,3 @@ val interface : Lexing.lexbuf -> Parsetree.signature val toplevel_phrase : Lexing.lexbuf -> Parsetree.toplevel_phrase val use_file : Lexing.lexbuf -> Parsetree.toplevel_phrase list -exception Error of int * int (* Syntax error *) diff --git a/parsing/parser.mly b/parsing/parser.mly index 79a5ef3cf..74c90f1e7 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -96,6 +96,10 @@ let rec mkrangepat c1 c2 = mkpat(Ppat_or(mkpat(Ppat_constant(Const_char c1)), mkrangepat (Char.chr(Char.code c1 + 1)) c2)) +let unclosed opening_name opening_num closing_name closing_num = + raise(Syntaxerr.Error(Syntaxerr.Unclosed(rhs_loc opening_num, opening_name, + rhs_loc closing_num, closing_name))) + %} /* Tokens */ @@ -277,15 +281,23 @@ module_expr: { mkmod(Pmod_ident $1) } | STRUCT structure END { mkmod(Pmod_structure($2)) } + | STRUCT structure error + { unclosed "struct" 1 "end" 3 } | FUNCTOR LPAREN UIDENT COLON module_type RPAREN MINUSGREATER module_expr %prec prec_fun { mkmod(Pmod_functor($3, $5, $8)) } | module_expr LPAREN module_expr RPAREN { mkmod(Pmod_apply($1, $3)) } + | module_expr LPAREN module_expr error + { unclosed "(" 2 ")" 4 } | LPAREN module_expr COLON module_type RPAREN { mkmod(Pmod_constraint($2, $4)) } + | LPAREN module_expr COLON module_type error + { unclosed "(" 1 ")" 5 } | LPAREN module_expr RPAREN { $2 } + | LPAREN module_expr error + { unclosed "(" 1 ")" 3 } ; structure: structure_tail { $1 } @@ -317,6 +329,8 @@ structure_item: { mkstr(Pstr_open $2) } | CLASS class_list END { mkstr(Pstr_class (List.rev $2)) } + | CLASS class_list error + { unclosed "class" 1 "end" 3 } ; module_binding: EQUAL module_expr @@ -334,6 +348,8 @@ module_type: { mkmty(Pmty_ident $1) } | SIG signature END { mkmty(Pmty_signature(List.rev $2)) } + | SIG signature error + { unclosed "sig" 1 "end" 3 } | FUNCTOR LPAREN UIDENT COLON module_type RPAREN MINUSGREATER module_type %prec prec_fun { mkmty(Pmty_functor($3, $5, $8)) } @@ -341,6 +357,8 @@ module_type: { mkmty(Pmty_with($1, List.rev $3)) } | LPAREN module_type RPAREN { $2 } + | LPAREN module_type error + { unclosed "(" 1 ")" 3 } ; signature: /* empty */ { [] } @@ -391,6 +409,8 @@ expr: { mkexp(Pexp_apply($1, List.rev $2)) } | LET rec_flag let_bindings IN seq_expr %prec prec_let { mkexp(Pexp_let($2, List.rev $3, $5)) } + | LET rec_flag let_bindings error %prec prec_let + { unclosed "let" 1 "in" 4 } | PARSER opt_pat opt_bar parser_cases %prec prec_fun { Pstream.cparser ($2, List.rev $4) } | FUNCTION opt_bar match_cases %prec prec_fun @@ -403,6 +423,8 @@ expr: { mkexp(Pexp_apply(Pstream.cparser ($5, List.rev $7), [$2])) } | TRY seq_expr WITH opt_bar match_cases %prec prec_try { mkexp(Pexp_try($2, List.rev $5)) } + | TRY seq_expr error %prec prec_try + { unclosed "try" 1 "with" 3 } | expr_comma_list { mkexp(Pexp_tuple(List.rev $1)) } | constr_longident simple_expr %prec prec_constr_appl @@ -413,8 +435,12 @@ expr: { mkexp(Pexp_ifthenelse($2, $4, None)) } | WHILE seq_expr DO seq_expr DONE { mkexp(Pexp_while($2, $4)) } + | WHILE seq_expr DO seq_expr error + { unclosed "while" 1 "done" 5 } | FOR val_ident EQUAL seq_expr direction_flag seq_expr DO seq_expr DONE { mkexp(Pexp_for($2, $4, $6, $5, $8)) } + | FOR val_ident EQUAL seq_expr direction_flag seq_expr DO seq_expr error + { unclosed "for" 1 "done" 9 } | expr COLONCOLON expr { mkexp(Pexp_construct(Lident "::", Some(mkexp(Pexp_tuple[$1;$3])), false)) } | expr INFIXOP0 expr @@ -471,30 +497,48 @@ simple_expr: { mkexp(Pexp_construct($1, None, false)) } | LPAREN seq_expr RPAREN { $2 } + | LPAREN seq_expr error + { unclosed "(" 1 ")" 3 } | BEGIN seq_expr END { $2 } + | BEGIN seq_expr error + { unclosed "begin" 1 "end" 3 } | LPAREN seq_expr type_constraint RPAREN { let (t, t') = $3 in mkexp(Pexp_constraint($2, t, t')) } + | LPAREN seq_expr type_constraint error + { unclosed "(" 1 ")" 4 } | simple_expr DOT label_longident { mkexp(Pexp_field($1, $3)) } | simple_expr DOT LPAREN seq_expr RPAREN { mkexp(Pexp_apply(mkexp(Pexp_ident(array_function "Array" "get")), [$1; $4])) } + | simple_expr DOT LPAREN seq_expr error + { unclosed "(" 3 ")" 5 } | simple_expr DOT LBRACKET seq_expr RBRACKET { mkexp(Pexp_apply(mkexp(Pexp_ident(array_function "String" "get")), [$1; $4])) } + | simple_expr DOT LBRACKET seq_expr error + { unclosed "[" 3 "]" 5 } | LBRACE lbl_expr_list opt_semi RBRACE { mkexp(Pexp_record(List.rev $2)) } + | LBRACE lbl_expr_list opt_semi error + { unclosed "{" 1 "}" 4 } | LBRACKETLESS stream_expr opt_semi GREATERRBRACKET { Pstream.cstream (List.rev $2) } + | LBRACKETLESS stream_expr opt_semi error + { unclosed "[<" 1 ">]" 4 } | LBRACKETLESS GREATERRBRACKET { Pstream.cstream [] } | LBRACKETBAR expr_semi_list opt_semi BARRBRACKET { mkexp(Pexp_array(List.rev $2)) } + | LBRACKETBAR expr_semi_list opt_semi error + { unclosed "[|" 1 "|]" 4 } | LBRACKETBAR BARRBRACKET { mkexp(Pexp_array []) } | LBRACKET expr_semi_list opt_semi RBRACKET { mklistexp(List.rev $2) } + | LBRACKET expr_semi_list opt_semi error + { unclosed "[" 1 "]" 4 } | PREFIXOP simple_expr { mkexp(Pexp_apply(mkoperator $1 1, [$2])) } | simple_expr SHARP label @@ -503,6 +547,8 @@ simple_expr: { mkexp(Pexp_new($2)) } | LBRACELESS label_expr_list opt_semi GREATERRBRACE { mkexp(Pexp_override(List.rev $2)) } + | LBRACELESS label_expr_list opt_semi error + { unclosed "{<" 1 ">}" 4 } | LBRACELESS GREATERRBRACE { mkexp(Pexp_override []) } | LPAREN SHARP label RPAREN @@ -541,6 +587,8 @@ parser_case: LBRACKETLESS stream_pattern opt_semi GREATERRBRACKET opt_pat MINUSGREATER seq_expr { (List.rev $2, $5, $7) } + | LBRACKETLESS stream_pattern opt_semi error + { unclosed "[<" 1 ">]" 4 } | LBRACKETLESS GREATERRBRACKET opt_pat MINUSGREATER seq_expr { ([], $3, $5) } ; @@ -642,12 +690,20 @@ simple_pattern: { mkpat(Ppat_construct($1, None, false)) } | LBRACE lbl_pattern_list opt_semi RBRACE { mkpat(Ppat_record(List.rev $2)) } + | LBRACE lbl_pattern_list opt_semi error + { unclosed "{" 1 "}" 4 } | LBRACKET pattern_semi_list opt_semi RBRACKET { mklistpat(List.rev $2) } + | LBRACKET pattern_semi_list opt_semi error + { unclosed "{" 1 "}" 4 } | LPAREN pattern RPAREN { $2 } + | LPAREN pattern error + { unclosed "(" 1 ")" 3 } | LPAREN pattern COLON core_type RPAREN { mkpat(Ppat_constraint($2, $4)) } + | LPAREN pattern COLON core_type error + { unclosed "(" 1 ")" 5 } ; pattern_comma_list: diff --git a/parsing/syntaxerr.ml b/parsing/syntaxerr.ml new file mode 100644 index 000000000..6b87819b0 --- /dev/null +++ b/parsing/syntaxerr.ml @@ -0,0 +1,47 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1997 Institut National de Recherche en Informatique et *) +(* Automatique. Distributed only by permission. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* Auxiliary type for reporting syntax errors *) + +open Format + +type error = + Unclosed of Location.t * string * Location.t * string + | Other of Location.t + +exception Error of error + +let report_error = function + Unclosed(opening_loc, opening, closing_loc, closing) -> + if String.length !Location.input_name > 0 then begin + Location.print closing_loc; + print_string "Syntax error: missing '"; + print_string closing; + print_string "'"; force_newline(); + Location.print opening_loc; + print_string "This is the location of the unmatched '"; + print_string opening; + print_string "'" + end else begin + Location.print opening_loc; + print_string "Syntax error: this '"; + print_string opening; + print_string "' has no matching '"; + print_string closing; + print_string "'" + end + | Other loc -> + Location.print loc; + print_string "Syntax error" + + diff --git a/parsing/syntaxerr.mli b/parsing/syntaxerr.mli new file mode 100644 index 000000000..dd69c8551 --- /dev/null +++ b/parsing/syntaxerr.mli @@ -0,0 +1,22 @@ +(***********************************************************************) +(* *) +(* Objective Caml *) +(* *) +(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) +(* *) +(* Copyright 1997 Institut National de Recherche en Informatique et *) +(* Automatique. Distributed only by permission. *) +(* *) +(***********************************************************************) + +(* $Id$ *) + +(* Auxiliary type for reporting syntax errors *) + +type error = + Unclosed of Location.t * string * Location.t * string + | Other of Location.t + +exception Error of error + +val report_error: error -> unit diff --git a/tools/Makefile b/tools/Makefile index 017738958..3dc8800b8 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -35,7 +35,7 @@ beforedepend:: ocamldep.ml CSLPROF=ocamlprof.cmo CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ linenum.cmo location.cmo longident.cmo pstream.cmo \ - parser.cmo lexer.cmo parse.cmo + syntaxerr.cmo parser.cmo lexer.cmo parse.cmo ocamlprof: $(CSLPROF) profiling.cmo $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF) diff --git a/tools/Makefile.Mac b/tools/Makefile.Mac index 154901a84..19f8647b2 100644 --- a/tools/Makefile.Mac +++ b/tools/Makefile.Mac @@ -33,7 +33,7 @@ beforedepend ÄÄ ocamldep #CSLPROF = ocamlprof.cmo #CSLPROF_IMPORTS = misc.cmo config.cmo clflags.cmo terminfo.cmo ¶ # linenum.cmo location.cmo longident.cmo pstream.cmo ¶ -# parser.cmo lexer.cmo parse.cmo +# syntaxerr.cmo parser.cmo lexer.cmo parse.cmo # #ocamlprof Ä {CSLPROF} profiling.cmo # {CAMLC} {LINKFLAGS} -o ocamlprof {CSLPROF_IMPORTS} {CSLPROF} diff --git a/tools/Makefile.nt b/tools/Makefile.nt index 135e42792..cf3a42d81 100644 --- a/tools/Makefile.nt +++ b/tools/Makefile.nt @@ -35,7 +35,7 @@ beforedepend:: ocamldep.ml CSLPROF=ocamlprof.cmo CSLPROF_IMPORTS=misc.cmo config.cmo clflags.cmo terminfo.cmo \ linenum.cmo location.cmo longident.cmo pstream.cmo \ - parser.cmo lexer.cmo parse.cmo + syntaxerr.cmo parser.cmo lexer.cmo parse.cmo ocamlprof: $(CSLPROF) profiling.cmo $(CAMLC) $(LINKFLAGS) -o ocamlprof $(CSLPROF_IMPORTS) $(CSLPROF) diff --git a/tools/ocamlprof.ml b/tools/ocamlprof.ml index a5ee31f5a..7011e3f97 100644 --- a/tools/ocamlprof.ml +++ b/tools/ocamlprof.ml @@ -376,9 +376,8 @@ let main () = Lexer.Error(err, start, stop) -> Location.print {loc_start = start; loc_end = stop}; Lexer.report_error err - | Parse.Error(start, stop) -> - Location.print {loc_start = start; loc_end = stop}; - print_string "Syntax error" + | Syntaxerr.Error err -> + Syntaxerr.report_error err | Profiler msg -> print_string msg | Inversion(pos, next) -> |