cmly_format.ml 3.26 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
(******************************************************************************)
(*                                                                            *)
(*                                   Menhir                                   *)
(*                                                                            *)
(*                       François Pottier, Inria Paris                        *)
(*              Yann Régis-Gianas, PPS, Université Paris Diderot              *)
(*                                                                            *)
(*  Copyright Inria. All rights reserved. This file is distributed under the  *)
(*  terms of the GNU General Public License version 2, as described in the    *)
(*  file LICENSE.                                                             *)
(*                                                                            *)
(******************************************************************************)

14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
(* This module defines the data that is stored in .cmly files. In short, a
   .cmly file contains a value of type [grammar], defined below. *)

(* The type definitions in this module are used by [Cmly_write], which writes
   a .cmly file, and by [Cmly_read], which reads a .cmly file. They should not
   be used anywhere else. *)

(* All entities (terminal symbols, nonterminal symbols, and so on) are
   represented as integers. These integers serve as indices into arrays. This
   enables simple and efficient hashing, comparison, indexing, etc. *)

type terminal    = int
type nonterminal = int
type production  = int
type lr0         = int
type lr1         = int

31 32
type ocamltype   = string
type ocamlexpr   = string
33

34 35 36 37 38
type range = {
  r_start: Lexing.position;
  r_end: Lexing.position;
}

39 40 41
type attribute = {
  a_label: string;
  a_payload: string;
42
  a_position: range;
43
}
44 45 46 47 48 49 50

type attributes =
  attribute list

type terminal_def = {
  t_name: string;
  t_kind: [`REGULAR | `ERROR | `EOF | `PSEUDO];
51
  t_type: ocamltype option;
52 53 54 55 56 57 58
  t_attributes: attributes;
}

type nonterminal_def = {
  n_name: string;
  n_kind: [`REGULAR | `START];
  n_mangled_name: string;
59
  n_type: ocamltype option;
60
  n_positions: range list;
61
  n_nullable: bool;
62 63 64 65 66 67 68 69 70 71 72
  n_first: terminal list;
  n_attributes: attributes;
}

type symbol =
  | T of terminal
  | N of nonterminal

type identifier = string

type action = {
73
  a_expr: ocamlexpr;
74 75 76 77 78 79 80 81 82 83
  a_keywords: Keyword.keyword list;
}

type producer_def =
  symbol * identifier * attributes

type production_def = {
  p_kind: [`REGULAR | `START];
  p_lhs: nonterminal;
  p_rhs: producer_def array;
84
  p_positions: range list;
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
  p_action: action option;
  p_attributes: attributes;
}

type lr0_state_def = {
  lr0_incoming: symbol option;
  lr0_items: (production * int) list;
}

type lr1_state_def = {
  lr1_lr0: lr0;
  lr1_transitions: (symbol * lr1) list;
  lr1_reductions: (terminal * production list) list;
}

type grammar = {
  g_basename     : string;
102 103
  g_preludes     : string list;
  g_postludes    : string list;
104 105 106 107 108
  g_terminals    : terminal_def    array;
  g_nonterminals : nonterminal_def array;
  g_productions  : production_def  array;
  g_lr0_states   : lr0_state_def   array;
  g_lr1_states   : lr1_state_def   array;
109
  g_entry_points : (nonterminal * production * lr1) list;
110
  g_attributes   : attributes;
111
  g_parameters   : string list;
112
}