File: parserAux.ml

package info (click to toggle)
menhir 20060615.dfsg-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,024 kB
  • ctags: 1,474
  • sloc: ml: 10,279; makefile: 124; sh: 38
file content (79 lines) | stat: -rw-r--r-- 2,691 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
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
69
70
71
72
73
74
75
76
77
78
79
(**************************************************************************)
(*                                                                        *)
(*  Menhir                                                                *)
(*                                                                        *)
(*  Franois Pottier and Yann Rgis-Gianas, INRIA Rocquencourt            *)
(*                                                                        *)
(*  Copyright 2005 Institut National de Recherche en Informatique et      *)
(*  en Automatique. All rights reserved. This file is distributed         *)
(*  under the terms of the Q Public License version 1.0, with the         *)
(*  change described in file LICENSE.                                     *)
(*                                                                        *)
(**************************************************************************)

open Positions
open Syntax

let current_token_precedence =
  let c = ref 0 in
  fun pos1 pos2 ->
    incr c;
    PrecedenceLevel (Error.get_filemark (), !c, pos1, pos2)
      
let current_reduce_precedence =
  let c = ref 0 in
  fun () ->
    incr c;
    PrecedenceLevel (Error.get_filemark (), !c, Lexing.dummy_pos, Lexing.dummy_pos)

module IdSet = Set.Make (struct
  type t = identifier located
  let compare id1 id2 =
    compare (value id1) (value id2)
end)

let defined_identifiers ((ido, _) : producer) accu =
  Option.fold IdSet.add ido accu

let defined_identifiers (producers : producer list) =
  List.fold_right defined_identifiers producers IdSet.empty

let check_production_group right_hand_sides pos1 pos2 action =

  begin
    match right_hand_sides with
    | [] ->
	assert false
    | ((producers : producer list), _, _, _) :: right_hand_sides ->
	let ids = defined_identifiers producers in
	List.iter (fun (producers, _, _, _) ->
	  let ids' = defined_identifiers producers in
	  try
	    let id =
	      IdSet.choose (IdSet.union
				  (IdSet.diff ids ids')
				  (IdSet.diff ids' ids))
	    in
	    Error.errorp id
	      "Two productions that share a semantic action must define\n\
	       exactly the same identifiers."
	  with Not_found ->
	    ()
	  ) right_hand_sides
  end;
  begin
    if List.length right_hand_sides > 1 && Action.use_dollar action then
      Error.signal pos1 pos2
	"A semantic action that is shared between several productions must\n\
 	 not use the $i notation -- semantic values must be named instead."
  end

let override pos o1 o2 =
  match o1, o2 with
  | Some _, Some _ ->
      Error.signalN [ pos ] "This production carries two %prec declarations.";
      o2
  | None, Some _ ->
      o2
  | _, None ->
      o1