Skip to content

Commit 7fb434a

Browse files
authored
Merge pull request ocaml#14654 from MisterDA/fix-14653
Fix non-exhaustive `directive` rule in lexer
2 parents cccfb13 + ba98849 commit 7fb434a

4 files changed

Lines changed: 55 additions & 5 deletions

File tree

Changes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,9 @@ Working version
129129
constructor declarations.
130130
(Florian Angeletti, review by Gabriel Scherer)
131131

132+
- #14654: Fix non-exhaustive directive rule in lexer.
133+
(Antonin Décimo, review by Martin Jambon and Gabriel Scherer)
134+
132135
### Build system:
133136

134137
### Bug fixes:

parsing/lexer.mll

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -650,9 +650,13 @@ rule token = parse
650650
}
651651
| "#"
652652
{ let at_beginning_of_line pos = (pos.pos_cnum = pos.pos_bol) in
653-
if not (at_beginning_of_line lexbuf.lex_start_p)
654-
then HASH
655-
else try directive lexbuf with Failure _ -> HASH
653+
if at_beginning_of_line lexbuf.lex_start_p
654+
&& lex_directive lexbuf
655+
then
656+
(* [lex_directive] silently updates location information on success;
657+
continue to the next token *)
658+
token lexbuf
659+
else HASH
656660
}
657661
| "&" { AMPERSAND }
658662
| "&&" { AMPERAMPER }
@@ -727,7 +731,7 @@ rule token = parse
727731
| (_ as illegal_char)
728732
{ error lexbuf (Illegal_character illegal_char) }
729733
730-
and directive = parse
734+
and lex_directive = parse
731735
| ([' ' '\t']* (['0'-'9']+ as num) [' ' '\t']*
732736
("\"" ([^ '\010' '\013' '\"' ] * as name) "\"") as directive)
733737
[^ '\010' '\013'] *
@@ -742,8 +746,16 @@ and directive = parse
742746
positive, but we have never guarded against this and it
743747
might have useful hackish uses. *)
744748
update_loc lexbuf (Some name) (line_num - 1) true 0;
745-
token lexbuf
749+
true
746750
}
751+
| ""
752+
{ (* hack: fix the location to include the `#` character we consumed
753+
before calling [lex_directive]. *)
754+
let pos = lexbuf.lex_start_p in
755+
lexbuf.lex_start_p <- { pos with pos_cnum = pos.pos_cnum - 1 };
756+
false
757+
}
758+
747759
and comment = parse
748760
"(*"
749761
{ comment_start_loc := (Location.curr lexbuf) :: !comment_start_loc;

testsuite/tests/parsing/hash_ambiguity.compilers.reference

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,36 @@
109109
ptype_manifest =
110110
None
111111
]
112+
structure_item (hash_ambiguity.ml[19,487+0]..[21,510+4])
113+
Pstr_type Rec
114+
[
115+
type_declaration "x" (hash_ambiguity.ml[19,487+8]..[19,487+9]) (hash_ambiguity.ml[19,487+0]..[21,510+4])
116+
ptype_params =
117+
[
118+
core_type (hash_ambiguity.ml[19,487+5]..[19,487+7])
119+
Ptyp_var a
120+
]
121+
ptype_constraints =
122+
[]
123+
ptype_kind =
124+
Ptype_variant
125+
[
126+
(hash_ambiguity.ml[19,487+12]..[21,510+4])
127+
"A" (hash_ambiguity.ml[19,487+12]..[19,487+13])
128+
[
129+
core_type (hash_ambiguity.ml[19,487+17]..[21,510+4])
130+
Ptyp_class "list" (hash_ambiguity.ml[21,510+0]..[21,510+4])
131+
[
132+
core_type (hash_ambiguity.ml[19,487+17]..[19,487+20])
133+
Ptyp_constr "int" (hash_ambiguity.ml[19,487+17]..[19,487+20])
134+
[]
135+
]
136+
]
137+
None
138+
]
139+
ptype_private = Public
140+
ptype_manifest =
141+
None
142+
]
112143
]
113144

testsuite/tests/parsing/hash_ambiguity.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ type 'a u = A of int #list
1616

1717
type 'a v = A of int * int #list
1818

19+
type 'a x = A of int
20+
#
21+
list
22+
1923
(* TEST
2024
flags = "-stop-after parsing -dparsetree";
2125
setup-ocamlc.byte-build-env;

0 commit comments

Comments
 (0)