-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrun_test_lexer.mll
209 lines (185 loc) · 5.17 KB
/
run_test_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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
(***************************************************************************)
(* Lucy-n *)
(* *)
(* *)
(* Authors: Louis Mandel ([email protected]) *)
(* Florence Plateau ([email protected]) *)
(* *)
(* Creation date: September 2011 *)
(* *)
(***************************************************************************)
(* Syntaxe :
run_test:
[ Good: "compiler1"
Bad n: "compiler2"
Bad n "regexp": "compiler3"
Warning: "compiler4"
Warning "regexp": "compiler5" ]
*)
{
let debug msg =
Format.eprintf "%s@." msg
open Run_test_misc
exception Error of string
type ident =
| Ident of string
| Id_run_test
| Id_good
| Id_bad
| Id_warning
let run_test_lbl = ref "run_test"
let tbl = Hashtbl.create 7
let () =
List.iter (fun (s,id) -> Hashtbl.add tbl s id)
[ !run_test_lbl, Id_run_test;
"good", Id_good;
"bad", Id_bad;
"warning", Id_warning ]
let ident_of_string =
(fun s ->
try Hashtbl.find tbl (String.lowercase s)
with Not_found -> Ident s)
}
let space = [' ''\t''\n']
let not_space = [^' ''\t']
let ident = ['a'-'z''A'-'Z''_']['a'-'z''A'-'Z''_''0'-'9''-''\'''$''#''@''!']*
let int = ['0'-'9']+
rule main acc = parse
(ident as id) space* ':' space* '['
{ match ident_of_string id with
| Id_run_test ->
main (get_tests acc lexbuf) lexbuf
| _ -> main acc lexbuf }
| eof
{ List.rev acc }
| _
{ main acc lexbuf }
and get_tests acc = parse
space
{ get_tests acc lexbuf }
| ']'
{ acc }
| (ident as id)
{ let req =
match ident_of_string id with
| Id_good -> good lexbuf
| Id_bad -> bad lexbuf
| Id_warning -> warning lexbuf
| _ ->
raise (Error ("unexpected \'"^id^"\': test description expected"))
in
let compiler = get_compiler lexbuf in
get_tests ((req, compiler) :: acc) lexbuf
}
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf "unexpected \'%c\': unterminated list of tests" c
in
raise (Error msg) }
and good = parse
space
{ good lexbuf }
| ':'
{ Good }
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf "unexpected \'%c\': \':\' expected after \'good\'" c
in
raise (Error msg) }
and bad = parse
space*
{ bad lexbuf }
| ':'
{ Bad (None, "") }
| (int as code) space* ':'
{ Bad (Some (int_of_string code), "") }
| (int as code) space* "\""
{ let msg =
let buf = Buffer.create 512 in
string buf lexbuf;
Buffer.contents buf
in
column lexbuf;
Bad (Some (int_of_string code), msg) }
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf "unexpected \'%c\': \':\' or \'code:\' or \'code \"regexp\":\' expected after \'bad\'" c
in
raise (Error msg) }
and warning = parse
space
{ warning lexbuf }
| ':'
{ Warning "" }
| "\""
{ let msg =
let buf = Buffer.create 512 in
string buf lexbuf;
Buffer.contents buf
in
column lexbuf;
Warning msg }
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf
"unexpected \'%c\': \':\' or \'code:\' or \'code \"regexp\":\' expected after \'warning\'"
c
in
raise (Error msg) }
and get_compiler = parse
space* "\""
{ let compiler =
let buf = Buffer.create 512 in
string buf lexbuf;
Buffer.contents buf
in
compiler }
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf "unexpected \'%c\': \'\"compiler\"\' expected" c
in
raise (Error msg) }
and string buf = parse
| "\"" { () }
| '\\' 'n'
{ Buffer.add_string buf "\\n";
string buf lexbuf }
| '\\' '\\'
{ Buffer.add_string buf "\\\\";
string buf lexbuf }
| '\\' '"'
{ Buffer.add_string buf "\\\"";
string buf lexbuf }
| [^ '\\' '"' '\n']+
{ Buffer.add_string buf (Lexing.lexeme lexbuf);
string buf lexbuf }
| '\\'
{ raise (Error "illegal escape character in string") }
| '\n' | eof
{ raise (Error "unterminated string") }
| _
{ raise (Error ("illegal character: " ^ Lexing.lexeme lexbuf)) }
and column = parse
space
{ column lexbuf }
| ':'
{ () }
| eof
{ raise (Error "unexpected end of file")}
| (_ as c)
{ let msg =
Format.sprintf "unexpected \'%c\': \':\' expected" c
in
raise (Error msg) }
{
}