Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
menhir
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
12
Issues
12
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
POTTIER Francois
menhir
Commits
586c30ec
Commit
586c30ec
authored
Dec 02, 2014
by
POTTIER Francois
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Removed support for the $previouserror keyword.
parent
ca793975
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
45 additions
and
133 deletions
+45
-133
CHANGES
CHANGES
+3
-0
doc/main.tex
doc/main.tex
+1
-7
src/action.ml
src/action.ml
+0
-3
src/action.mli
src/action.mli
+0
-3
src/codeBackend.ml
src/codeBackend.ml
+5
-41
src/codePieces.ml
src/codePieces.ml
+6
-11
src/codePieces.mli
src/codePieces.mli
+4
-6
src/coqBackend.ml
src/coqBackend.ml
+2
-2
src/engine.ml
src/engine.ml
+0
-2
src/engineTypes.ml
src/engineTypes.ml
+0
-6
src/fancy-parser.mly
src/fancy-parser.mly
+20
-37
src/infer.ml
src/infer.ml
+0
-1
src/invariant.ml
src/invariant.ml
+0
-1
src/keyword.ml
src/keyword.ml
+0
-1
src/keyword.mli
src/keyword.mli
+0
-1
src/lexer.mll
src/lexer.mll
+3
-6
src/partialGrammar.ml
src/partialGrammar.ml
+0
-1
src/tableBackend.ml
src/tableBackend.ml
+1
-4
No files found.
CHANGES
View file @
586c30ec
2014/12/02:
Removed support for the $previouserror keyword.
2014/02/18:
In the Coq backend, use ' instead of _ as separator in identifiers.
Also, correct a serious bug that was inadvertently introduced on
...
...
doc/main.tex
View file @
586c30ec
...
...
@@ -1609,7 +1609,7 @@ issues a warning otherwise. This ensures that the parser always terminates.
\paragraph
{
Error-related keywords
}
A couple of error-related keywords are
made available to semantic actions.
The following keyword is
made available to semantic actions.
When the
\verb
+
$syntaxerror
+
keyword is evaluated, evaluation of the semantic
action is aborted, so that the current reduction is abandoned; the current
...
...
@@ -1619,12 +1619,6 @@ handling mode is entered. Note that there is no mechanism for inserting an
might also be desirable. It is unclear whether this keyword is useful; it
might be suppressed in the future.
The
\verb
+
$previouserror
+
keyword evaluates to an integer value, and indicates
how many tokens were successfully shifted since the last
\error
token was
shifted. This allows heuristics such as
\textit
{
``when a new error is detected, do not
display a new error message unless the previous error is ancient enough''
}
to
be implemented if and where desired.
\paragraph
{
When are errors detected?
}
An error is detected when the current state of the automaton has no action on
...
...
src/action.ml
View file @
586c30ec
...
...
@@ -167,9 +167,6 @@ let rec print f action =
in
P
.
expr
action
.
expr
let
has_previouserror
action
=
KeywordSet
.
mem
PreviousError
(
keywords
action
)
let
has_syntaxerror
action
=
KeywordSet
.
mem
SyntaxError
(
keywords
action
)
...
...
src/action.mli
View file @
586c30ec
...
...
@@ -44,9 +44,6 @@ val print: out_channel -> t -> unit
(** [from_stretch s] builds an action out of a textual piece of code. *)
val
from_stretch
:
Stretch
.
t
->
t
(** Check whether the keyword $previouserror is used in the action. *)
val
has_previouserror
:
t
->
bool
(** Check whether the keyword $syntaxerror is used in the action. *)
val
has_syntaxerror
:
t
->
bool
...
...
src/codeBackend.ml
View file @
586c30ec
...
...
@@ -186,17 +186,6 @@ open Interface
were the default behavior; however, recall that error recovery is
disabled unless [--error-recovery] was specified.
When an error is detected and an error production is reduced, the
user might like to know how recent the previous error was, so as
(for instance) to suppress diagnostic messages if it was too
recent. (yacc and ocamlyacc have their own, hard-wired,
idiosyncratic mechanism for that.) We provide access to this
information as follows. When a new error is detected and
[env.shifted] is set to -1, the previous value of [env.shifted] is
saved to [env.previouserror]. Thus, the number of tokens that were
shifted between the two errors is recorded. This information is
then made available to the user via the $previouserror keyword.
I note that error recovery, case (a) above, can cause the parser to
enter an infinite loop. Indeed, the token stream is in principle
infinite -- for instance, many lexers will return an EOF token
...
...
@@ -328,9 +317,6 @@ let fstartp =
let
fendp
=
prefix
"endp"
let
fpreviouserror
=
prefix
"previouserror"
(* The type variable that represents the stack tail. *)
let
tvtail
=
...
...
@@ -421,14 +407,6 @@ let tracecomment (comment : string) (body : expr) : expr =
let
auto2scheme
t
=
scheme
[
tvtail
;
tvresult
]
t
(* ------------------------------------------------------------------------ *)
(* Determine whether at least one semantic action mentions $previouserror. *)
let
previouserror_required
:
bool
=
Production
.
foldx
(
fun
prod
accu
->
accu
||
Action
.
has_previouserror
(
Production
.
action
prod
)
)
false
(* ------------------------------------------------------------------------ *)
(* Determine whether the [goto] function for nonterminal [nt] will push
a new cell onto the stack. If it doesn't, then that job is delegated
...
...
@@ -604,7 +582,7 @@ let envtypedef = {
typename
=
tcenv
;
typeparams
=
[]
;
typerhs
=
TDefRecord
(
[
TDefRecord
[
(* The lexer itself. *)
...
...
@@ -635,14 +613,7 @@ let envtypedef = {
field
true
fshifted
tint
;
]
@
(* If at least one semantic action mentions $previouserror, then we keep
track of this information. *)
insertif
previouserror_required
(
field
true
fpreviouserror
tint
)
);
];
typeconstraint
=
None
}
...
...
@@ -1146,11 +1117,7 @@ let defaultreductioncomment toks e =
(* This produces some bookkeeping code that is used when initiating
error handling.
First, we copy [env.shifted] to [env.previouserror]. Of course,
this is done only if at least one semantic action uses the
[$previouserror] keyword.
Then, we reset the count of tokens shifted since the last error to
We reset the count of tokens shifted since the last error to
-1, so that it becomes zero *after* the error token itself is
shifted. By convention, when [shifted] is -1, the field [env.token]
becomes meaningless and one considers that the first token on the
...
...
@@ -1163,8 +1130,6 @@ let errorbookkeeping e =
tracecomment
"Initiating error handling"
(
blet
(
concatif
previouserror_required
[
PUnit
,
ERecordWrite
(
EVar
env
,
fpreviouserror
,
ERecordAccess
(
EVar
env
,
fshifted
))
]
@
[
PUnit
,
ERecordWrite
(
EVar
env
,
fshifted
,
EIntConst
(
-
1
))
]
,
e
))
...
...
@@ -1446,7 +1411,7 @@ let reducebody prod =
(
pat
,
EVar
stack
)
::
unitbindings
@
posbindings
action
@
extrabindings
fpreviouserror
action
,
extrabindings
action
,
(* If the semantic action is susceptible of raising [Error],
use a [let/unless] construct, otherwise use [let]. *)
...
...
@@ -1801,8 +1766,7 @@ let initenvdef =
(
fstartp
,
ERecordAccess
(
EVar
lexbuf
,
"Lexing.lex_start_p"
));
(
fendp
,
ERecordAccess
(
EVar
lexbuf
,
"Lexing.lex_curr_p"
));
(
fshifted
,
EMaxInt
)
]
@
insertif
previouserror_required
(
fpreviouserror
,
EMaxInt
)
]
)
)
)
,
...
...
src/codePieces.ml
View file @
586c30ec
...
...
@@ -192,18 +192,15 @@ let destructuretokendef name codomain bindsemv branch = {
(* Bindings for exotic keywords. *)
(* [extrabindings fpreviouserror action] provides definitions for the
[$startofs], [$endofs], and [$previouserror] keywords, if required
by a semantic action. The parameter [fpreviouserror] is the name of
the [previouserror] field in the environment -- the table-based and
code-based back-ends use different names. The parameter [action] is
the semantic action within which these keywords might be used. *)
(* [extrabindings action] provides definitions for the [$startofs] and
[$endofs] keywords, if required by a semantic action. The parameter
[action] is the semantic action within which these keywords might be
used. *)
(* The [ofs] keyword family is defined in terms of the [pos] family by
accessing the [pos_cnum] field. The [$previouserror] keyword simply
provides access to the current value of [env.previouserror]. *)
accessing the [pos_cnum] field. *)
let
extrabindings
fpreviouserror
action
=
let
extrabindings
action
=
Keyword
.
KeywordSet
.
fold
(
fun
keyword
bindings
->
match
keyword
with
|
Keyword
.
Dollar
_
...
...
@@ -213,8 +210,6 @@ let extrabindings fpreviouserror action =
|
Keyword
.
Position
(
s
,
w
,
(
Keyword
.
FlavorOffset
as
f
))
->
(
PVar
(
Keyword
.
posvar
s
w
f
)
,
ERecordAccess
(
EVar
(
Keyword
.
posvar
s
w
Keyword
.
FlavorPosition
)
,
"Lexing.pos_cnum"
))
::
bindings
|
Keyword
.
PreviousError
->
(
PVar
"_previouserror"
,
ERecordAccess
(
EVar
env
,
fpreviouserror
))
::
bindings
)
(
Action
.
keywords
action
)
[]
(* ------------------------------------------------------------------------ *)
...
...
src/codePieces.mli
View file @
586c30ec
...
...
@@ -108,13 +108,11 @@ val destructuretokendef: string -> typ -> bool -> (Terminal.t -> expr) -> valdef
(* Bindings for exotic keywords. *)
(* This provides definitions for the [$startofs], [$endofs], and
[$previouserror] keywords, if required by a semantic action. The
[ofs] keyword family is defined in terms of the [pos] family by
accessing the [pos_cnum] field. The [$previouserror] keyword simply
provides access to the current value of [env.previouserror]. *)
(* This provides definitions for the [$startofs] and [$endofs] keywords, if
required by a semantic action. The [ofs] keyword family is defined in terms
of the [pos] family by accessing the [pos_cnum] field. *)
val
extrabindings
:
string
->
Action
.
t
->
(
pattern
*
expr
)
list
val
extrabindings
:
Action
.
t
->
(
pattern
*
expr
)
list
(* ------------------------------------------------------------------------ *)
...
...
src/coqBackend.ml
View file @
586c30ec
...
...
@@ -69,10 +69,10 @@ module Run (T: sig end) = struct
|
Some
_
->
()
);
Production
.
iterx
(
fun
prod
->
let
act
=
Production
.
action
prod
in
if
Action
.
has_
previouserror
act
||
Action
.
has_
syntaxerror
act
||
if
Action
.
has_syntaxerror
act
||
Action
.
has_leftstart
act
||
Action
.
has_leftend
act
||
Action
.
use_dollar
act
then
Error
.
error
[]
(
"$
previouserror, $
syntaxerror, $start, $end, $i are not "
^
Error
.
error
[]
(
"$syntaxerror, $start, $end, $i are not "
^
"supported by the coq back-end"
))
end
;
...
...
src/engine.ml
View file @
586c30ec
...
...
@@ -231,7 +231,6 @@ module Make (T : TABLE) = struct
and
errorbookkeeping
env
=
Log
.
initiating_error_handling
()
;
env
.
previouserror
<-
env
.
shifted
;
env
.
shifted
<-
(
-
1
);
error
env
...
...
@@ -329,7 +328,6 @@ module Make (T : TABLE) = struct
lexbuf
=
lexbuf
;
token
=
token
;
shifted
=
max_int
;
previouserror
=
max_int
;
stack
=
empty
;
current
=
s
;
}
in
...
...
src/engineTypes.ml
View file @
586c30ec
...
...
@@ -67,12 +67,6 @@ type ('state, 'semantic_value, 'token) env = {
mutable
shifted
:
int
;
(* A copy of the value of [shifted] just before the most recent error
was detected. This value is not used by the automaton itself, but
is made accessible to semantic actions. *)
mutable
previouserror
:
int
;
(* The stack. In [CodeBackend], it is passed around on its own,
whereas, here, it is accessed via the environment. *)
...
...
src/fancy-parser.mly
View file @
586c30ec
/*
This
is
the
fancy
version
of
the
parser
,
to
be
processed
by
menhir
.
It
is
kept
in
sync
with
[
Parser
]
,
but
exercises
menhir's
features
.
*/
/*
As
of
2014
/
12
/
02
,
the
$
previouserror
keyword
and
the
--
error
-
recovery
mode
no
longer
exists
.
Thus
,
we
replace
all
calls
to
[
Error
.
signal
]
with
calls
to
[
Error
.
error
]
,
and
report
just
one
error
.
*/
/*
-------------------------------------------------------------------------
*/
/*
Imports
.
*/
...
...
@@ -79,12 +83,11 @@ declaration:
|
TOKEN
OCAMLTYPE
?
clist
(
terminal
)
error
|
TOKEN
OCAMLTYPE
?
error
{
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"\
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"\
Syntax error in a %token declaration.
Here are sample valid declarations:
%token DOT SEMICOLON
%token <string> LID UID"
;
[]
%token <string> LID UID"
}
|
START
t
=
OCAMLTYPE
?
nts
=
clist
(
nonterminal
)
%
prec
decl
...
...
@@ -100,12 +103,11 @@ Here are sample valid declarations:
|
START
OCAMLTYPE
?
clist
(
nonterminal
)
error
|
START
OCAMLTYPE
?
error
{
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"\
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"\
Syntax error in a %start declaration.
Here are sample valid declarations:
%start expression phrase
%start <int> date time"
;
[]
%start <int> date time"
}
|
TYPE
t
=
OCAMLTYPE
ss
=
clist
(
actual_parameter
)
%
prec
decl
...
...
@@ -115,12 +117,11 @@ Here are sample valid declarations:
|
TYPE
OCAMLTYPE
clist
(
actual_parameter
)
error
|
TYPE
OCAMLTYPE
error
|
TYPE
error
{
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"\
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"\
Syntax error in a %type declaration.
Here are sample valid declarations:
%type <Syntax.expression> expression
%type <int> date time"
;
[]
%type <int> date time"
}
|
k
=
priority_keyword
ss
=
clist
(
symbol
)
%
prec
decl
...
...
@@ -129,34 +130,26 @@ Here are sample valid declarations:
|
priority_keyword
clist
(
symbol
)
error
|
priority_keyword
error
{
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"\
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"\
Syntax error in a precedence declaration.
Here are sample valid declarations:
%left PLUS TIMES
%nonassoc unary_minus
%right CONCAT"
;
[]
%right CONCAT"
}
|
PARAMETER
t
=
OCAMLTYPE
{
[
with_poss
$
startpos
$
endpos
(
DParameter
t
)
]
}
|
PARAMETER
error
{
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"\
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"\
Syntax error in a %parameter declaration.
Here is a sample valid declaration:
%parameter <X : sig type t end>"
;
[]
%parameter <X : sig type t end>"
}
/*
This
error
production
should
lead
to
resynchronization
on
the
next
%
something
.
The
use
of
$
previouserror
prevents
reporting
errors
that
are
too
close
to
one
another
--
presumably
,
the
second
error
only
means
that
we
failed
to
properly
recover
after
the
first
error
.
*/
|
error
{
if
$
previouserror
>=
3
then
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside a declaration."
;
[]
}
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside a declaration."
}
/*
This
production
recognizes
tokens
that
are
valid
in
the
rules
section
,
but
not
in
the
declarations
section
.
This
is
a
hint
that
a
%%
was
...
...
@@ -164,15 +157,9 @@ Here is a sample valid declaration:
|
rule_specific_token
{
if
$
previouserror
>=
3
then
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside a declaration.
\n
\
Did you perhaps forget the %% that separates declarations and rules?"
;
(* Do not attempt to perform error recovery. There is no way of
forcing the automaton into a state where rules are expected. *)
exit
1
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside a declaration.
\n
\
Did you perhaps forget the %% that separates declarations and rules?"
}
priority_keyword
:
...
...
@@ -250,9 +237,7 @@ rule:
|
error
/*
This
error
production
should
lead
to
resynchronization
on
the
next
well
-
formed
rule
.
*/
{
if
$
previouserror
>=
3
then
Error
.
signal
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside the definition of a nonterminal symbol."
;
[]
}
{
Error
.
error
(
Positions
.
two
$
startpos
$
endpos
)
"Syntax error inside the definition of a nonterminal symbol."
}
flags
:
/*
epsilon
*/
...
...
@@ -296,9 +281,7 @@ production_group:
/*
This
error
production
should
lead
to
resynchronization
on
the
next
semantic
action
,
unless
the
end
of
file
is
reached
before
a
semantic
action
is
found
.
*/
{
if
$
previouserror
>=
3
then
Error
.
signal
(
Positions
.
two
$
startpos
(
$
1
)
$
endpos
(
$
1
))
"Syntax error inside a production."
;
[]
}
{
Error
.
error
(
Positions
.
two
$
startpos
(
$
1
)
$
endpos
(
$
1
))
"Syntax error inside a production."
}
%
inline
precedence
:
PREC
symbol
=
symbol
...
...
src/infer.ml
View file @
586c30ec
...
...
@@ -100,7 +100,6 @@ let actiondef grammar symbol branch =
right-hand side. *)
let
formals
=
PAnnot
(
PVar
"_previouserror"
,
tint
)
::
PAnnot
(
PVar
"_eRR"
,
texn
)
::
PAnnot
(
PVar
"_startpos"
,
tposition
)
::
PAnnot
(
PVar
"_endpos"
,
tposition
)
::
...
...
src/invariant.ml
View file @
586c30ec
...
...
@@ -646,7 +646,6 @@ let () =
KeywordSet
.
iter
(
function
|
Dollar
_
|
PreviousError
|
SyntaxError
->
()
|
Position
(
Left
,
where
,
_
)
->
...
...
src/keyword.ml
View file @
586c30ec
...
...
@@ -34,7 +34,6 @@ type subject =
type
keyword
=
|
Dollar
of
int
|
Position
of
subject
*
where
*
flavor
|
PreviousError
|
SyntaxError
(* ------------------------------------------------------------------------- *)
...
...
src/keyword.mli
View file @
586c30ec
...
...
@@ -31,7 +31,6 @@ type subject =
type
keyword
=
|
Dollar
of
int
|
Position
of
subject
*
where
*
flavor
|
PreviousError
|
SyntaxError
(* This maps a [Position] keyword to the name of the variable that the
...
...
src/lexer.mll
View file @
586c30ec
...
...
@@ -60,8 +60,7 @@
overwrite
content
ofs
'
$
'
'
_'
;
match
keyword
with
|
Keyword
.
Dollar
_
|
Keyword
.
Position
(
Keyword
.
Left
,
_
,
_
)
|
Keyword
.
PreviousError
->
|
Keyword
.
Position
(
Keyword
.
Left
,
_
,
_
)
->
()
|
Keyword
.
SyntaxError
->
(* $syntaxerror is replaced with
...
...
@@ -374,8 +373,7 @@ and action percent openingpos pkeywords = parse
{
let
pkeyword
=
mk_keyword
lexbuf
w
f
n
id
in
action
percent
openingpos
(
pkeyword
::
pkeywords
)
lexbuf
}
|
previouserror
{
let
pkeyword
=
with_cpos
lexbuf
Keyword
.
PreviousError
in
action
percent
openingpos
(
pkeyword
::
pkeywords
)
lexbuf
}
{
error1
(
lexeme_start_p
lexbuf
)
"$previouserror is no longer supported."
}
|
syntaxerror
{
let
pkeyword
=
with_cpos
lexbuf
Keyword
.
SyntaxError
in
action
percent
openingpos
(
pkeyword
::
pkeywords
)
lexbuf
}
...
...
@@ -413,8 +411,7 @@ and parentheses openingpos pkeywords = parse
{ let pkeyword = mk_keyword lexbuf w f n id in
parentheses openingpos (pkeyword :: pkeywords) lexbuf }
| previouserror
{ let pkeyword = with_cpos lexbuf Keyword.PreviousError in
parentheses openingpos (pkeyword :: pkeywords) lexbuf }
{ error1 (lexeme_start_p lexbuf) "$previouserror is no longer supported." }
| syntaxerror
{ let pkeyword = with_cpos lexbuf Keyword.SyntaxError in
parentheses openingpos (pkeyword :: pkeywords) lexbuf }
...
...
src/partialGrammar.ml
View file @
586c30ec
...
...
@@ -614,7 +614,6 @@ let check_keywords grammar producers action =
Error
.
errorp
keyword
(
Printf
.
sprintf
"%s refers to a nonexistent symbol."
id
)
|
Position
(
Left
,
_
,
_
)
|
PreviousError
|
SyntaxError
->
()
)
(
Action
.
pkeywords
action
)
...
...
src/tableBackend.ml
View file @
586c30ec
...
...
@@ -55,9 +55,6 @@ let fcurrent =
let
flexbuf
=
field
"lexbuf"
let
fpreviouserror
=
field
"previouserror"
let
flex_start_p
=
"Lexing.lex_start_p"
...
...
@@ -202,7 +199,7 @@ let reducebody prod =
(
pat
,
EVar
stack
)
::
(* destructure the stack *)
casts
@
(* perform type casts *)
posbindings
@
(* bind [startp] and [endp] *)
extrabindings
fpreviouserror
action
@
(* add bindings for the weird keywords *)
extrabindings
action
@
(* add bindings for the weird keywords *)
[
PVar
semv
,
act
]
,
(* run the user's code and bind [semv] *)
ERecordWrite
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment