sentenceParser.mly 3.86 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
/* This is two parsers in one. */

16
/* This parser is used to read the sentences provided on the standard input
17
   channel when [--interpret] is set. The entry point is [optional_sentence]. */
18

19
/* It is used also to read a [.messages] file. The entry point is [entry]. */
20

21 22 23 24
/* This parser must be compatible with both ocamlyacc and menhir, so we use
   $ notation, do not use Menhir's standard library, and collect positions
   manually. */

25 26
/* ------------------------------------------------------------------------ */
/* Tokens. */
27 28

%token COLON EOF EOL
29 30
%token<Grammar.Terminal.t * Lexing.position * Lexing.position> TERMINAL
%token<Grammar.Nonterminal.t * Lexing.position * Lexing.position> NONTERMINAL
31 32
%token<string> COMMENT
  /* only manually-written comments, beginning with a single # */
33 34 35 36 37 38

/* ------------------------------------------------------------------------ */
/* Types. */

%{

39
  open SentenceParserAux
40

41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
  (* Removing the position information in a terminal or non-terminal symbol. *)

  let strip_symbol (x, _, _) = x

  (* Removing the position information in a sentence. *)

  let strip_sentence (nto, terminals) =
    Option.map strip_symbol nto,
    List.map strip_symbol terminals

  (* Computing the start and end positions of a sentence. *)

  let locate_sentence (nto, terminals) =
    let opening =
      match nto, terminals with
      | Some (_, opening, _), _
      | None, (_, opening, _) :: _ ->
          opening
      | None, [] ->
          Lexing.dummy_pos (* cannot happen *)
    and closing =
      match nto, List.rev terminals with
      | _, (_, _, closing) :: _
      | Some (_, _, closing), _ ->
          closing
      | None, [] ->
          Lexing.dummy_pos (* cannot happen *)
    in
POTTIER Francois's avatar
POTTIER Francois committed
69
    [Positions.import (opening, closing)],
70 71
    strip_sentence (nto, terminals)

72
%}
73

74 75
%type <located_sentence> located_sentence

76
%type <SentenceParserAux.sentence option> optional_sentence
77 78
%start optional_sentence

79
%type<SentenceParserAux.located_sentence SentenceParserAux.or_comment list> entry
80
%start entry
81 82 83

%%

84 85
/* ------------------------------------------------------------------------ */

86 87 88
/* An entry is a list of located sentences or comments. */
entry: located_sentences_or_comments EOF
  { $1 }
89

90 91 92
/* A list of located sentences or comments. */
located_sentences_or_comments:
  { [] }
93 94
| located_sentence located_sentences_or_comments { Thing   $1 :: $2 }
| COMMENT          located_sentences_or_comments { Comment $1 :: $2 }
95

96 97
/* A located sentence. */
located_sentence: sentence
98
  { locate_sentence $1 }
99 100 101

/* An optional sentence. */
optional_sentence:
102
| EOF
POTTIER Francois's avatar
POTTIER Francois committed
103
    { None }
104
| sentence
105
    { Some (strip_sentence $1) }
106 107 108 109

/* A sentence is a pair of an optional non-terminal start symbol and a list
   of terminal symbols. It is terminated by a newline. */
sentence:
110
| NONTERMINAL COLON terminals EOL
111
    { Some $1, $3 }
112
| terminals EOL
113 114 115
    { None, $1 }

/* A list of terminal symbols. */
116
terminals:
POTTIER Francois's avatar
POTTIER Francois committed
117 118
|
    { [] }
119 120
| TERMINAL terminals
    { $1 :: $2 }