Commit 3948a181 authored by POTTIER Francois's avatar POTTIER Francois

A better error message for %inline cycles.

parent de3e7583
# Changes
## 2018/11/XX
* When a cycle of `%inline` nonterminal symbols is encountered,
the error message now shows the entire cycle,
as opposed to just one symbol that participates in the cycle.
## 2018/11/13
* In `.mly` files, a new syntax for rules has been introduced, which is
......
......@@ -474,11 +474,25 @@ module Inline (G : sig val grammar: grammar end) = struct
let expand_symbol symbol =
try
expand_symbol symbol
with Memoize.String.Cycle (_, symbol) ->
with Memoize.String.Cycle (symbols, symbol) ->
let rule = find symbol in
Error.error rule.positions
"there is a cycle in the definition of %s." symbol
(* TEMPORARY we can now give a better message. *)
let b = Buffer.create 128 in
Printf.bprintf b "there is a cycle of %%inline nonterminal symbols:\n";
begin match symbols with
| [] ->
assert false
| head :: [] ->
assert (head = symbol);
Printf.bprintf b " %s refers to itself." symbol
| head :: next :: symbols ->
assert (head = symbol);
Printf.bprintf b " %s refers to %s,\n" head next;
List.iter (fun symbol ->
Printf.bprintf b " which refers to %s,\n" symbol
) symbols;
Printf.bprintf b " which refers back to %s." symbol
end;
Error.error rule.positions "%s" (Buffer.contents b)
(* If we are in Coq mode, %inline is forbidden. *)
let _ =
......
File "inline-cycle-complex.mly", line 7, characters 8-9:
Error: there is a cycle in the definition of b.
Error: there is a cycle of %inline nonterminal symbols:
b refers to c,
which refers to d,
which refers back to b.
File "inline-cycle-long.mly", line 37, characters 4-15:
Error: there is a cycle of %inline nonterminal symbols:
atomic_expr refers to delimited(LPAREN,app(unary_op,atomic_expr),RPAREN),
which refers to app(unary_op,atomic_expr),
which refers back to atomic_expr.
%token <int> INT
%token PLUS MINUS TIMES DIV
%token LPAREN RPAREN
%token EOL
%start <int> main
%%
let fold_left(op, elem) :=
| elem
| sum = fold_left(op, elem); ~ = op; ~ = elem; { op sum elem }
let app(f, x) ==
~ = f; ~ = x; { f x }
let main :=
~ = expr; EOL; <>
let expr ==
additive_expr
let additive_expr ==
fold_left(additive_op, multiplicative_expr)
let additive_op ==
| PLUS; { ( + ) }
| MINUS; { ( - ) }
let multiplicative_expr ==
fold_left(multiplicative_op, atomic_expr)
let multiplicative_op ==
| TIMES; { ( * ) }
| DIV; { ( / ) }
let atomic_expr == (* this is the culprit *)
| INT
| delimited(LPAREN, expr, RPAREN)
| delimited(LPAREN, app(unary_op, atomic_expr), RPAREN)
let unary_op ==
| MINUS; { (~- ) }
File "inline-cycle.mly", line 5, characters 8-9:
Error: there is a cycle in the definition of b.
Error: there is a cycle of %inline nonterminal symbols:
b refers to c,
which refers back to b.
File "inline-minimal-cycle.mly", line 5, characters 8-9:
Error: there is a cycle in the definition of b.
Error: there is a cycle of %inline nonterminal symbols:
b refers to itself.
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