Skip to content

Commit ccb39b9

Browse files
EmileTrotignonjonludlam
authored andcommitted
Better errors and more permissive parser
1 parent 9583287 commit ccb39b9

File tree

3 files changed

+56
-55
lines changed

3 files changed

+56
-55
lines changed

src/lexer.mll

+26-40
Original file line numberDiff line numberDiff line change
@@ -279,76 +279,60 @@ let language_tag_char =
279279
let delim_char =
280280
['a'-'z' 'A'-'Z' '0'-'9' '_' ]
281281

282-
rule reference_paren_content input start depth_paren depth_curly buffer = parse
282+
rule reference_paren_content input start ref_offset start_offset depth_paren
283+
buffer =
284+
parse
283285
| '('
284286
{
285287
buffer_add_lexeme buffer lexbuf ;
286-
reference_paren_content input start (depth_paren + 1) depth_curly buffer
287-
lexbuf }
288-
| '{'
289-
{
290-
buffer_add_lexeme buffer lexbuf ;
291-
reference_paren_content input start depth_paren (depth_curly + 1) buffer
292-
lexbuf }
288+
reference_paren_content input start ref_offset start_offset
289+
(depth_paren + 1) buffer lexbuf }
293290
| ')'
294291
{
295292
buffer_add_lexeme buffer lexbuf ;
296293
if depth_paren = 0 then
297-
reference_content input start buffer lexbuf
298-
else
299-
reference_paren_content input start (depth_paren - 1) depth_curly
300-
buffer lexbuf }
301-
| '}'
302-
{
303-
if depth_curly = 0 then (
304-
warning
305-
input
306-
~start_offset:(Lexing.lexeme_end lexbuf)
307-
(Parse_error.not_allowed
308-
~what:"'}' (end of reference)"
309-
~in_what:(
310-
Printf.sprintf "'%s' (custom operator)"
311-
(Buffer.contents buffer ))) ;
312-
Buffer.contents buffer )
294+
reference_content input start ref_offset buffer lexbuf
313295
else
314-
(
315-
buffer_add_lexeme buffer lexbuf ;
316-
reference_paren_content input start depth_paren (depth_curly - 1)
317-
buffer lexbuf ) }
296+
reference_paren_content input start ref_offset start_offset
297+
(depth_paren - 1) buffer lexbuf }
318298
| eof
319-
{ reference_content input start buffer lexbuf }
299+
{ warning
300+
input
301+
~start_offset
302+
(Parse_error.unclosed_bracket ~bracket:"(") ;
303+
Buffer.contents buffer }
320304
| _
321305
{
322306
buffer_add_lexeme buffer lexbuf ;
323-
reference_paren_content input start depth_paren depth_curly buffer lexbuf }
307+
reference_paren_content input start ref_offset start_offset depth_paren
308+
buffer lexbuf }
324309

325-
and reference_content input start buffer = parse
310+
and reference_content input start start_offset buffer = parse
326311
| '}'
327312
{
328313
Buffer.contents buffer
329314
}
330315
| '('
331316
{
332317
buffer_add_lexeme buffer lexbuf ;
333-
reference_paren_content input start 0 0 buffer lexbuf
318+
reference_paren_content input start start_offset
319+
(Lexing.lexeme_start lexbuf) 0 buffer lexbuf
334320
}
335321
| '"' [^ '"']* '"'
336322
{
337323
buffer_add_lexeme buffer lexbuf ;
338-
reference_content input start buffer lexbuf
324+
reference_content input start start_offset buffer lexbuf
339325
}
340326
| eof
341327
{ warning
342328
input
343-
~start_offset:(Lexing.lexeme_end lexbuf)
344-
(Parse_error.not_allowed
345-
~what:(Token.describe `End)
346-
~in_what:(Token.describe (reference_token start "")));
347-
Buffer.contents buffer }
329+
~start_offset
330+
(Parse_error.unclosed_bracket ~bracket:start) ;
331+
Buffer.contents buffer }
348332
| _
349333
{
350334
buffer_add_lexeme buffer lexbuf ;
351-
reference_content input start buffer lexbuf }
335+
reference_content input start start_offset buffer lexbuf }
352336

353337
and token input = parse
354338
| horizontal_space* eof
@@ -421,7 +405,9 @@ and token input = parse
421405
| (reference_start as start)
422406
{
423407
let start_offset = Lexing.lexeme_start lexbuf in
424-
let target = reference_content input start (Buffer.create 16) lexbuf in
408+
let target =
409+
reference_content input start start_offset (Buffer.create 16) lexbuf
410+
in
425411
let token = (reference_token start target) in
426412
emit ~start_offset input token }
427413

src/parse_error.ml

+5
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ let not_allowed :
3030
Warning.make ?suggestion "%s is not allowed in %s." (capitalize_ascii what)
3131
in_what
3232

33+
let unclosed_bracket :
34+
?suggestion:string -> bracket:string -> Loc.span -> Warning.t =
35+
fun ?suggestion ~bracket ->
36+
Warning.make ?suggestion "Open bracket '%s' is never closed." bracket
37+
3338
let no_leading_whitespace_in_verbatim : Loc.span -> Warning.t =
3439
Warning.make "'{v' should be followed by whitespace."
3540

test/test.ml

+25-15
Original file line numberDiff line numberDiff line change
@@ -1537,8 +1537,8 @@ let%expect_test _ =
15371537
(((f.ml (1 0) (1 5))
15381538
(paragraph (((f.ml (1 0) (1 5)) (simple ((f.ml (1 2) (1 5)) foo) ())))))))
15391539
(warnings
1540-
( "File \"f.ml\", line 1, characters 5-5:\
1541-
\nEnd of text is not allowed in '{!...}' (cross-reference)."))) |}]
1540+
( "File \"f.ml\", line 1, characters 0-5:\
1541+
\nOpen bracket '{!' is never closed."))) |}]
15421542

15431543
let empty_kind =
15441544
test "{!:foo}";
@@ -1647,8 +1647,8 @@ let%expect_test _ =
16471647
(paragraph
16481648
(((f.ml (1 0) (1 9)) (simple ((f.ml (1 2) (1 9)) val:foo) ())))))))
16491649
(warnings
1650-
( "File \"f.ml\", line 1, characters 9-9:\
1651-
\nEnd of text is not allowed in '{!...}' (cross-reference)."))) |}]
1650+
( "File \"f.ml\", line 1, characters 0-9:\
1651+
\nOpen bracket '{!' is never closed."))) |}]
16521652

16531653
let operator =
16541654
test "{!(>>=)}";
@@ -1720,17 +1720,27 @@ let%expect_test _ =
17201720
(((f.ml (1 0) (1 6)) (simple ((f.ml (1 2) (1 6)) "\"}\"") ())))))))
17211721
(warnings ())) |}]
17221722

1723+
let operator_with_curly_braces =
1724+
test "{!( } )}";
1725+
[%expect
1726+
{|
1727+
((output
1728+
(((f.ml (1 0) (1 8))
1729+
(paragraph
1730+
(((f.ml (1 0) (1 8)) (simple ((f.ml (1 2) (1 8)) "( } )") ())))))))
1731+
(warnings ())) |}]
1732+
17231733
let operator_unbalanced =
17241734
test "{!(.*()}";
17251735
[%expect
17261736
{|
17271737
((output
17281738
(((f.ml (1 0) (1 8))
17291739
(paragraph
1730-
(((f.ml (1 0) (1 8)) (simple ((f.ml (1 2) (1 8)) "(.*()") ())))))))
1740+
(((f.ml (1 0) (1 8)) (simple ((f.ml (1 2) (1 8)) "(.*()}") ())))))))
17311741
(warnings
1732-
( "File \"f.ml\", line 1, characters 8-8:\
1733-
\n'}' (end of reference) is not allowed in '(.*()' (custom operator)."))) |}]
1742+
( "File \"f.ml\", line 1, characters 2-8:\
1743+
\nOpen bracket '(' is never closed."))) |}]
17341744

17351745
let operator_eof =
17361746
test "{!(.*()";
@@ -1741,8 +1751,8 @@ let%expect_test _ =
17411751
(paragraph
17421752
(((f.ml (1 0) (1 7)) (simple ((f.ml (1 2) (1 7)) "(.*()") ())))))))
17431753
(warnings
1744-
( "File \"f.ml\", line 1, characters 7-7:\
1745-
\nEnd of text is not allowed in '{!...}' (cross-reference)."))) |}]
1754+
( "File \"f.ml\", line 1, characters 2-7:\
1755+
\nOpen bracket '(' is never closed."))) |}]
17461756
end in
17471757
()
17481758

@@ -1933,8 +1943,8 @@ let%expect_test _ =
19331943
(paragraph
19341944
(((f.ml (1 0) (1 6)) (with_text ((f.ml (1 3) (1 6)) foo) ())))))))
19351945
(warnings
1936-
( "File \"f.ml\", line 1, characters 6-6:\
1937-
\nEnd of text is not allowed in '{{!...} ...}' (cross-reference)."
1946+
( "File \"f.ml\", line 1, characters 0-6:\
1947+
\nOpen bracket '{{!' is never closed."
19381948
"File \"f.ml\", line 1, characters 6-6:\
19391949
\nEnd of text is not allowed in '{{!...} ...}' (cross-reference)."
19401950
"File \"f.ml\", line 1, characters 0-6:\
@@ -2102,8 +2112,8 @@ let%expect_test _ =
21022112
{|
21032113
((output (((f.ml (1 0) (1 6)) (paragraph (((f.ml (1 0) (1 6)) (foo ())))))))
21042114
(warnings
2105-
( "File \"f.ml\", line 1, characters 6-6:\
2106-
\nEnd of text is not allowed in '{{:...} ...}' (external link)."
2115+
( "File \"f.ml\", line 1, characters 0-6:\
2116+
\nOpen bracket '{{:' is never closed."
21072117
"File \"f.ml\", line 1, characters 6-6:\
21082118
\nEnd of text is not allowed in '{{:...} ...}' (external link)."))) |}]
21092119

@@ -2120,8 +2130,8 @@ let%expect_test _ =
21202130
{|
21212131
((output (((f.ml (1 0) (1 5)) (paragraph (((f.ml (1 0) (1 5)) (foo ())))))))
21222132
(warnings
2123-
( "File \"f.ml\", line 1, characters 5-5:\
2124-
\nEnd of text is not allowed in '{:...} (external link)'."))) |}]
2133+
( "File \"f.ml\", line 1, characters 0-5:\
2134+
\nOpen bracket '{:' is never closed."))) |}]
21252135

21262136
let empty_single_braces =
21272137
test "{:}";

0 commit comments

Comments
 (0)