aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSérgio Queiroz <sqmedeiros@gmail.com>2017-12-05 16:50:33 -0300
committerSérgio Queiroz <sqmedeiros@gmail.com>2017-12-05 16:50:33 -0300
commit030df9b4a4f4dc3a2cc5775e032f83e92d3c0097 (patch)
treed150ffdf74711a479e8bef584c1099e5c2fa408a
parent54443578aaef5d2198ab772c7f5f53b330f80a7d (diff)
downloadlpeglabel-030df9b4a4f4dc3a2cc5775e032f83e92d3c0097.tar.gz
lpeglabel-030df9b4a4f4dc3a2cc5775e032f83e92d3c0097.tar.bz2
lpeglabel-030df9b4a4f4dc3a2cc5775e032f83e92d3c0097.zip
Adding p^name as syntactic sugar for p / T(name) in relabel
-rw-r--r--relabel.lua12
-rw-r--r--testlabel.lua213
2 files changed, 223 insertions, 2 deletions
diff --git a/relabel.lua b/relabel.lua
index 87269be..642b0fe 100644
--- a/relabel.lua
+++ b/relabel.lua
@@ -241,6 +241,13 @@ local function choicerec (...)
241 return p 241 return p
242end 242end
243 243
244local function getlab (f)
245 if not tlabels[f] then
246 error("undefined label: " .. f)
247 end
248 return mm.T(tlabels[f])
249end
250
244local exp = m.P{ "Exp", 251local exp = m.P{ "Exp",
245 Exp = S * ( m.V"Grammar" 252 Exp = S * ( m.V"Grammar"
246 + (m.V"Seq" * (S * ((m.C(m.P"//" + "/") * m.Ct(m.V"Labels")) + (m.C"/" * m.Cc(false))) 253 + (m.V"Seq" * (S * ((m.C(m.P"//" + "/") * m.Ct(m.V"Labels")) + (m.C"/" * m.Cc(false)))
@@ -260,6 +267,7 @@ local exp = m.P{ "Exp",
260 + m.P"?" * m.Cc(-1, mt.__pow) 267 + m.P"?" * m.Cc(-1, mt.__pow)
261 + "^" * expect( m.Cg(num * m.Cc(mult)) 268 + "^" * expect( m.Cg(num * m.Cc(mult))
262 + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow) 269 + m.Cg(m.C(m.S"+-" * m.R"09"^1) * m.Cc(mt.__pow)
270 + name * m.Cc"lab"
263 ), 271 ),
264 "ExpNum") 272 "ExpNum")
265 + "->" * expect(S * ( m.Cg((String + num) * m.Cc(mt.__div)) 273 + "->" * expect(S * ( m.Cg((String + num) * m.Cc(mt.__div))
@@ -270,7 +278,7 @@ local exp = m.P{ "Exp",
270 + "=>" * expect(S * m.Cg(Def / getdef * m.Cc(m.Cmt)), 278 + "=>" * expect(S * m.Cg(Def / getdef * m.Cc(m.Cmt)),
271 "ExpName1") 279 "ExpName1")
272 ) 280 )
273 )^0, function (a,b,f) return f(a,b) end ); 281 )^0, function (a,b,f) if f == "lab" then return a + getlab(b) else return f(a,b) end end );
274 Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1") 282 Primary = "(" * expect(m.V"Exp", "ExpPatt4") * expect(S * ")", "MisClose1")
275 + String / mm.P 283 + String / mm.P
276 + Class 284 + Class
@@ -293,7 +301,7 @@ local exp = m.P{ "Exp",
293 + m.P"." * m.Cc(any) 301 + m.P"." * m.Cc(any)
294 + (name * -arrow + "<" * expect(name, "ExpName3") 302 + (name * -arrow + "<" * expect(name, "ExpName3")
295 * expect(">", "MisClose6")) * m.Cb("G") / NT; 303 * expect(">", "MisClose6")) * m.Cb("G") / NT;
296 Label = num + name / function (f) return tlabels[f] end; 304 Label = num + name / function (f) return getlab(f) end;
297 Definition = name * arrow * expect(m.V"Exp", "ExpPatt8"); 305 Definition = name * arrow * expect(m.V"Exp", "ExpPatt8");
298 Grammar = m.Cg(m.Cc(true), "G") 306 Grammar = m.Cg(m.Cc(true), "G")
299 * m.Cf(m.V"Definition" / firstdef * (S * m.Cg(m.V"Definition"))^0, 307 * m.Cf(m.V"Definition" / firstdef * (S * m.Cg(m.V"Definition"))^0,
diff --git a/testlabel.lua b/testlabel.lua
index 2d9233a..d3d95b1 100644
--- a/testlabel.lua
+++ b/testlabel.lua
@@ -1267,4 +1267,217 @@ assert(eval("1+") == 4)
1267--> syntax error: expected a term after the operator (at index 3) 1267--> syntax error: expected a term after the operator (at index 3)
1268 1268
1269 1269
1270-- tests related to the use of '^' in relabel to throw labels
1271local errinfo = {
1272 { 'cmdSeq', "Missing ';' in CmdSeq"},
1273 { 'ifExp', "Error in expresion of 'if'"},
1274 { 'ifThen', "Error matching 'then' keyword"},
1275 { 'ifThenCmdSeq', "Error matching CmdSeq of 'then' branch"},
1276 { 'ifElseCmdSeq', "Error matching CmdSeq of 'else' branch"},
1277 { 'ifEnd', "Error matching 'end' keyword of 'if'"},
1278 { 'repeatCmdSeq', "Error matching CmdSeq of 'repeat'"},
1279 { 'repeatUntil', "Error matching 'until' keyword"},
1280 { 'repeatExp', "Error matching expression of 'until'"},
1281 { 'assignOp', "Error matching ':='"},
1282 { 'assignExp', "Error matching expression of assignment"},
1283 { 'readName', "Error matching 'NAME' after 'read'"},
1284 { 'writeExp', "Error matching expression after 'write'"},
1285 { 'simpleExp', "Error matching 'SimpleExp'"},
1286 { 'term', "Error matching 'Term'"},
1287 { 'factor', "Error matching 'Factor'"},
1288 { 'openParExp', "Error matching expression after '('"},
1289 { 'closePar', "Error matching ')'"},
1290 { 'undefined', "Undefined Error" }
1291}
1292
1293
1294local errmsgs = {}
1295local labels = {}
1296
1297for i, err in ipairs(errinfo) do
1298 errmsgs[i] = err[2]
1299 labels[err[1]] = i
1300end
1301
1302re.setlabels(labels)
1303
1304g = re.compile([[
1305 Tiny <- CmdSeq
1306 CmdSeq <- (Cmd SEMICOLON^cmdSeq) (Cmd SEMICOLON^cmdSeq)*
1307 Cmd <- IfCmd / RepeatCmd / ReadCmd / WriteCmd / AssignCmd
1308 IfCmd <- IF Exp^ifExp THEN^ifThen CmdSeq^ifThenCmdSeq (ELSE CmdSeq^ifElseCmdSeq / '') END^ifEnd
1309 RepeatCmd <- REPEAT CmdSeq^repeatCmdSeq UNTIL^repeatUntil Exp^repeatExp
1310 AssignCmd <- NAME ASSIGNMENT^assignOp Exp^assignExp
1311 ReadCmd <- READ NAME^readName
1312 WriteCmd <- WRITE Exp^writeExp
1313 Exp <- SimpleExp ((LESS / EQUAL) SimpleExp^simpleExp / '')
1314 SimpleExp <- Term ((ADD / SUB) Term^term)*
1315 Term <- Factor ((MUL / DIV) Factor^factor)*
1316 Factor <- OPENPAR Exp^openParExp CLOSEPAR^closePar / NUMBER / NAME
1317 ADD <- Sp '+'
1318 ASSIGNMENT <- Sp ':='
1319 CLOSEPAR <- Sp ')'
1320 DIV <- Sp '/'
1321 IF <- Sp 'if'
1322 ELSE <- Sp 'else'
1323 END <- Sp 'end'
1324 EQUAL <- Sp '='
1325 LESS <- Sp '<'
1326 MUL <- Sp '*'
1327 NAME <- !RESERVED Sp [a-z]+
1328 NUMBER <- Sp [0-9]+
1329 OPENPAR <- Sp '('
1330 READ <- Sp 'read'
1331 REPEAT <- Sp 'repeat'
1332 SEMICOLON <- Sp ';'
1333 SUB <- Sp '-'
1334 THEN <- Sp 'then'
1335 UNTIL <- Sp 'until'
1336 WRITE <- Sp 'write'
1337 RESERVED <- (IF / ELSE / END / READ / REPEAT / THEN / UNTIL / WRITE) ![a-z]+
1338 Sp <- (%s / %nl)*
1339]], terror)
1340
1341s = [[
1342n := 5;]]
1343assert(g:match(s) == #s + 1)
1344
1345s = [[
1346n := 5;
1347f := 1;
1348repeat
1349 f := f * n;
1350 n := n - 1;
1351until (n < 1);
1352write f;]]
1353assert(g:match(s) == #s + 1)
1354
1355-- a ';' is missing in 'read a'
1356s = [[
1357read a]]
1358assert(table.pack(g:match(s))[2] == labels['cmdSeq'])
1359
1360
1361-- a ';' is missing in 'n := n - 1'
1362s = [[
1363n := 5;
1364f := 1;
1365repeat
1366 f := f * n;
1367 n := n - 1
1368until (n < 1);
1369write f;]]
1370assert(table.pack(g:match(s))[2] == labels['cmdSeq'])
1371
1372
1373-- IF expression
1374s = [[
1375if a then a := a + 1; end;]]
1376assert(g:match(s) == #s + 1)
1377
1378-- IF expression
1379s = [[
1380if a then a := a + 1; else write 2; end;]]
1381assert(g:match(s) == #s + 1)
1382
1383-- Error in expression of 'if'. 'A' is not a valida name
1384s = [[
1385if A then a := a + 1; else write 2; end;]]
1386assert(table.pack(g:match(s))[2] == labels['ifExp'])
1387
1388-- Error matching the 'then' keyword
1389s = [[
1390if a a := a + 1; else write 2; end;]]
1391assert(table.pack(g:match(s))[2] == labels['ifThen'])
1392
1393-- Error matching the CmdSeq inside of 'then' branch
1394s = [[
1395if a then 3 := 2; else write 2; end;]]
1396assert(table.pack(g:match(s))[2] == labels['ifThenCmdSeq'])
1397
1398-- Error matching the CmdSeq inside of 'else' branch
1399s = [[
1400if a then b := 2; else A := 2; end;]]
1401assert(table.pack(g:match(s))[2] == labels['ifElseCmdSeq'])
1402
1403-- Error matching 'end' of 'if'
1404s = [[
1405if a then b := 2; else a := 2; 77;]]
1406assert(table.pack(g:match(s))[2] == labels['ifEnd'])
1407
1408-- Error matching the CmdSeq of 'repeat'
1409s = [[repeat
1410 F := f * n;
1411 n := n - 1;
1412until (n < 1);]]
1413assert(table.pack(g:match(s))[2] == labels['repeatCmdSeq'])
1414
1415-- Error matching 'until'
1416s = [[repeat
1417 f := f * n;
1418 n := n - 1;
141988 (n < 1);]]
1420assert(table.pack(g:match(s))[2] == labels['repeatUntil'])
1421
1422-- Error matching expression of 'until'
1423s = [[repeat
1424 f := f * n;
1425 n := n - 1;
1426until ; (n < 1);]]
1427assert(table.pack(g:match(s))[2] == labels['repeatExp'])
1428
1429-- Error matching ':='
1430s = [[
1431f = f * n;]]
1432assert(table.pack(g:match(s))[2] == labels['assignOp'])
1433
1434-- Error matching expression of assignment
1435s = [[
1436f := A * n;]]
1437assert(table.pack(g:match(s))[2] == labels['assignExp'])
1438
1439-- Error matching 'name'
1440s = [[
1441read 2;]]
1442assert(table.pack(g:match(s))[2] == labels['readName'])
1443
1444-- Error matching expression after 'write'
1445s = [[
1446write [a] := 2;]]
1447assert(table.pack(g:match(s))[2] == labels['writeExp'])
1448
1449-- Error matching 'SimpleExp'
1450s = [[
1451a := a < A;]]
1452assert(table.pack(g:match(s))[2] == labels['simpleExp'])
1453
1454-- Error matching 'Term'
1455s = [[
1456a := a + A;]]
1457assert(table.pack(g:match(s))[2] == labels['term'])
1458
1459-- Error matching 'Factor'
1460s = [[
1461a := a * A;]]
1462assert(table.pack(g:match(s))[2] == labels['factor'])
1463
1464-- Error matching expression after '('
1465s = [[
1466a := (A);]]
1467assert(table.pack(g:match(s))[2] == labels['openParExp'])
1468
1469-- Error matching ')'
1470s = [[
1471a := (a];]]
1472assert(table.pack(g:match(s))[2] == labels['closePar'])
1473
1474-- Error undefined
1475s = [[
1476A := a;]]
1477assert(table.pack(g:match(s))[2] == 0)
1478
1479
1480
1481
1482
1270print("OK") 1483print("OK")