forked from ocaml/dune
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdune_lexer.mll
77 lines (67 loc) · 1.54 KB
/
dune_lexer.mll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{
open! Stdune
type first_line =
{ lang : Loc.t * string
; version : Loc.t * string
}
let make_loc lexbuf : Loc.t =
{ start = Lexing.lexeme_start_p lexbuf
; stop = Lexing.lexeme_end_p lexbuf
}
let invalid_lang_line start lexbuf =
lexbuf.Lexing.lex_start_p <- start;
Errors.fail_lex lexbuf
"Invalid first line, expected: (lang <lang> <version>)"
}
let newline = '\r'? '\n'
let blank = [' ' '\t']
let atom_char = [^';' '(' ')' '"' '#' '|' '\000'-'\032']
rule is_script = parse
| "(* -*- tuareg -*- *)" { true }
| "" { false }
and maybe_first_line = parse
| '(' blank* "lang"
{ let start = Lexing.lexeme_start_p lexbuf in
let lang = atom start lexbuf in
let version = atom start lexbuf in
first_line_rparen_end start lexbuf;
Some { lang; version }
}
| ""
{ None
}
and atom start = parse
| blank+
{ atom start lexbuf
}
| atom_char+ as s
{ (make_loc lexbuf, s)
}
| _ | eof
{ to_eol lexbuf;
invalid_lang_line start lexbuf
}
and first_line_rparen_end start = parse
| blank* ')' blank* (newline | eof as s)
{ if s <> "" then Lexing.new_line lexbuf
}
| ""
{ to_eol lexbuf;
invalid_lang_line start lexbuf
}
and to_eol = parse
| [^'\r' '\n']*
{ ()
}
and eof_reached = parse
| eof { true }
| "" { false }
{
let first_line lb =
match maybe_first_line lb with
| Some x -> x
| None ->
let start = Lexing.lexeme_start_p lb in
to_eol lb;
invalid_lang_line start lb
}