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:
that all of them bind the same names. *)
ParserAux.check_production_group productions;
(* Then, *)
List.map (fun (producers, oprec1, rprec, pos) ->
List.map (fun (producers, oprec1, level, pos) ->
(* Replace [$i] with [_i]. *)
let pr_producers = ParserAux.normalize_producers producers in
(* Distribute the semantic action. Also, check that every [$i]
......@@ -223,7 +223,7 @@ production_group:
pr_producers;
pr_action;
pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2;
pr_branch_reduce_precedence = rprec;
pr_branch_production_level = level;
pr_branch_position = pos
})
productions
......@@ -241,7 +241,7 @@ production:
producers = producer* oprec = ioption(precedence)
{ producers,
oprec,
ParserAux.current_reduce_precedence(),
ParserAux.new_production_level(),
Positions.lex_join $startpos $endpos
}
......
......@@ -554,7 +554,7 @@ module Production = struct
let prec_decl : symbol located option array =
Array.make n None
let reduce_precedence : precedence_level array =
let production_level : precedence_level array =
Array.make n UndefinedPrecedence
let (_ : int) = StringMap.fold (fun nonterminal { branches = branches } k ->
......@@ -564,7 +564,7 @@ module Production = struct
table.(k) <- (nt, Array.map (fun (v, _) -> Symbol.lookup v) symbols);
identifiers.(k) <- Array.map snd symbols;
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;
positions.(k) <- [ branch.branch_position ];
k+1
......@@ -1497,9 +1497,9 @@ module Precedence = struct
let reduce_reduce prod1 prod2 =
let rp1 = Production.reduce_precedence.(prod1)
and rp2 = Production.reduce_precedence.(prod2) in
match precedence_order rp1 rp2 with
let pl1 = Production.production_level.(prod1)
and pl2 = Production.production_level.(prod2) in
match precedence_order pl1 pl2 with
| Lt ->
Some prod1
| Gt ->
......
......@@ -558,7 +558,7 @@ let expand p_grammar =
producers = new_producers;
action = pbranch.pr_action;
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
......
......@@ -7,7 +7,7 @@ let new_precedence_level =
incr c;
PrecedenceLevel (Error.get_filemark (), !c, pos1, pos2)
let current_reduce_precedence =
let new_production_level =
let c = ref 0 in
fun () ->
incr c;
......
......@@ -3,17 +3,26 @@
open Syntax
(* [new_precedence_level pos1 pos2] creates a new precendence level,
which is stronger than any previously created levels, for tokens.
It should be called every time a [%left], [%right], or [%nonassoc]
declaration is found. The positions are the positions of this
declaration in the source code. *)
(* [new_precedence_level pos1 pos2] creates a new precendence level, which is
stronger than any levels previously created by this function. It should be
called every time a [%left], [%right], or [%nonassoc] declaration is found.
The positions are the positions of this declaration in the source code. The
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
(* 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
productions in the group define the same set of identifiers. *)
......
......@@ -86,12 +86,15 @@ type declaration =
| DType of Stretch.ocamltype * parameter
(* 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 =
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
type producer =
......@@ -103,7 +106,7 @@ type parameterized_branch =
pr_producers : producer list;
pr_action : action;
pr_branch_prec_annotation : branch_prec_annotation;
pr_branch_reduce_precedence : branch_reduce_precedence
pr_branch_production_level : branch_production_level
}
type parameterized_rule =
......
......@@ -144,9 +144,12 @@ let print_branch mode f branch =
let print_trailers b g =
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 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 ->
0
| PrecedenceLevel (m, l, _, _), PrecedenceLevel (m', l', _, _) ->
......
......@@ -22,7 +22,7 @@ type branch =
par rapport à syntax.mli; faire un type record au lieu d'une paire? *)
action : action;
branch_prec_annotation : branch_prec_annotation;
branch_reduce_precedence : branch_reduce_precedence
branch_production_level : branch_production_level
}
type rule =
......
......@@ -267,7 +267,7 @@ production_group:
that all of them bind the same names. *)
ParserAux.check_production_group productions;
(* Then, *)
List.map (fun (producers, oprec1, rprec, pos) ->
List.map (fun (producers, oprec1, level, pos) ->
(* Replace [$i] with [_i]. *)
let pr_producers = ParserAux.normalize_producers producers in
(* Distribute the semantic action. Also, check that every [$i]
......@@ -277,7 +277,7 @@ production_group:
pr_producers;
pr_action;
pr_branch_prec_annotation = ParserAux.override pos oprec1 oprec2;
pr_branch_reduce_precedence = rprec;
pr_branch_production_level = level;
pr_branch_position = pos
})
productions
......@@ -310,7 +310,7 @@ production:
producers optional_precedence
{ List.rev $1,
$2,
ParserAux.current_reduce_precedence(),
ParserAux.new_production_level(),
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