1 (**************************************************************************)
5 (* François Pottier, INRIA Rocquencourt *)
6 (* Yann Régis-Gianas, PPS, Université Paris Diderot *)
8 (* Copyright 2005-2008 Institut National de Recherche en Informatique *)
9 (* et en Automatique. All rights reserved. This file is distributed *)
10 (* under the terms of the Q Public License version 1.0, with the change *)
11 (* described in file LICENSE. *)
13 (**************************************************************************)
19 open UnparameterizedSyntax
22 let print_preludes f g
=
23 List.iter
(fun prelude
->
24 Printf.fprintf f
"%%{%s%%}\n" prelude
.stretch_raw_content
27 let print_start_symbols b g
=
28 StringSet.iter
(fun symbol
->
29 Printf.fprintf b
"%%start %s\n" (Misc.normalize symbol
)
32 let rec insert_in_partitions item m
= function
36 | (m'
, items
) :: partitions
when Mark.same m m'
->
37 (m'
, item
:: items
) :: partitions
40 t
:: (insert_in_partitions item m partitions
)
42 let insert (undefined
, partitions
) = function
43 | (item
, UndefinedPrecedence
) ->
44 ((item
, 0) :: undefined
, partitions
)
46 | (item
, PrecedenceLevel
(m
, v
, _
, _
)) ->
47 (undefined
, insert_in_partitions (item
, v
) m partitions
)
49 let print_ocamltype ocamltype
=
50 Printf.sprintf
" <%s>" (
53 stretch
.stretch_raw_content
58 let print_assoc = function
60 Printf.sprintf
"%%left"
62 Printf.sprintf
"%%right"
64 Printf.sprintf
"%%nonassoc"
68 let print_tokens mode b g
=
69 (* Sort tokens wrt precedence. *)
70 let undefined, partition_tokens
=
71 StringMap.fold
(fun token prop acu
->
72 insert acu
(token
, prop
.tk_priority
)
76 List.fold_left
(fun acu
(_
, ms
) ->
77 acu
@ List.sort
(fun (_
, v
) (_
, v'
) -> compare v v'
) ms
78 ) undefined partition_tokens
80 List.iter
(fun (token
, _
) ->
81 let prop = StringMap.find token g
.tokens
in
82 if prop.tk_is_declared
then
83 Printf.fprintf b
"%%token%s %s\n"
87 Misc.o2s
prop.tk_ocamltype
print_ocamltype
88 | PrintUnitActionsUnitTokens
->
89 "" (* omitted ocamltype after %token means <unit> *)
94 ignore
(List.fold_left
95 (fun last_prop
(token
, v
) ->
96 let prop = StringMap.find token g
.tokens
in
100 if prop.tk_associativity
= UndefinedAssoc
then
103 Printf.fprintf b
"%s %s "
104 (print_assoc prop.tk_associativity
) token
;
107 | Some v'
when v
<> v'
->
108 if prop.tk_associativity
= UndefinedAssoc
then
111 Printf.fprintf b
"\n%s %s "
112 (print_assoc prop.tk_associativity
) token
;
116 Printf.fprintf b
"%s " token
;
119 ) None
ordered_tokens);
120 Printf.fprintf b
"\n"
122 let print_types mode b g
=
123 StringMap.iter
(fun symbol ty
->
124 Printf.fprintf b
"%%type%s %s\n"
125 begin match mode
with
129 | PrintUnitActionsUnitTokens
->
132 (Misc.normalize symbol
)
135 let binding mode id
=
140 | PrintUnitActionsUnitTokens
->
143 let string_of_producer mode
(symbol
, ido
) =
144 Misc.o2s ido
(binding mode
) ^
(Misc.normalize symbol
)
146 let print_branch mode f branch
=
147 Printf.fprintf f
"%s%s\n {"
148 (String.concat
" " (List.map
(string_of_producer mode
) branch
.producers
))
149 (Misc.o2s branch
.branch_shift_precedence
(fun x
-> " %prec "^x
.value));
150 begin match mode
with
152 Action.print f branch
.action
154 | PrintUnitActionsUnitTokens
->
155 Printf.fprintf f
"()"
157 Printf.fprintf f
"}\n"
159 let print_trailers b g
=
160 List.iter
(Printf.fprintf b
"%s\n") g
.postludes
162 let branches_order r r'
=
163 let branch_order b b'
=
164 match b
.branch_reduce_precedence
, b'
.branch_reduce_precedence
with
165 | UndefinedPrecedence
, _
| _
, UndefinedPrecedence
->
167 | PrecedenceLevel
(m
, l
, _
, _
), PrecedenceLevel
(m'
, l'
, _
, _
) ->
168 if Mark.same m m'
then
177 let rec lexical_order bs bs'
=
185 | b
:: bs
, b'
:: bs'
->
186 match branch_order b b'
with
192 lexical_order r
.branches r'
.branches
194 let print_rules mode b g
=
196 StringMap.fold
(fun nt r acu
-> (nt
, r
) :: acu
) g
.rules
[]
199 List.sort
(fun (nt
, r
) (nt'
, r'
) -> branches_order r r'
) rules_as_list
201 List.iter
(fun (nt
, r
) ->
202 Printf.fprintf b
"\n%s:\n" (Misc.normalize nt
);
204 Printf.fprintf b
"| ";
205 print_branch mode b br
210 begin match mode
with
214 | PrintUnitActionsUnitTokens
->
217 print_start_symbols f g
;
218 print_tokens mode f g
;
219 print_types mode f g
;
220 Printf.fprintf f
"%%%%\n";
221 print_rules mode f g
;
222 Printf.fprintf f
"\n%%%%\n";
223 begin match mode
with
227 | PrintUnitActionsUnitTokens
->