Skip to content

Commit f90c67e

Browse files
committed
Updating the parser to support the syntax of Lua 5.3
1 parent 5859060 commit f90c67e

3 files changed

Lines changed: 116 additions & 23 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
lua-parser
22
==========
33

4-
This is a Lua 5.2 parser written with LPeg that generates an AST in
4+
This is a Lua 5.3 parser written with LPeg that generates an AST in
55
the format specified by [Metalua](https://github.com/fab13n/metalua-parser).
66
The parser also implements an error reporting technique that is
77
based on tracking the farthest failure position.
@@ -77,5 +77,5 @@ Usage
7777
$ lua parse.lua "for i=1, 10 do print(i) "
7878
exemplo1.lua:1:24: syntax error, unexpected 'EOF', expecting 'end',
7979
'return', 'Name', 'goto', 'break', '::', 'local', 'function', 'repeat',
80-
'for', 'do', 'while', 'if', ';', '=', ',', 'String', '{', '(', ':', '[', '.'
80+
'for', 'do', 'while', 'if', ';', '=', ',', 'String', '{', '(', ':', '[', '.'
8181

lua-parser/parser.lua

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,9 @@ apply:
4242
4343
lhs: `Id{ <string> } | `Index{ expr expr }
4444
45-
opid: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow' | 'concat'
46-
| 'eq' | 'lt' | 'le' | 'and' | 'or' | 'not' | 'unm' | 'len'
45+
opid: 'add' | 'sub' | 'mul' | 'div' | 'idiv' | 'mod' | 'pow' | 'concat'
46+
| 'band' | 'bor' | 'bxor' | 'shl' | 'shr' | 'eq' | 'lt' | 'le'
47+
| 'and' | 'or' | 'not' | 'unm' | 'len' | 'bnot'
4748
]]
4849
local parser = {}
4950

@@ -152,9 +153,15 @@ local function binaryop (e1, op, e2)
152153
op == "sub" or
153154
op == "mul" or
154155
op == "div" or
156+
op == "idiv" or
155157
op == "mod" or
156158
op == "pow" or
157159
op == "concat" or
160+
op == "band" or
161+
op == "bor" or
162+
op == "bxor" or
163+
op == "shl" or
164+
op == "shr" or
158165
op == "eq" or
159166
op == "lt" or
160167
op == "le" or
@@ -227,13 +234,17 @@ local G = { V"Lua",
227234
SubExpr_1 = chainl1(V"SubExpr_2", V"OrOp");
228235
SubExpr_2 = chainl1(V"SubExpr_3", V"AndOp");
229236
SubExpr_3 = chainl1(V"SubExpr_4", V"RelOp");
230-
SubExpr_4 = V"SubExpr_5" * V"ConOp" * V"SubExpr_4" / binaryop +
231-
V"SubExpr_5";
232-
SubExpr_5 = chainl1(V"SubExpr_6", V"AddOp");
233-
SubExpr_6 = chainl1(V"SubExpr_7", V"MulOp");
234-
SubExpr_7 = V"UnOp" * V"SubExpr_7" / unaryop +
235-
V"SubExpr_8";
236-
SubExpr_8 = V"SimpleExp" * (V"PowOp" * V"SubExpr_7")^-1 / binaryop;
237+
SubExpr_4 = chainl1(V"SubExpr_5", V"BOrOp");
238+
SubExpr_5 = chainl1(V"SubExpr_6", V"BXorOp");
239+
SubExpr_6 = chainl1(V"SubExpr_7", V"BAndOp");
240+
SubExpr_7 = chainl1(V"SubExpr_8", V"ShiftOp");
241+
SubExpr_8 = V"SubExpr_9" * V"ConOp" * V"SubExpr_8" / binaryop +
242+
V"SubExpr_9";
243+
SubExpr_9 = chainl1(V"SubExpr_10", V"AddOp");
244+
SubExpr_10 = chainl1(V"SubExpr_11", V"MulOp");
245+
SubExpr_11 = V"UnOp" * V"SubExpr_11" / unaryop +
246+
V"SubExpr_12";
247+
SubExpr_12 = V"SimpleExp" * (V"PowOp" * V"SubExpr_11")^-1 / binaryop;
237248
SimpleExp = taggedCap("Number", token(V"Number", "Number")) +
238249
taggedCap("String", token(V"String", "String")) +
239250
taggedCap("Nil", kw("nil")) +
@@ -405,15 +416,22 @@ local G = { V"Lua",
405416
symb(">=") / "ge" +
406417
symb("<") / "lt" +
407418
symb(">") / "gt";
419+
BOrOp = symb("|") / "bor";
420+
BXorOp = symb("~") / "bxor";
421+
BAndOp = symb("&") / "band";
422+
ShiftOp = symb("<<") / "shl" +
423+
symb(">>") / "shr";
408424
ConOp = symb("..") / "concat";
409425
AddOp = symb("+") / "add" +
410426
symb("-") / "sub";
411427
MulOp = symb("*") / "mul" +
428+
symb("//") / "idiv" +
412429
symb("/") / "div" +
413430
symb("%") / "mod";
414431
UnOp = kw("not") / "not" +
415432
symb("-") / "unm" +
416-
symb("#") / "len";
433+
symb("#") / "len" +
434+
symb("~") / "bnot";
417435
PowOp = symb("^") / "pow";
418436
Shebang = P"#" * (P(1) - P"\n")^0 * P"\n";
419437
-- for error reporting

test.lua

Lines changed: 86 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ long string
377377
]==]
378378
]=]
379379
e = [=[
380-
test.lua:5:7: syntax error, unexpected '[', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
380+
test.lua:5:7: syntax error, unexpected '[', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
381381
]=]
382382

383383
r = parse(s)
@@ -393,7 +393,7 @@ ss6 = "testing unfinished string
393393
-- short string test end
394394
]=]
395395
e = [=[
396-
test.lua:3:7: syntax error, unexpected '"', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
396+
test.lua:3:7: syntax error, unexpected '"', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
397397
]=]
398398

399399
r = parse(s)
@@ -488,6 +488,16 @@ e = [=[
488488
r = parse(s)
489489
assert(r == e)
490490

491+
s = [=[
492+
q, r, f = 3//2, 3%2, 3/2
493+
]=]
494+
e = [=[
495+
{ `Set{ { `Id "q", `Id "r", `Id "f" }, { `Op{ "idiv", `Number "3", `Number "2" }, `Op{ "mod", `Number "3", `Number "2" }, `Op{ "div", `Number "3", `Number "2" } } } }
496+
]=]
497+
498+
r = parse(s)
499+
assert(r == e)
500+
491501
-- assignments
492502

493503
s = [=[
@@ -551,6 +561,28 @@ e = [=[
551561
r = parse(s)
552562
assert(r == e)
553563

564+
-- bitwise expressions
565+
566+
s = [=[
567+
b = 1 & 0 | 1 ~ 1
568+
]=]
569+
e = [=[
570+
{ `Set{ { `Id "b" }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Number "1", `Number "1" } } } } }
571+
]=]
572+
573+
r = parse(s)
574+
assert(r == e)
575+
576+
s = [=[
577+
b = 1 & 0 | 1 >> 1 ~ 1
578+
]=]
579+
e = [=[
580+
{ `Set{ { `Id "b" }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Op{ "shr", `Number "1", `Number "1" }, `Number "1" } } } } }
581+
]=]
582+
583+
r = parse(s)
584+
assert(r == e)
585+
554586
-- break
555587

556588
s = [=[
@@ -1272,6 +1304,50 @@ test.lua:2:1: syntax error, unexpected 'EOF', expecting 'end', 'return', '(', 'N
12721304
r = parse(s)
12731305
assert(r == e)
12741306

1307+
-- arithmetic expressions
1308+
1309+
s = [=[
1310+
a = 3 / / 2
1311+
]=]
1312+
e = [=[
1313+
test.lua:1:9: syntax error, unexpected '/', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
1314+
]=]
1315+
1316+
r = parse(s)
1317+
assert(r == e)
1318+
1319+
-- bitwise expressions
1320+
1321+
s = [=[
1322+
b = 1 && 1
1323+
]=]
1324+
e = [=[
1325+
test.lua:1:8: syntax error, unexpected '&', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
1326+
]=]
1327+
1328+
r = parse(s)
1329+
assert(r == e)
1330+
1331+
s = [=[
1332+
b = 1 <> 0
1333+
]=]
1334+
e = [=[
1335+
test.lua:1:8: syntax error, unexpected '>', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
1336+
]=]
1337+
1338+
r = parse(s)
1339+
assert(r == e)
1340+
1341+
s = [=[
1342+
b = 1 < < 0
1343+
]=]
1344+
e = [=[
1345+
test.lua:1:9: syntax error, unexpected '<', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
1346+
]=]
1347+
1348+
r = parse(s)
1349+
assert(r == e)
1350+
12751351
-- break
12761352

12771353
s = [=[
@@ -1308,14 +1384,13 @@ test.lua:3:1: syntax error, <break> not inside a loop
13081384
r = parse(s)
13091385
assert(r == e)
13101386

1311-
13121387
-- concatenation expressions
13131388

13141389
s = [=[
13151390
concat2 = 2^3..1
13161391
]=]
13171392
e = [=[
1318-
test.lua:1:15: syntax error, unexpected '.1', expecting 'return', '(', 'Name', 'goto', 'break', '::', 'local', 'function', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '..', '-', '+', '%', '/', '*', '^'
1393+
test.lua:1:15: syntax error, unexpected '.1', expecting 'return', '(', 'Name', 'goto', 'break', '::', 'local', 'function', 'repeat', 'for', 'do', 'while', 'if', ';', ',', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^'
13191394
]=]
13201395

13211396
r = parse(s)
@@ -1349,7 +1424,7 @@ s = [=[
13491424
for i=1,10, do end
13501425
]=]
13511426
e = [=[
1352-
test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
1427+
test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
13531428
]=]
13541429

13551430
r = parse(s)
@@ -1404,7 +1479,7 @@ s = [=[
14041479
goto label
14051480
]=]
14061481
e = [=[
1407-
test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
1482+
test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
14081483
]=]
14091484

14101485
r = parse(s)
@@ -1474,7 +1549,7 @@ elseif
14741549
end
14751550
]=]
14761551
e = [=[
1477-
test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
1552+
test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
14781553
]=]
14791554

14801555
r = parse(s)
@@ -1521,7 +1596,7 @@ s = [=[
15211596
local a =
15221597
]=]
15231598
e = [=[
1524-
test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
1599+
test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
15251600
]=]
15261601

15271602
r = parse(s)
@@ -1592,7 +1667,7 @@ return 1;
15921667
return 1,1-2*3+4,"alo";
15931668
]=]
15941669
e = [=[
1595-
test.lua:2:1: syntax error, unexpected 'return', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
1670+
test.lua:2:1: syntax error, unexpected 'return', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
15961671
]=]
15971672

15981673
r = parse(s)
@@ -1604,7 +1679,7 @@ s = [=[
16041679
t = { , }
16051680
]=]
16061681
e = [=[
1607-
test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not', 'Name', '['
1682+
test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not', 'Name', '['
16081683
]=]
16091684

16101685
r = parse(s)
@@ -1671,7 +1746,7 @@ while (i < 10)
16711746
end
16721747
]=]
16731748
e = [=[
1674-
test.lua:3:3: syntax error, unexpected 'i', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '..', '-', '+', '%', '/', '*', '^', 'String', '{', '(', ':', '[', '.'
1749+
test.lua:3:3: syntax error, unexpected 'i', expecting 'do', 'or', 'and', '>', '<', '>=', '<=', '==', '~=', '|', '~', '&', '>>', '<<', '..', '-', '+', '%', '/', '//', '*', '^', 'String', '{', '(', ':', '[', '.'
16751750
]=]
16761751

16771752
r = parse(s)

0 commit comments

Comments
 (0)