Commit 34e4fb47 authored by POTTIER Francois's avatar POTTIER Francois

Cleanup. Renamed [reduce_precedence] to [production_level] and documented.

parent df9f32fc
...@@ -212,7 +212,7 @@ production_group: ...@@ -212,7 +212,7 @@ production_group:
that all of them bind the same names. *) that all of them bind the same names. *)
ParserAux.check_production_group productions; ParserAux.check_production_group productions;
(* Then, *) (* Then, *)
List.map (fun (producers, oprec1, rprec, pos) -> List.map (fun (producers, oprec1, level, pos) ->
(* Replace [$i] with [_i]. *) (* Replace [$i] with [_i]. *)
let pr_producers = ParserAux.normalize_producers producers in let pr_producers = ParserAux.normalize_producers producers in
(* Distribute the semantic action. Also, check that every [$i] (* Distribute the semantic action. Also, check that every [$i]
...@@ -223,7 +223,7 @@ production_group: ...@@ -223,7 +223,7 @@ production_group:
pr_producers; pr_producers;
pr_action; pr_action;
pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2; pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2;
pr_branch_reduce_precedence = rprec; pr_branch_production_level = level;
pr_branch_position = pos pr_branch_position = pos
}) })
productions productions
...@@ -241,7 +241,7 @@ production: ...@@ -241,7 +241,7 @@ production:
producers = producer* oprec = ioption(precedence) producers = producer* oprec = ioption(precedence)
{ producers, { producers,
oprec, oprec,
ParserAux.current_reduce_precedence(), ParserAux.new_production_level(),
Positions.lex_join $startpos $endpos Positions.lex_join $startpos $endpos
} }
......
...@@ -554,7 +554,7 @@ module Production = struct ...@@ -554,7 +554,7 @@ module Production = struct
let prec_decl : symbol located option array = let prec_decl : symbol located option array =
Array.make n None Array.make n None
let reduce_precedence : precedence_level array = let production_level : precedence_level array =
Array.make n UndefinedPrecedence Array.make n UndefinedPrecedence
let (_ : int) = StringMap.fold (fun nonterminal { branches = branches } k -> let (_ : int) = StringMap.fold (fun nonterminal { branches = branches } k ->
...@@ -564,7 +564,7 @@ module Production = struct ...@@ -564,7 +564,7 @@ module Production = struct
table.(k) <- (nt, Array.map (fun (v, _) -> Symbol.lookup v) symbols); table.(k) <- (nt, Array.map (fun (v, _) -> Symbol.lookup v) symbols);
identifiers.(k) <- Array.map snd symbols; identifiers.(k) <- Array.map snd symbols;
actions.(k) <- Some branch.action; actions.(k) <- Some branch.action;
reduce_precedence.(k) <- branch.branch_reduce_precedence; production_level.(k) <- branch.branch_production_level;
prec_decl.(k) <- branch.branch_prec_annotation; prec_decl.(k) <- branch.branch_prec_annotation;
positions.(k) <- [ branch.branch_position ]; positions.(k) <- [ branch.branch_position ];
k+1 k+1
...@@ -1497,9 +1497,9 @@ module Precedence = struct ...@@ -1497,9 +1497,9 @@ module Precedence = struct
let reduce_reduce prod1 prod2 = let reduce_reduce prod1 prod2 =
let rp1 = Production.reduce_precedence.(prod1) let pl1 = Production.production_level.(prod1)
and rp2 = Production.reduce_precedence.(prod2) in and pl2 = Production.production_level.(prod2) in
match precedence_order rp1 rp2 with match precedence_order pl1 pl2 with
| Lt -> | Lt ->
Some prod1 Some prod1
| Gt -> | Gt ->
......
...@@ -558,7 +558,7 @@ let expand p_grammar = ...@@ -558,7 +558,7 @@ let expand p_grammar =
producers = new_producers; producers = new_producers;
action = pbranch.pr_action; action = pbranch.pr_action;
branch_prec_annotation = pbranch.pr_branch_prec_annotation; branch_prec_annotation = pbranch.pr_branch_prec_annotation;
branch_reduce_precedence = pbranch.pr_branch_reduce_precedence; branch_production_level = pbranch.pr_branch_production_level;
} }
(* Instantiate the branches of sym for a particular set of actual (* Instantiate the branches of sym for a particular set of actual
......
...@@ -7,7 +7,7 @@ let new_precedence_level = ...@@ -7,7 +7,7 @@ let new_precedence_level =
incr c; incr c;
PrecedenceLevel (Error.get_filemark (), !c, pos1, pos2) PrecedenceLevel (Error.get_filemark (), !c, pos1, pos2)
let current_reduce_precedence = let new_production_level =
let c = ref 0 in let c = ref 0 in
fun () -> fun () ->
incr c; incr c;
......
...@@ -3,17 +3,26 @@ ...@@ -3,17 +3,26 @@
open Syntax open Syntax
(* [new_precedence_level pos1 pos2] creates a new precendence level, (* [new_precedence_level pos1 pos2] creates a new precendence level, which is
which is stronger than any previously created levels, for tokens. stronger than any levels previously created by this function. It should be
It should be called every time a [%left], [%right], or [%nonassoc] called every time a [%left], [%right], or [%nonassoc] declaration is found.
declaration is found. The positions are the positions of this The positions are the positions of this declaration in the source code. The
declaration in the source code. *) precedence levels created by this function are attached to tokens and (via
%prec) to productions. They are used in solving shift/reduce and
shift/reduce/reduce conflicts. *)
val new_precedence_level: Lexing.position -> Lexing.position -> precedence_level val new_precedence_level: Lexing.position -> Lexing.position -> precedence_level
(* TEMPORARY document *) (* [new_production_level()] creates a new precedence level, which is stronger
than any levels previously created by this function. It should be called
every time a new production is found. The precedence levels created by this
function are attached to productions. They are used in solving
reduce/reduce conflicts: following ocamlyacc and bison, the production that
appears first in the grammar receives preference. It may seem very strange
that %prec annotations do not influence this process, but that's how it is,
at least for the moment. *)
val current_reduce_precedence: unit -> precedence_level val new_production_level: unit -> precedence_level
(* [check_production_group] accepts a production group and checks that all (* [check_production_group] accepts a production group and checks that all
productions in the group define the same set of identifiers. *) productions in the group define the same set of identifiers. *)
......
...@@ -86,12 +86,15 @@ type declaration = ...@@ -86,12 +86,15 @@ type declaration =
| DType of Stretch.ocamltype * parameter | DType of Stretch.ocamltype * parameter
(* A [%prec] annotation is optional. A production can carry at most one. (* A [%prec] annotation is optional. A production can carry at most one.
If there is one, it is a symbol name. *) If there is one, it is a symbol name. See [ParserAux]. *)
type branch_prec_annotation = type branch_prec_annotation =
symbol Positions.located option symbol Positions.located option
type branch_reduce_precedence = (* A "production level" is used to solve reduce/reduce conflicts. It reflects
which production appears first in the grammar. See [ParserAux]. *)
type branch_production_level =
precedence_level precedence_level
type producer = type producer =
...@@ -103,7 +106,7 @@ type parameterized_branch = ...@@ -103,7 +106,7 @@ type parameterized_branch =
pr_producers : producer list; pr_producers : producer list;
pr_action : action; pr_action : action;
pr_branch_prec_annotation : branch_prec_annotation; pr_branch_prec_annotation : branch_prec_annotation;
pr_branch_reduce_precedence : branch_reduce_precedence pr_branch_production_level : branch_production_level
} }
type parameterized_rule = type parameterized_rule =
......
...@@ -144,9 +144,12 @@ let print_branch mode f branch = ...@@ -144,9 +144,12 @@ let print_branch mode f branch =
let print_trailers b g = let print_trailers b g =
List.iter (fun stretch -> Printf.fprintf b "%s\n" stretch.stretch_raw_content) g.postludes List.iter (fun stretch -> Printf.fprintf b "%s\n" stretch.stretch_raw_content) g.postludes
(* Because the resolution of reduce/reduce conflicts is implicitly dictated by
the order in which productions appear in the grammar, the printer should be
careful to preserve this order. *)
let branches_order r r' = let branches_order r r' =
let branch_order b b' = let branch_order b b' =
match b.branch_reduce_precedence, b'.branch_reduce_precedence with match b.branch_production_level, b'.branch_production_level with
| UndefinedPrecedence, _ | _, UndefinedPrecedence -> | UndefinedPrecedence, _ | _, UndefinedPrecedence ->
0 0
| PrecedenceLevel (m, l, _, _), PrecedenceLevel (m', l', _, _) -> | PrecedenceLevel (m, l, _, _), PrecedenceLevel (m', l', _, _) ->
......
...@@ -22,7 +22,7 @@ type branch = ...@@ -22,7 +22,7 @@ type branch =
par rapport à syntax.mli; faire un type record au lieu d'une paire? *) par rapport à syntax.mli; faire un type record au lieu d'une paire? *)
action : action; action : action;
branch_prec_annotation : branch_prec_annotation; branch_prec_annotation : branch_prec_annotation;
branch_reduce_precedence : branch_reduce_precedence branch_production_level : branch_production_level
} }
type rule = type rule =
......
...@@ -267,7 +267,7 @@ production_group: ...@@ -267,7 +267,7 @@ production_group:
that all of them bind the same names. *) that all of them bind the same names. *)
ParserAux.check_production_group productions; ParserAux.check_production_group productions;
(* Then, *) (* Then, *)
List.map (fun (producers, oprec1, rprec, pos) -> List.map (fun (producers, oprec1, level, pos) ->
(* Replace [$i] with [_i]. *) (* Replace [$i] with [_i]. *)
let pr_producers = ParserAux.normalize_producers producers in let pr_producers = ParserAux.normalize_producers producers in
(* Distribute the semantic action. Also, check that every [$i] (* Distribute the semantic action. Also, check that every [$i]
...@@ -277,7 +277,7 @@ production_group: ...@@ -277,7 +277,7 @@ production_group:
pr_producers; pr_producers;
pr_action; pr_action;
pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2; pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2;
pr_branch_reduce_precedence = rprec; pr_branch_production_level = level;
pr_branch_position = pos pr_branch_position = pos
}) })
productions productions
...@@ -310,7 +310,7 @@ production: ...@@ -310,7 +310,7 @@ production:
producers optional_precedence producers optional_precedence
{ List.rev $1, { List.rev $1,
$2, $2,
ParserAux.current_reduce_precedence(), ParserAux.new_production_level(),
Positions.lex_join (symbol_start_pos()) (symbol_end_pos()) Positions.lex_join (symbol_start_pos()) (symbol_end_pos())
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment