Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reerror: error-resilient parsing (same as Merlin for OCaml) #2439

Closed
wants to merge 46 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d239fd9
split reason_toolchain in a few sub-modules
let-def Apr 27, 2019
b6b357e
Remove menhir error messages
let-def Apr 28, 2019
416c123
removed more menhir-related error management
let-def Apr 28, 2019
281b4c2
refactor errors in semantic actions
let-def Apr 28, 2019
5cd57b8
REMOVE ME: some notes
let-def Apr 28, 2019
caecbb5
move more error management code to Reason_errors
let-def Apr 29, 2019
946dbec
recovery annotations
let-def Apr 29, 2019
0c98aaa
add recovery tool
let-def Apr 29, 2019
11a4eae
build recovery
let-def Apr 29, 2019
565e31d
WIP lexer -> declarative_lexer, remove state
let-def Apr 30, 2019
85771e0
rewrite lexer to isolate state
let-def Apr 30, 2019
ac090ac
factor the deterministic parser out of reason_toolchain
let-def Apr 30, 2019
07da552
implement support for POSTFIX
let-def Apr 30, 2019
f3f8837
introduce reason-multi-parser
let-def May 1, 2019
4b0d0a6
Switch on recovery
let-def May 2, 2019
1c1b6e1
add TODO plan
let-def May 2, 2019
8644c52
oops, better to recover more than one token
let-def May 2, 2019
b0a1e8d
fix invalid docstrings merging
let-def May 2, 2019
f88247c
fix DOCSTRING parsing
let-def May 2, 2019
bc33004
fishy printing
let-def May 2, 2019
ce11819
recovery is now optional
let-def May 2, 2019
eb6f169
update TODO
let-def May 2, 2019
51a15b7
attach errors for intf and impl
let-def May 2, 2019
b18723e
Implement slightly better error messages
let-def May 13, 2019
a61d42f
Update reason.opam
let-def May 13, 2019
cda93f6
handle EOF
let-def May 13, 2019
76e0ce1
Use Migrate_parsetree.Ast_404 instead of Ast_404
May 24, 2019
c081351
Reenable previous error messages (through Reason_parser_explain)
May 24, 2019
bcabb64
detect unclosed parentheses
May 24, 2019
85dabfa
TEMPORARY: tweak unclosed parenthesis error message
let-def May 25, 2019
870100b
TEMPORARY: disable JSX error messages on recovery
let-def May 25, 2019
3b230e4
wip: distinguish recovery errors
May 29, 2019
4bea463
insert extension nodes only in recovery mode
let-def Jun 8, 2019
7be758a
build with 4.02
Jun 12, 2019
c412f59
instrument reason-error message printer
Jun 12, 2019
2a1c09f
raise fatal errors if not using Reason_config.recoverable
Jun 12, 2019
46a5072
no need for lexer_report_error
Jul 4, 2019
e754a8e
fix reporting of errors
Jul 4, 2019
546f078
refactor version-dependent definitions
Jul 4, 2019
be195c4
move error manipulation to reason_syntax_util
Jul 4, 2019
4075318
menhir-recover: hide warnings about recover.cost attribute on production
Jul 4, 2019
45c7113
fix error reporting (pre 4.08)
let-def Aug 9, 2019
5d0f827
update more tests
let-def Aug 9, 2019
4a91962
Abstract version-dependent compiler-libs definitions to ocaml_util.ml
let-def Aug 9, 2019
50255c4
update tests
let-def Aug 9, 2019
474900e
add fix dependency to esy
Aug 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions PLAN
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Fix error recovery & error reporting

Step 1: remove existing implementation

OK * Put reason parser in its own file
OK * Remove menhir error management:
OK - remove "error" token
OK - remove error messages infrastructure
OK Now message defaults to "Syntax error"
* Fix reported error location (when recovering or not)

Step 2: reintroduce recovery
* Preprocess grammar:
- check exhaustivity of recovery
- produce a mapping of automaton states to automaton-items suitable for
recovery
* Instrument parser:
- first, always complete the AST and drop user input (":'(")
- second, introduce an heuristic for recovering based on location

Step 3: reintroduce error messages
* Ask the crowd:
What should messages look like?
Which situations are tricky or counter-intuitive?
* Make a testsuite representative of common syntax errors
* ... Design an analysis sufficient to produce the messages automatically
:P
1 change: 1 addition & 0 deletions esy.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"version": "3.5.0",
"dependencies": {
"ocaml": " >= 4.2.0 < 4.9.0",
"@opam/fix": "*",
"@opam/ocamlfind": "*",
"@opam/menhir": " >= 20170418.0.0",
"@opam/utop": " >= 1.17.0 < 2.3.0",
Expand Down
2 changes: 1 addition & 1 deletion formatTest/errorTests/expected_output/reservedField.re
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedField.re", line 1, characters 11-15:
Error: 1054: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File "reservedField.re", line 1, characters 11-15:
1 | let x = {< type >};
^^^^
Error: 1054: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead

2 changes: 1 addition & 1 deletion formatTest/errorTests/expected_output/reservedRecord.re
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedRecord.re", line 1, characters 24-28:
Error: 1863: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File "reservedRecord.re", line 1, characters 24-28:
1 | let foo = { foo: "bar", type: "qux" };
^^^^
Error: 1863: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead

Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedRecordPunned.re", line 1, characters 22-26:
Error: 3411: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File "reservedRecordPunned.re", line 1, characters 22-26:
1 | let foo = { ...other, type };
^^^^
Error: 3411: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead

2 changes: 1 addition & 1 deletion formatTest/errorTests/expected_output/reservedRecordTy
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedRecordTypePunned.re", line 1, characters 11-15:
Error: 770: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedRecordType.re", line 1, characters 11-15:
Error: 770: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File "reservedRecordType.re", line 1, characters 11-15:
1 | type x = { type: string };
^^^^
Error: 770: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead

Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
File "reservedRecordTypePunned.re", line 1, characters 11-15:
Error: 770: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
File "reservedRecordTypePunned.re", line 1, characters 11-15:
1 | type x = { type };
^^^^
Error: 770: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead
Error: type is a reserved keyword, it cannot be used as an identifier. Try `type_` or `_type` instead

1 change: 1 addition & 0 deletions reason.opam
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ depends: [
"ocamlfind" {build}
"menhir" {>= "20170418"}
"merlin-extend" {>= "0.4"}
"fix"
"result"
"ocaml-migrate-parsetree"
]
Expand Down
15 changes: 15 additions & 0 deletions src/menhir-recover/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.PHONY: all clean
jordwalke marked this conversation as resolved.
Show resolved Hide resolved

all:
dune build main.exe

clean:
dune clean

test-dijkstra:
dune build main.exe demo/calc.exe
_build/default/main.exe _build/default/demo/parser.cmly

test-custom:
dune build main.exe demo/calc.exe
_build/default/main.exe -custom _build/default/demo/parser.cmly
Loading