Commit f58d6adb authored by POTTIER Francois's avatar POTTIER Francois

Cleanup. Distinguished the types [precedence_level] and [production_level].

parent 6b54866b
......@@ -554,8 +554,12 @@ module Production = struct
let prec_decl : symbol located option array =
Array.make n None
let production_level : precedence_level array =
Array.make n UndefinedPrecedence
let production_level : branch_production_level array =
(* The start productions should receive this dummy level, I suppose.
We use a fresh mark, so a reduce/reduce conflict that involves a
start production will not be solved. *)
let dummy = ProductionLevel (Mark.fresh(), 0) in
Array.make n dummy
let (_ : int) = StringMap.fold (fun nonterminal { branches = branches } k ->
let nt = Nonterminal.lookup nonterminal in
......@@ -1444,7 +1448,6 @@ module Precedence = struct
| UndefinedPrecedence, _
| _, UndefinedPrecedence ->
Ic
| PrecedenceLevel (m1, l1, _, _), PrecedenceLevel (m2, l2, _, _) ->
if not (Mark.same m1 m2) then
Ic
......@@ -1456,6 +1459,19 @@ module Precedence = struct
else
Eq
let production_order p1 p2 =
match p1, p2 with
| ProductionLevel (m1, l1), ProductionLevel (m2, l2) ->
if not (Mark.same m1 m2) then
Ic
else
if l1 > l2 then
Gt
else if l1 < l2 then
Lt
else
Eq
let shift_reduce tok prod =
let fact1, tokp = Terminal.precedence_level tok
and fact2, prodp = Production.precedence prod in
......@@ -1499,7 +1515,7 @@ module Precedence = struct
let reduce_reduce prod1 prod2 =
let pl1 = Production.production_level.(prod1)
and pl2 = Production.production_level.(prod2) in
match precedence_order pl1 pl2 with
match production_order pl1 pl2 with
| Lt ->
Some prod1
| Gt ->
......
......@@ -11,7 +11,7 @@ let new_production_level =
let c = ref 0 in
fun () ->
incr c;
PrecedenceLevel (Error.get_filemark (), !c, Lexing.dummy_pos, Lexing.dummy_pos)
ProductionLevel (Error.get_filemark (), !c)
module IdSet = Set.Make (struct
type t = identifier located
......
......@@ -13,16 +13,16 @@ open Syntax
val new_precedence_level: Lexing.position -> Lexing.position -> precedence_level
(* [new_production_level()] creates a new precedence level, which is stronger
(* [new_production_level()] creates a new production 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
every time a new production is found. The production 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 new_production_level: unit -> precedence_level
val new_production_level: unit -> branch_production_level
(* [check_production_group] accepts a production group and checks that all
productions in the group define the same set of identifiers. *)
......
......@@ -95,7 +95,7 @@ type branch_prec_annotation =
which production appears first in the grammar. See [ParserAux]. *)
type branch_production_level =
precedence_level
| ProductionLevel of Mark.t * int
type producer =
identifier Positions.located * parameter
......
......@@ -150,9 +150,7 @@ let print_trailers b g =
let branches_order r r' =
let branch_order b b' =
match b.branch_production_level, b'.branch_production_level with
| UndefinedPrecedence, _ | _, UndefinedPrecedence ->
0
| PrecedenceLevel (m, l, _, _), PrecedenceLevel (m', l', _, _) ->
| ProductionLevel (m, l), ProductionLevel (m', l') ->
if Mark.same m m' then
if l < l' then
-1
......
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