let insert_tree entry gsymbols action tree =
let rec insert symbols tree =
match symbols with
| s :: sl -> insert_in_tree s sl tree
| [] ->
(match tree with
| Node { node = s; son = son; brother = bro } ->
Node
{
node = s;
son = son;
brother = insert [] bro;
}
| LocAct (old_action, action_list) ->
let () =
if !(entry.egram.warning_verbose)
then
eprintf
"<W> Grammar extension: in [%s] some rule has been masked@."
entry.ename
else ()
in LocAct (action, (old_action :: action_list))
| DeadEnd -> LocAct (action, []))
and insert_in_tree s sl tree =
match try_insert s sl tree with
| Some t -> t
| None ->
Node
{
node = s;
son = insert sl DeadEnd;
brother = tree;
}
and try_insert s sl tree =
match tree with
| Node { node = s1; son = son; brother = bro } ->
if Tools.eq_symbol s s1
then
(let t =
Node
{
node = s1;
son = insert sl son;
brother = bro;
}
in Some t)
else
if
(is_before s1 s) ||
((derive_eps s) && (not (derive_eps s1)))
then
(let bro =
match try_insert s sl bro with
| Some bro -> bro
| None ->
Node
{
node = s;
son = insert sl DeadEnd;
brother = bro;
} in
let t =
Node { node = s1; son = son; brother = bro; }
in Some t)
else
(match try_insert s sl bro with
| Some bro ->
let t =
Node
{ node = s1; son = son; brother = bro; }
in Some t
| None -> None)
| LocAct (_, _) | DeadEnd -> None
and insert_new =
function
| s :: sl ->
Node
{ node = s; son = insert_new sl; brother = DeadEnd;
}
| [] -> LocAct (action, [])
in insert gsymbols tree