2019-05-12 21:31:22 +04:00
|
|
|
(* Driver for the parser of Mini-ML *)
|
|
|
|
|
|
|
|
(* Error printing and exception tracing *)
|
|
|
|
|
|
|
|
Printexc.record_backtrace true;;
|
|
|
|
|
2019-05-15 17:03:15 +04:00
|
|
|
(* Reading the command-line options *)
|
|
|
|
|
|
|
|
let options = EvalOpt.read ()
|
|
|
|
|
|
|
|
open EvalOpt
|
|
|
|
|
2019-05-12 21:31:22 +04:00
|
|
|
(* Path to the Mini-ML standard library *)
|
|
|
|
|
|
|
|
let lib_path =
|
2019-05-15 17:03:15 +04:00
|
|
|
match options.libs with
|
2019-05-12 21:31:22 +04:00
|
|
|
[] -> ""
|
|
|
|
| libs -> let mk_I dir path = Printf.sprintf " -I %s%s" dir path
|
|
|
|
in List.fold_right mk_I libs ""
|
|
|
|
|
|
|
|
(* Opening the input channel and setting the lexing engine *)
|
|
|
|
|
|
|
|
let cin, reset =
|
2019-05-15 17:03:15 +04:00
|
|
|
match options.input with
|
|
|
|
None | Some "-" -> stdin, ignore
|
|
|
|
| Some file -> open_in file, Lexer.reset_file ~file
|
2019-05-12 21:31:22 +04:00
|
|
|
|
|
|
|
let buffer = Lexing.from_channel cin
|
|
|
|
let () = reset buffer
|
|
|
|
|
|
|
|
(* Tokeniser *)
|
|
|
|
|
|
|
|
let tokeniser =
|
2019-05-15 17:03:15 +04:00
|
|
|
if Utils.String.Set.mem "lexer" options.verbose then
|
2019-05-12 21:31:22 +04:00
|
|
|
Lexer.get_token ~log:(stdout, Lexer.output_token buffer)
|
|
|
|
else Lexer.get_token ?log:None
|
|
|
|
|
|
|
|
let () =
|
|
|
|
try
|
|
|
|
let ast = Parser.program tokeniser buffer in
|
2019-05-22 21:38:09 +04:00
|
|
|
if Utils.String.Set.mem "parser" options.verbose
|
|
|
|
then AST.print_tokens ast
|
2019-05-12 21:31:22 +04:00
|
|
|
with
|
|
|
|
Lexer.Error diag ->
|
|
|
|
close_in cin; Lexer.prerr ~kind:"Lexical" diag
|
|
|
|
| Parser.Error ->
|
|
|
|
let start = Pos.from_byte (Lexing.lexeme_start_p buffer)
|
|
|
|
and stop = Pos.from_byte (Lexing.lexeme_end_p buffer) in
|
|
|
|
let region = Region.make ~start ~stop in
|
|
|
|
close_in cin;
|
|
|
|
Lexer.prerr ~kind:"Syntactical"
|
|
|
|
Region.{value="Parse error."; region}
|
|
|
|
| Sys_error msg -> Utils.highlight msg
|