Attention une mise à jour du serveur va être effectuée le vendredi 16 avril entre 12h et 12h30. Cette mise à jour va générer une interruption du service de quelques minutes.

front.ml 5.49 KB
Newer Older
1
(* The front-end. This module performs a series of toplevel side effects. *)
2

3 4 5 6 7 8 9
(* ------------------------------------------------------------------------- *)

(* Reading a grammar from a file. *)

let load_partial_grammar filename =
  let validExt = if Settings.coq then ".vy" else ".mly" in
  if not (Filename.check_suffix filename validExt) then
10
    Error.error []
11
      "argument file names should end in %s. \"%s\" is not accepted."
12
      validExt filename;
13 14 15 16 17
  Error.set_filename filename;
  try

    let contents = IO.read_whole_file filename in
    Error.file_contents := Some contents;
POTTIER Francois's avatar
POTTIER Francois committed
18
    let open Lexing in
19
    let lexbuf = Lexing.from_string contents in
POTTIER Francois's avatar
POTTIER Francois committed
20
    lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = filename };
21
    let grammar =
22
      { (Driver.grammar Lexer.main lexbuf) with Syntax.pg_filename = filename }
23 24 25 26 27
    in
    Error.file_contents := None;
    grammar

  with Sys_error msg ->
28
    Error.error [] "%s" msg
29 30 31 32 33

(* ------------------------------------------------------------------------- *)

(* Read all of the grammar files that are named on the command line. *)

POTTIER Francois's avatar
POTTIER Francois committed
34
let partial_grammars =
35 36 37 38 39 40 41
  List.map load_partial_grammar Settings.filenames

let () =
  Time.tick "Lexing and parsing"

(* ------------------------------------------------------------------------- *)

42 43 44 45 46 47 48
(* Eliminate anonymous rules. *)

let partial_grammars =
  List.map Anonymous.transform_partial_grammar partial_grammars

(* ------------------------------------------------------------------------- *)

49 50
(* If several grammar files were specified, merge them. *)

POTTIER Francois's avatar
POTTIER Francois committed
51
let parameterized_grammar =
52 53 54 55 56 57 58
  PartialGrammar.join_partial_grammars partial_grammars

(* ------------------------------------------------------------------------- *)

(* Expand away all applications of parameterized nonterminal symbols, so as to
   obtain a grammar without parameterized nonterminal symbols. *)

POTTIER Francois's avatar
POTTIER Francois committed
59
let grammar =
60 61 62 63 64 65
  ParameterizedGrammar.expand parameterized_grammar

let () =
  Time.tick "Joining and expanding"

(* ------------------------------------------------------------------------- *)
66

67 68 69 70
(* If [--only-tokens] was specified on the command line, produce
   the definition of the [token] type and stop. *)

let () =
71
  TokenType.produce_tokentypes grammar
72

73 74
(* ------------------------------------------------------------------------- *)

75 76 77 78 79 80 81 82
(* Perform reachability analysis. *)

let grammar =
  Reachability.trim grammar

let () =
  Time.tick "Trimming"

83 84
(* ------------------------------------------------------------------------- *)

85 86
(* If [--depend] or [--raw-depend] was specified on the command line,
   perform dependency analysis and stop. *)
87 88 89 90 91 92 93 94 95

let () =
  match Settings.depend with
  | Settings.OMRaw
  | Settings.OMPostprocess ->
      Infer.depend grammar (* never returns *)
  | Settings.OMNone ->
      ()

96 97 98
(* The purpose of [--depend] and [--raw-depend] is to support [--infer].
   Indeed, [--infer] is implemented by producing a mock [.ml] file (which
   contains just the semantic actions) and invoking [ocamlc]. This requires
99 100 101 102 103
   certain [.cmi] files to exist. So, [--(raw-)depend] is a way for us to
   announce which [.cmi] files we need. It is implemented by producing the
   mock [.ml] file and running [ocamldep] on it. We also produce a mock
   [.mli] file, even though in principle it should be unnecessary -- see
   comment in [nonterminalType.mli]. *)
104

105 106
(* ------------------------------------------------------------------------- *)

107 108 109 110 111 112 113 114
(* If some flags imply that we will NOT produce an OCaml parser, then there
   is no need to perform type inference, so we act as if --infer was absent.
   This saves time and dependency nightmares. *)

let skipping_parser_generation =
  Settings.coq ||
  Settings.compile_errors <> None ||
  Settings.interpret_error ||
115
  Settings.list_errors ||
116 117 118 119
  Settings.compare_errors <> None ||
  Settings.update_errors <> None ||
  Settings.echo_errors <> None ||
  false
120 121 122 123
    (* maybe also: [preprocess_mode <> PMNormal] *)

(* ------------------------------------------------------------------------- *)

POTTIER Francois's avatar
POTTIER Francois committed
124 125
(* If [--infer] was specified on the command line, perform type inference.
   The OCaml type of every nonterminal is then known. *)
126 127

let grammar =
128
  if Settings.infer && not skipping_parser_generation then
129 130 131 132 133 134
    let grammar = Infer.infer grammar in
    Time.tick "Inferring types for nonterminals";
    grammar
  else
    grammar

135
(* ------------------------------------------------------------------------- *)
136 137 138 139 140 141 142

(* Expand away some of the position keywords. *)

let grammar =
  KeywordExpansion.expand_grammar grammar

(* ------------------------------------------------------------------------- *)
143

144 145 146 147 148
(* If [--no-inline] was specified on the command line, skip the
   inlining of non terminal definitions marked with %inline. *)

let grammar =
  if Settings.inline then begin
POTTIER Francois's avatar
POTTIER Francois committed
149
    let grammar, inlined =
150 151
      NonTerminalDefinitionInlining.inline grammar
    in
152
    if not Settings.infer && inlined && not skipping_parser_generation then
153
      Error.warning []
154 155
        "you are using the standard library and/or the %%inline keyword. We\n\
         recommend switching on --infer in order to avoid obscure type error messages.";
156 157 158
    Time.tick "Inlining";
    grammar
  end
POTTIER Francois's avatar
POTTIER Francois committed
159
  else
160 161
    grammar

162 163
(* ------------------------------------------------------------------------- *)

164 165 166 167 168 169 170 171 172 173
(* If [--only-preprocess] or [--only-preprocess-drop] was specified on the
   command line, print the grammar and stop. Otherwise, continue. *)

let () =
  match Settings.preprocess_mode with
  | Settings.PMOnlyPreprocess mode ->
      UnparameterizedPrinter.print mode stdout grammar;
      exit 0
  | Settings.PMNormal ->
      ()