-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.mll
71 lines (64 loc) · 1.99 KB
/
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
{
open Types
open Parser
exception LexingError of error
let get_pos = Range.from_lexbuf
let fail (e : error) =
raise (LexingError(e))
}
let space = [' ' '\t']
let break = ('\r' '\n' | '\r' | '\n')
let capital = ['A'-'Z']
let small = ['a'-'z']
let digit = ['0'-'9']
let lower = (small (small | capital | digit | "_")*)
let upper = (capital (small | capital | digit | "_")*)
rule token = parse
| space { token lexbuf }
| break { Lexing.new_line lexbuf; token lexbuf }
| ":=" { DEFEQ(get_pos lexbuf) }
| "=" { EQ(get_pos lexbuf) }
| "|" { BAR(get_pos lexbuf) }
| "{" { BRECORD(get_pos lexbuf) }
| "}" { ERECORD(get_pos lexbuf) }
| "[" { LBRACKET(get_pos lexbuf) }
| "]" { RBRACKET(get_pos lexbuf) }
| "(" { LPAREN(get_pos lexbuf) }
| ")" { RPAREN(get_pos lexbuf) }
| ":" { COLON(get_pos lexbuf) }
| "," { COMMA(get_pos lexbuf) }
| ("@" (lower as s)) {
match s with
| "output" -> META_OUTPUT(get_pos lexbuf)
| "language_version" -> META_LANGUAGE_VERSION(get_pos lexbuf)
| "external" -> META_EXTERNAL(get_pos lexbuf)
| _ -> fail (UnknownMeta(s))
}
| ("$" (lower as x)) { VARIABLE(get_pos lexbuf, x) }
| "\"" { string (get_pos lexbuf) (Buffer.create 256) lexbuf }
| "/*" { comment (get_pos lexbuf) lexbuf; token lexbuf }
| lower { LOWER(get_pos lexbuf, Lexing.lexeme lexbuf) }
| upper { UPPER(get_pos lexbuf, Lexing.lexeme lexbuf) }
| eof { EOI }
| _ as c { fail (LexingInvalidCharacter{ character = c; range = get_pos lexbuf }) }
and string start buf = parse
| "\\\"" {
Buffer.add_char buf '"';
string start buf lexbuf
}
| ([^ '\\' '"' '\r' '\n']+ as s) {
Buffer.add_string buf s;
string start buf lexbuf
}
| '"' {
let last = get_pos lexbuf in
let s = Buffer.contents buf in
STRING(Range.unite start last, s)
}
| (eof | '\r' | '\n') {
fail (EndOfLineInsideStringLiteral{ start = start; })
}
and comment start = parse
| "*/" { () }
| eof { fail (EndOfLineInsideComment{ start = start; }) }
| _ { comment start lexbuf }