Commit 428429f0 authored by POTTIER Francois's avatar POTTIER Francois

Changed the concrete syntax of the new keyword to [$endpos($0)].

Now supported by the table back-end.
parent 2e8ede8b
...@@ -58,5 +58,5 @@ val has_leftend: t -> bool ...@@ -58,5 +58,5 @@ val has_leftend: t -> bool
(** Check whether the keyword $start or $end is used in the action. *) (** Check whether the keyword $start or $end is used in the action. *)
val has_left: t -> bool val has_left: t -> bool
(** Check whether the keyword $beforeend is used in the action. *) (** Check whether the keyword $endpos($0) is used in the action. *)
val has_beforeend: t -> bool val has_beforeend: t -> bool
...@@ -48,6 +48,11 @@ let token = ...@@ -48,6 +48,11 @@ let token =
that binding these variables before executing a semantic action is that binding these variables before executing a semantic action is
meaningful. *) meaningful. *)
(* These names should agree with the printing function [Keyword.posvar]. *)
let beforeendp =
"_endpos__0_"
let startp = let startp =
"_startpos" "_startpos"
......
...@@ -37,6 +37,7 @@ val token: string ...@@ -37,6 +37,7 @@ val token: string
(* Variables used to hold start and end positions. *) (* Variables used to hold start and end positions. *)
val beforeendp: string
val startp: string val startp: string
val endp: string val endp: string
......
...@@ -620,7 +620,7 @@ let rewind node : instruction = ...@@ -620,7 +620,7 @@ let rewind node : instruction =
[sym] must keep track of its end position. (Furthermore, if some initial [sym] must keep track of its end position. (Furthermore, if some initial
state can reduce an epsilon production, then the sentinel cell at the bottom state can reduce an epsilon production, then the sentinel cell at the bottom
of the stack must contain a position. This does not concern us here.) of the stack must contain a position. This does not concern us here.)
Similarly, if some state whose incoming symbol is [sym] uses [$beforeendpos], Similarly, if some state whose incoming symbol is [sym] uses [$endpos($0)],
then [sym] must keep track of its end position. *) then [sym] must keep track of its end position. *)
open Keyword open Keyword
...@@ -667,10 +667,10 @@ let () = ...@@ -667,10 +667,10 @@ let () =
| SyntaxError -> | SyntaxError ->
() ()
| Position (Before, _, _) -> | Position (Before, _, _) ->
(* Doing nothing here is OK because the presence of [$beforepos] (* Doing nothing here is OK because the presence of [$endpos($0)]
in a semantic action is taken account below when we look at in a semantic action is taken account below when we look at
every state and check whether it can reduce a production whose every state and check whether it can reduce a production whose
semantic action contains [$beforepos]. *) semantic action contains [$endpos($0)]. *)
() ()
| Position (Left, where, _) -> | Position (Left, where, _) ->
require_aux where prod require_aux where prod
......
...@@ -57,7 +57,7 @@ let where = function ...@@ -57,7 +57,7 @@ let where = function
let subject = function let subject = function
| Before -> | Before ->
"before" "__0_"
| Left -> | Left ->
"" ""
| RightNamed id -> | RightNamed id ->
......
...@@ -25,7 +25,7 @@ type where = ...@@ -25,7 +25,7 @@ type where =
and desugared as a [subject] during keywords rewriting into actual and desugared as a [subject] during keywords rewriting into actual
OCaml identifiers. (See {!Lexer.transform_keywords}.) OCaml identifiers. (See {!Lexer.transform_keywords}.)
We add a new subject, [Before], which corresponds to [$beforeendpos] We add a new subject, [Before], which corresponds to [$endpos($0)]
in concrete syntax. We adopt the (slightly awkward) convention that in concrete syntax. We adopt the (slightly awkward) convention that
when the subject is [Before], the [where] component must be [WhereEnd]. *) when the subject is [Before], the [where] component must be [WhereEnd]. *)
type parsed_subject = type parsed_subject =
......
...@@ -844,7 +844,7 @@ let invert reductions : TerminalSet.t ProductionMap.t = ...@@ -844,7 +844,7 @@ let invert reductions : TerminalSet.t ProductionMap.t =
(* This is the case if [s] can reduce an epsilon production whose semantic (* This is the case if [s] can reduce an epsilon production whose semantic
action uses [$startpos] or [$endpos]. This is also the case if [s] can action uses [$startpos] or [$endpos]. This is also the case if [s] can
reduce a production whose semantic action uses [$beforeendpos]. *) reduce a production whose semantic action uses [$endpos($0)]. *)
let has_beforeend node = let has_beforeend node =
TerminalMap.fold (fun _ prods accu -> TerminalMap.fold (fun _ prods accu ->
......
...@@ -26,7 +26,7 @@ let index2id producers i = ...@@ -26,7 +26,7 @@ let index2id producers i =
respectively. *) respectively. *)
(* It does not modify [$startpos] or [$endpos], of course, nor [$startpos(y)] (* It does not modify [$startpos] or [$endpos], of course, nor [$startpos(y)]
and [$endpos(y)] for some other [y]. It does not modify [$beforeendpos]. *) and [$endpos(y)] for some other [y]. It does not modify [$endpos($0)]. *)
let rename_sw_outer (x, startp, endp) (subject, where) : (subject * where) option = let rename_sw_outer (x, startp, endp) (subject, where) : (subject * where) option =
match subject with match subject with
...@@ -42,16 +42,16 @@ let rename_sw_outer (x, startp, endp) (subject, where) : (subject * where) optio ...@@ -42,16 +42,16 @@ let rename_sw_outer (x, startp, endp) (subject, where) : (subject * where) optio
None None
(* [rename_sw_inner] transforms the keywords in the inner production (the callee) (* [rename_sw_inner] transforms the keywords in the inner production (the callee)
during inlining. It looks for [$beforepos], [$startpos], and [$endpos,] and during inlining. It looks for [$endpos($0)], [$startpos], and [$endpos], and
replaces them with [beforep], [startp], and [endp], respectively. *) replaces them with [beforeendp], [startp], and [endp], respectively. *)
(* It does not modify any [$startpos(x)], of course. *) (* It does not modify any [$startpos(x)], of course. *)
let rename_sw_inner (beforep, startp, endp) (subject, where) : (subject * where) option = let rename_sw_inner (beforeendp, startp, endp) (subject, where) : (subject * where) option =
match subject, where with match subject, where with
| Before, _ -> | Before, _ ->
assert (where = WhereEnd); assert (where = WhereEnd);
Some beforep Some beforeendp
| Left, WhereStart -> | Left, WhereStart ->
Some startp Some startp
| Left, WhereEnd -> | Left, WhereEnd ->
...@@ -191,7 +191,7 @@ let inline grammar = ...@@ -191,7 +191,7 @@ let inline grammar =
else else
(* If the inner production is epsilon and the prefix is empty, then (* If the inner production is epsilon and the prefix is empty, then
we need to look up the end position stored in the top stack cell. we need to look up the end position stored in the top stack cell.
This is the reason why we need the keyword [$beforeendpos]. It is This is the reason why we need the keyword [$endpos($0)]. It is
required in this case to preserve the semantics of $startpos and required in this case to preserve the semantics of $startpos and
$endpos. *) $endpos. *)
Before, WhereEnd Before, WhereEnd
...@@ -215,13 +215,13 @@ let inline grammar = ...@@ -215,13 +215,13 @@ let inline grammar =
in in
(* We must also transform [$beforeendpos] if it used by the inner (* We must also transform [$endpos($0)] if it used by the inner
production. It refers to the end position of the stack cell production. It refers to the end position of the stack cell
that comes before the inner production. So, if the prefix is that comes before the inner production. So, if the prefix is
non-empty, then it translates to the end position of the last non-empty, then it translates to the end position of the last
element of the prefix. Otherwise, it translates to [$beforeendpos]. *) element of the prefix. Otherwise, it translates to [$endpos($0)]. *)
let beforep = let beforeendp =
if prefix > 0 then if prefix > 0 then
RightNamed (index2id (prefix - 1)), WhereEnd RightNamed (index2id (prefix - 1)), WhereEnd
else else
...@@ -232,7 +232,7 @@ let inline grammar = ...@@ -232,7 +232,7 @@ let inline grammar =
let outer_action = let outer_action =
Action.rename (rename_sw_outer (c, startp, endp)) [] b.action Action.rename (rename_sw_outer (c, startp, endp)) [] b.action
and action' = and action' =
Action.rename (rename_sw_inner (beforep, startp, endp)) phi pb.action Action.rename (rename_sw_inner (beforeendp, startp, endp)) phi pb.action
in in
{ b with { b with
......
...@@ -205,10 +205,16 @@ let reducebody prod = ...@@ -205,10 +205,16 @@ let reducebody prod =
) (0, PVar stack, []) (Invariant.prodstack prod) ) (0, PVar stack, []) (Invariant.prodstack prod)
in in
(* Determine start and end positions for the left-hand side of the (* Determine beforeend/start/end positions for the left-hand side of the
production. *) production, and bind them to the conventional variables [beforeendp],
[startp], and [endp]. These variables may be unused by the semantic
action, in which case these bindings are dead code and can be ignored
by the OCaml compiler. *)
let posbindings = let posbindings =
( PVar beforeendp,
endpos_of_top_stack_cell
) ::
( PVar startp, ( PVar startp,
if length > 0 then if length > 0 then
EVar (Printf.sprintf "_startpos_%s_" ids.(0)) EVar (Printf.sprintf "_startpos_%s_" ids.(0))
......
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