diff options
author | Sergio Medeiros <sqmedeiros@gmail.com> | 2014-10-29 18:13:38 -0300 |
---|---|---|
committer | Sergio Medeiros <sqmedeiros@gmail.com> | 2014-10-29 18:13:38 -0300 |
commit | 8d30a0ff8a8584e225c03d878a9add439ea193a3 (patch) | |
tree | cdc03907837ebec1aed26be7290a5a40d00f3e2c /testlabel.lua | |
parent | 3af55803f0a261dd9b2ccf85a7532288c4a270ae (diff) | |
download | lpeglabel-8d30a0ff8a8584e225c03d878a9add439ea193a3.tar.gz lpeglabel-8d30a0ff8a8584e225c03d878a9add439ea193a3.tar.bz2 lpeglabel-8d30a0ff8a8584e225c03d878a9add439ea193a3.zip |
Creating the git repository with the current implementation.
Diffstat (limited to 'testlabel.lua')
-rw-r--r-- | testlabel.lua | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/testlabel.lua b/testlabel.lua new file mode 100644 index 0000000..100c0d0 --- /dev/null +++ b/testlabel.lua | |||
@@ -0,0 +1,422 @@ | |||
1 | local m = require 'lpeglabel' | ||
2 | |||
3 | local p = m.T(1, 2, 5) | ||
4 | assert(p:match("abc") == nil) | ||
5 | |||
6 | -- throws a label that is not caught by ordinary choice | ||
7 | p = m.T(1) + m.P"a" | ||
8 | local r = p:match("abc") | ||
9 | assert(r == nil) | ||
10 | |||
11 | -- again throws a label that is not caught by ordinary choice | ||
12 | local g = m.P{ | ||
13 | "S", | ||
14 | S = m.V"A" + m.V"B", | ||
15 | A = m.T(1), | ||
16 | B = m.P"a" | ||
17 | } | ||
18 | r = g:match("abc") | ||
19 | assert(r == nil) | ||
20 | |||
21 | -- throws a label that is not caught by labeled choice | ||
22 | p = m.Lc(m.T(2), m.P"a", 1, 3) | ||
23 | r = p:match("abc") | ||
24 | assert(r == nil) | ||
25 | |||
26 | -- modifies previous pattern | ||
27 | -- adds another labeled choice to catch label "2" | ||
28 | p = m.Lc(p, m.P"a", 2) | ||
29 | r = p:match("abc") | ||
30 | assert(r == 2) | ||
31 | |||
32 | -- throws a label that is caught by labeled choice | ||
33 | p = m.Lc(m.T(25), m.P"a", 25) | ||
34 | r = p:match("abc") | ||
35 | assert(r == 2) | ||
36 | assert(p:match("bola") == nil) | ||
37 | |||
38 | -- labeled choice did not catch "fail" by default | ||
39 | p = m.Lc(m.P"b", m.P"a", 1) | ||
40 | r = p:match("abc") | ||
41 | assert(r == nil, r) | ||
42 | assert(p:match("bola") == 2) | ||
43 | |||
44 | -- "fail" is label "0" | ||
45 | -- labeled choice can catch "fail" | ||
46 | p = m.Lc(m.P"b", m.P"a", 0) | ||
47 | r = p:match("abc") | ||
48 | assert(r == 2, r) | ||
49 | assert(p:match("bola") == 2) | ||
50 | |||
51 | -- "fail" is label "0" | ||
52 | -- labeled choice can catch "fail" or "3" | ||
53 | p = m.Lc(m.P"a" * m.T(3), (m.P"a" + m.P"b"), 0, 3) | ||
54 | assert(p:match("abc") == 2) | ||
55 | assert(p:match("bac") == 2) | ||
56 | assert(p:match("cab") == nil) | ||
57 | |||
58 | --[[ | ||
59 | S -> A /{1} 'a' | ||
60 | A -> B | ||
61 | B -> %1 | ||
62 | ]] | ||
63 | g = m.P{ | ||
64 | "S", | ||
65 | S = m.Lc(m.V"A", m.P"a", 1), | ||
66 | A = m.V"B", | ||
67 | B = m.T(1), | ||
68 | } | ||
69 | assert(g:match("ab") == 2) | ||
70 | assert(g:match("bc") == nil) | ||
71 | |||
72 | |||
73 | --[[ | ||
74 | S -> A | ||
75 | A -> (B (';' / %{1}))* | ||
76 | B -> 'a' | ||
77 | ]] | ||
78 | g = m.P{ | ||
79 | "S", | ||
80 | S = m.V"A", | ||
81 | A = m.P(m.V"B" * (";" + m.T(1)))^0, | ||
82 | B = m.P'a', | ||
83 | } | ||
84 | assert(g:match("a;a;") == 5) | ||
85 | assert(g:match("a;a") == nil) | ||
86 | |||
87 | |||
88 | |||
89 | -- %1 /{1,3} %2 /{2} 'a' | ||
90 | p = m.Lc(m.Lc(m.T(1), m.T(2), 1, 3), m.P"a", 2) | ||
91 | r = p:match("abc") | ||
92 | assert(r == 2) | ||
93 | assert(p:match("") == nil) | ||
94 | |||
95 | p = m.Lc(m.T(1), m.Lc(m.T(2), m.P"a", 2), 1, 3) | ||
96 | r = p:match("abc") | ||
97 | assert(r == 2) | ||
98 | assert(p:match("") == nil) | ||
99 | |||
100 | print("+") | ||
101 | |||
102 | --[[ grammar based on Figure 8 of paper submitted to SCP | ||
103 | S -> S0 /{1} ID /{2} ID '=' Exp /{3} 'unsigned'* 'int' ID /{4} 'unsigned'* ID ID / %error | ||
104 | S0 -> ID S1 / 'unsigned' S2 / 'int' %3 | ||
105 | S1 -> '=' %2 / !. %1 / ID %4 | ||
106 | S2 -> 'unsigned' S2 / ID %4 / 'int' %3 | ||
107 | ]] | ||
108 | |||
109 | local sp = m.S" \t\n"^0 | ||
110 | local eq = sp * m.P"=" | ||
111 | |||
112 | g = m.P{ | ||
113 | "S", | ||
114 | S = m.Lc( | ||
115 | m.Lc( | ||
116 | m.Lc( | ||
117 | m.Lc(m.V"S0", m.V"ID" * (m.P(1) + ""), 1), | ||
118 | m.V"ID" * eq * m.V"Exp", 2 | ||
119 | ), | ||
120 | m.V"U"^0 * m.V"I" * m.V"ID", 3 | ||
121 | ), | ||
122 | m.V"U"^0 * m.V"ID" * m.V"ID", 4) | ||
123 | + m.T(5), | ||
124 | S0 = m.V"ID" * m.V"S1" + m.V"U" * m.V"S2" + m.V"I" * m.T(3), | ||
125 | S1 = eq * m.T(2) + sp * -m.P(1) * m.T(1) + m.V"ID" * m.T(4), | ||
126 | S2 = m.V"U" * m.V"S2" + m.V"ID" * m.T(4) + m.V"I" * m.T(3), | ||
127 | ID = sp * m.P"a", | ||
128 | U = sp * m.P"unsigned", | ||
129 | I = sp * m.P"int", | ||
130 | Exp = sp * m.P"E", | ||
131 | } | ||
132 | --g:pcode() | ||
133 | |||
134 | local s = "a" | ||
135 | assert(g:match(s) == #s + 1) --1 | ||
136 | s = "a = E" | ||
137 | assert(g:match(s) == #s + 1) --2 | ||
138 | s = "int a" | ||
139 | assert(g:match(s) == #s + 1) --3 | ||
140 | s = "unsigned int a" | ||
141 | assert(g:match(s) == #s + 1) --3 | ||
142 | s = "unsigned a a" | ||
143 | assert(g:match(s) == #s + 1) --4 | ||
144 | s = "b" | ||
145 | assert(g:match(s) == nil) | ||
146 | s = "unsigned" | ||
147 | assert(g:match(s) == nil) | ||
148 | s = "unsigned a" | ||
149 | assert(g:match(s) == nil) | ||
150 | s = "unsigned int" | ||
151 | assert(g:match(s) == nil) | ||
152 | |||
153 | |||
154 | print("+") | ||
155 | |||
156 | local re = require 're' | ||
157 | |||
158 | g = re.compile[['a' /{4,9} [a-z] | ||
159 | ]] | ||
160 | assert(g:match("a") == 2) | ||
161 | assert(g:match("b") == nil) | ||
162 | |||
163 | g = re.compile[['a' /{4,9} [a-f] /{5, 7} [a-z] | ||
164 | ]] | ||
165 | assert(g:match("a") == 2) | ||
166 | assert(g:match("b") == nil) | ||
167 | |||
168 | g = re.compile[[%{1} /{4,9} [a-z] | ||
169 | ]] | ||
170 | assert(g:match("a") == nil) | ||
171 | |||
172 | g = re.compile[[%{1} /{4,1} [a-f] | ||
173 | ]] | ||
174 | assert(g:match("a") == 2) | ||
175 | assert(g:match("h") == nil) | ||
176 | |||
177 | g = re.compile[[[a-f]%{15, 9} /{4,9} [a-c]%{7} /{5, 7} [a-z] ]] | ||
178 | assert(g:match("a") == 2) | ||
179 | assert(g:match("c") == 2) | ||
180 | assert(g:match("d") == nil) | ||
181 | assert(g:match("g") == nil) | ||
182 | |||
183 | --[[ grammar based on Figure 8 of paper submitted to SCP | ||
184 | S -> S0 /{1} ID /{2} ID '=' Exp /{3} 'unsigned'* 'int' ID /{4} 'unsigned'* ID ID / %error | ||
185 | S0 -> ID S1 / 'unsigned' S2 / 'int' %3 | ||
186 | S1 -> '=' %2 / !. %1 / ID %4 | ||
187 | S2 -> 'unsigned' S2 / ID %4 / 'int' %3 | ||
188 | ]] | ||
189 | |||
190 | |||
191 | g = re.compile([[ | ||
192 | S <- S0 /{1} ID /{2} ID %s* '=' Exp /{3} U* Int ID /{4} U ID ID /{0} %{5} | ||
193 | S0 <- ID S1 / U S2 / Int %{3} | ||
194 | S1 <- %s* '=' %{2} / !. %{1} / ID %{4} | ||
195 | S2 <- U S2 / ID %{4} / Int %{3} | ||
196 | ID <- %s* 'a' | ||
197 | U <- %s* 'unsigned' | ||
198 | Int <- %s* 'int' | ||
199 | Exp <- %s* 'E' | ||
200 | ]]) | ||
201 | |||
202 | local s = "a" | ||
203 | assert(g:match(s) == #s + 1) --1 | ||
204 | s = "a = E" | ||
205 | assert(g:match(s) == #s + 1) --2 | ||
206 | s = "int a" | ||
207 | assert(g:match(s) == #s + 1) --3 | ||
208 | s = "unsigned int a" | ||
209 | assert(g:match(s) == #s + 1) --3 | ||
210 | s = "unsigned a a" | ||
211 | assert(g:match(s) == #s + 1) --4 | ||
212 | s = "b" | ||
213 | assert(g:match(s) == nil) | ||
214 | s = "unsigned" | ||
215 | assert(g:match(s) == nil) | ||
216 | s = "unsigned a" | ||
217 | assert(g:match(s) == nil) | ||
218 | s = "unsigned int" | ||
219 | assert(g:match(s) == nil) | ||
220 | |||
221 | local terror = { ['cmdSeq'] = "Missing ';' in CmdSeq", | ||
222 | ['ifExp'] = "Error in expresion of 'if'", | ||
223 | ['ifThen'] = "Error matching 'then' keyword", | ||
224 | ['ifThenCmdSeq'] = "Error matching CmdSeq of 'then' branch", | ||
225 | ['ifElseCmdSeq'] = "Error matching CmdSeq of 'else' branch", | ||
226 | ['ifEnd'] = "Error matching 'end' keyword of 'if'", | ||
227 | ['repeatCmdSeq'] = "Error matching CmdSeq of 'repeat'", | ||
228 | ['repeatUntil'] = "Error matching 'until' keyword", | ||
229 | ['repeatExp'] = "Error matching expression of 'until'", | ||
230 | ['assignOp'] = "Error matching ':='", | ||
231 | ['assignExp'] = "Error matching expression of assignment", | ||
232 | ['readName'] = "Error matching 'NAME' after 'read'", | ||
233 | ['writeExp'] = "Error matching expression after 'write'", | ||
234 | ['simpleExp'] = "Error matching 'SimpleExp'", | ||
235 | ['term'] = "Error matching 'Term'", | ||
236 | ['factor'] = "Error matching 'Factor'", | ||
237 | ['openParExp'] = "Error matching expression after '('", | ||
238 | ['closePar'] = "Error matching ')'", | ||
239 | ['undefined'] = "Error undefined'"} | ||
240 | |||
241 | g = re.compile([[ | ||
242 | Tiny <- CmdSeq /{1} '' -> cmdSeq /{2} '' -> ifExp /{3} '' -> ifThen /{4} '' -> ifThenCmdSeq | ||
243 | /{5} '' -> ifElseCmdSeq /{6} '' -> ifEnd /{7} '' -> repeatCmdSeq | ||
244 | /{8} '' -> repeatUntil /{9} '' -> repeatExp /{10} '' -> assignOp | ||
245 | /{11} '' -> assignExp /{12} '' -> readName /{13} '' -> writeExp | ||
246 | /{14} '' -> simpleExp /{15} '' -> term /{16} '' -> factor | ||
247 | /{17} '' -> openParExp /{18} '' -> closePar /{0} '' -> undefined | ||
248 | CmdSeq <- (Cmd (SEMICOLON / %{1})) (Cmd (SEMICOLON / %{1}))* | ||
249 | Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd | ||
250 | IfCmd <- IF (Exp / %{2}) (THEN / %{3}) (CmdSeq / %{4}) (ELSE (CmdSeq / %{5}) / '') (END / %{6}) | ||
251 | RepeatCmd <- REPEAT (CmdSeq / %{7}) (UNTIL / %{8}) (Exp / %{9}) | ||
252 | AssignCmd <- !RESERVED NAME (ASSIGNMENT / %{10}) (Exp / %{11}) | ||
253 | ReadCmd <- READ (NAME / %{12}) | ||
254 | WriteCmd <- WRITE (Exp / %{13}) | ||
255 | Exp <- SimpleExp ((LESS / EQUAL) (SimpleExp / %{14}) / '') | ||
256 | SimpleExp <- Term ((ADD / SUB) (Term / %{15}))* | ||
257 | Term <- Factor ((MUL / DIV) (Factor / %{16}))* | ||
258 | Factor <- OPENPAR (Exp / %{17}) (CLOSEPAR / %{18}) / NUMBER / NAME | ||
259 | ADD <- Sp '+' | ||
260 | ASSIGNMENT <- Sp ':=' | ||
261 | CLOSEPAR <- Sp ')' | ||
262 | DIV <- Sp '/' | ||
263 | IF <- Sp 'if' | ||
264 | ELSE <- Sp 'else' | ||
265 | END <- Sp 'end' | ||
266 | EQUAL <- Sp '=' | ||
267 | LESS <- Sp '<' | ||
268 | MUL <- Sp '*' | ||
269 | NAME <- Sp [a-z]+ | ||
270 | NUMBER <- Sp [0-9]+ | ||
271 | OPENPAR <- Sp '(' | ||
272 | READ <- Sp 'read' | ||
273 | REPEAT <- Sp 'repeat' | ||
274 | SEMICOLON <- Sp ';' | ||
275 | SUB <- Sp '-' | ||
276 | THEN <- Sp 'then' | ||
277 | UNTIL <- Sp 'until' | ||
278 | WRITE <- Sp 'write' | ||
279 | RESERVED <- IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE | ||
280 | Sp <- (%s / %nl)* | ||
281 | ]], terror) | ||
282 | |||
283 | s = [[ | ||
284 | n := 5;]] | ||
285 | assert(g:match(s) == #s + 1) | ||
286 | |||
287 | s = [[ | ||
288 | n := 5; | ||
289 | f := 1; | ||
290 | repeat | ||
291 | f := f * n; | ||
292 | n := n - 1; | ||
293 | until (n < 1); | ||
294 | write f;]] | ||
295 | assert(g:match(s) == #s + 1) | ||
296 | |||
297 | -- a ';' is missing in 'read a' | ||
298 | s = [[ | ||
299 | read a]] | ||
300 | assert(g:match(s) == terror['cmdSeq']) | ||
301 | |||
302 | |||
303 | -- a ';' is missing in 'n := n - 1' | ||
304 | s = [[ | ||
305 | n := 5; | ||
306 | f := 1; | ||
307 | repeat | ||
308 | f := f * n; | ||
309 | n := n - 1 | ||
310 | until (n < 1); | ||
311 | write f;]] | ||
312 | assert(g:match(s) == terror['cmdSeq']) | ||
313 | |||
314 | |||
315 | -- IF expression | ||
316 | s = [[ | ||
317 | if a then a := a + 1; end;]] | ||
318 | assert(g:match(s) == #s + 1) | ||
319 | |||
320 | -- IF expression | ||
321 | s = [[ | ||
322 | if a then a := a + 1; else write 2; end;]] | ||
323 | assert(g:match(s) == #s + 1) | ||
324 | |||
325 | -- Error in expression of 'if'. 'A' is not a valida name | ||
326 | s = [[ | ||
327 | if A then a := a + 1; else write 2; end;]] | ||
328 | assert(g:match(s) == terror['ifExp']) | ||
329 | |||
330 | -- Error matching the 'then' keyword | ||
331 | s = [[ | ||
332 | if a a := a + 1; else write 2; end;]] | ||
333 | assert(g:match(s) == terror['ifThen']) | ||
334 | |||
335 | -- Error matching the CmdSeq inside of 'then' branch | ||
336 | s = [[ | ||
337 | if a then 3 := 2; else write 2; end;]] | ||
338 | assert(g:match(s) == terror['ifThenCmdSeq']) | ||
339 | |||
340 | -- Error matching the CmdSeq inside of 'else' branch | ||
341 | s = [[ | ||
342 | if a then b := 2; else A := 2; end;]] | ||
343 | assert(g:match(s) == terror['ifElseCmdSeq']) | ||
344 | |||
345 | -- Error matching 'end' of 'if' | ||
346 | s = [[ | ||
347 | if a then b := 2; else a := 2; 77;]] | ||
348 | assert(g:match(s) == terror['ifEnd']) | ||
349 | |||
350 | -- Error matching the CmdSeq of 'repeat' | ||
351 | s = [[repeat | ||
352 | F := f * n; | ||
353 | n := n - 1; | ||
354 | until (n < 1);]] | ||
355 | assert(g:match(s) == terror['repeatCmdSeq']) | ||
356 | |||
357 | -- Error matching 'until' | ||
358 | s = [[repeat | ||
359 | f := f * n; | ||
360 | n := n - 1; | ||
361 | 88 (n < 1);]] | ||
362 | assert(g:match(s) == terror['repeatUntil']) | ||
363 | |||
364 | -- Error matching expression of 'until' | ||
365 | s = [[repeat | ||
366 | f := f * n; | ||
367 | n := n - 1; | ||
368 | until ; (n < 1);]] | ||
369 | assert(g:match(s) == terror['repeatExp']) | ||
370 | |||
371 | -- Error matching ':=' | ||
372 | s = [[ | ||
373 | f = f * n;]] | ||
374 | assert(g:match(s) == terror['assignOp']) | ||
375 | |||
376 | -- Error matching expression of assignment | ||
377 | s = [[ | ||
378 | f := A * n;]] | ||
379 | assert(g:match(s) == terror['assignExp']) | ||
380 | |||
381 | -- Error matching 'name' | ||
382 | s = [[ | ||
383 | read 2;]] | ||
384 | assert(g:match(s) == terror['readName']) | ||
385 | |||
386 | -- Error matching expression after 'write' | ||
387 | s = [[ | ||
388 | write [a] := 2;]] | ||
389 | assert(g:match(s) == terror['writeExp']) | ||
390 | |||
391 | -- Error matching 'SimpleExp' | ||
392 | s = [[ | ||
393 | a := a < A;]] | ||
394 | assert(g:match(s) == terror['simpleExp']) | ||
395 | |||
396 | -- Error matching 'Term' | ||
397 | s = [[ | ||
398 | a := a + A;]] | ||
399 | assert(g:match(s) == terror['term']) | ||
400 | |||
401 | -- Error matching 'Factor' | ||
402 | s = [[ | ||
403 | a := a * A;]] | ||
404 | assert(g:match(s) == terror['factor']) | ||
405 | |||
406 | -- Error matching expression after '(' | ||
407 | s = [[ | ||
408 | a := (A);]] | ||
409 | assert(g:match(s) == terror['openParExp']) | ||
410 | |||
411 | -- Error matching ')' | ||
412 | s = [[ | ||
413 | a := (a];]] | ||
414 | assert(g:match(s) == terror['closePar']) | ||
415 | |||
416 | -- Error undefined | ||
417 | s = [[ | ||
418 | A := a;]] | ||
419 | assert(g:match(s) == terror['undefined']) | ||
420 | |||
421 | |||
422 | print("OK") | ||