Skip to content

Commit

Permalink
Updating the parser to support the syntax of Lua 5.3
Browse files Browse the repository at this point in the history
  • Loading branch information
andremm committed Aug 3, 2014
1 parent 5859060 commit f90c67e
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
lua-parser
==========

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

38 changes: 28 additions & 10 deletions lua-parser/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,9 @@ apply:
lhs: `Id{ <string> } | `Index{ expr expr }
opid: 'add' | 'sub' | 'mul' | 'div' | 'mod' | 'pow' | 'concat'
| 'eq' | 'lt' | 'le' | 'and' | 'or' | 'not' | 'unm' | 'len'
opid: 'add' | 'sub' | 'mul' | 'div' | 'idiv' | 'mod' | 'pow' | 'concat'
| 'band' | 'bor' | 'bxor' | 'shl' | 'shr' | 'eq' | 'lt' | 'le'
| 'and' | 'or' | 'not' | 'unm' | 'len' | 'bnot'
]]
local parser = {}

Expand Down Expand Up @@ -152,9 +153,15 @@ local function binaryop (e1, op, e2)
op == "sub" or
op == "mul" or
op == "div" or
op == "idiv" or
op == "mod" or
op == "pow" or
op == "concat" or
op == "band" or
op == "bor" or
op == "bxor" or
op == "shl" or
op == "shr" or
op == "eq" or
op == "lt" or
op == "le" or
Expand Down Expand Up @@ -227,13 +234,17 @@ local G = { V"Lua",
SubExpr_1 = chainl1(V"SubExpr_2", V"OrOp");
SubExpr_2 = chainl1(V"SubExpr_3", V"AndOp");
SubExpr_3 = chainl1(V"SubExpr_4", V"RelOp");
SubExpr_4 = V"SubExpr_5" * V"ConOp" * V"SubExpr_4" / binaryop +
V"SubExpr_5";
SubExpr_5 = chainl1(V"SubExpr_6", V"AddOp");
SubExpr_6 = chainl1(V"SubExpr_7", V"MulOp");
SubExpr_7 = V"UnOp" * V"SubExpr_7" / unaryop +
V"SubExpr_8";
SubExpr_8 = V"SimpleExp" * (V"PowOp" * V"SubExpr_7")^-1 / binaryop;
SubExpr_4 = chainl1(V"SubExpr_5", V"BOrOp");
SubExpr_5 = chainl1(V"SubExpr_6", V"BXorOp");
SubExpr_6 = chainl1(V"SubExpr_7", V"BAndOp");
SubExpr_7 = chainl1(V"SubExpr_8", V"ShiftOp");
SubExpr_8 = V"SubExpr_9" * V"ConOp" * V"SubExpr_8" / binaryop +
V"SubExpr_9";
SubExpr_9 = chainl1(V"SubExpr_10", V"AddOp");
SubExpr_10 = chainl1(V"SubExpr_11", V"MulOp");
SubExpr_11 = V"UnOp" * V"SubExpr_11" / unaryop +
V"SubExpr_12";
SubExpr_12 = V"SimpleExp" * (V"PowOp" * V"SubExpr_11")^-1 / binaryop;
SimpleExp = taggedCap("Number", token(V"Number", "Number")) +
taggedCap("String", token(V"String", "String")) +
taggedCap("Nil", kw("nil")) +
Expand Down Expand Up @@ -405,15 +416,22 @@ local G = { V"Lua",
symb(">=") / "ge" +
symb("<") / "lt" +
symb(">") / "gt";
BOrOp = symb("|") / "bor";
BXorOp = symb("~") / "bxor";
BAndOp = symb("&") / "band";
ShiftOp = symb("<<") / "shl" +
symb(">>") / "shr";
ConOp = symb("..") / "concat";
AddOp = symb("+") / "add" +
symb("-") / "sub";
MulOp = symb("*") / "mul" +
symb("//") / "idiv" +
symb("/") / "div" +
symb("%") / "mod";
UnOp = kw("not") / "not" +
symb("-") / "unm" +
symb("#") / "len";
symb("#") / "len" +
symb("~") / "bnot";
PowOp = symb("^") / "pow";
Shebang = P"#" * (P(1) - P"\n")^0 * P"\n";
-- for error reporting
Expand Down
97 changes: 86 additions & 11 deletions test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ long string
]==]
]=]
e = [=[
test.lua:5:7: syntax error, unexpected '[', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
test.lua:5:7: syntax error, unexpected '[', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

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

r = parse(s)
Expand Down Expand Up @@ -488,6 +488,16 @@ e = [=[
r = parse(s)
assert(r == e)

s = [=[
q, r, f = 3//2, 3%2, 3/2
]=]
e = [=[
{ `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" } } } }
]=]

r = parse(s)
assert(r == e)

-- assignments

s = [=[
Expand Down Expand Up @@ -551,6 +561,28 @@ e = [=[
r = parse(s)
assert(r == e)

-- bitwise expressions

s = [=[
b = 1 & 0 | 1 ~ 1
]=]
e = [=[
{ `Set{ { `Id "b" }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Number "1", `Number "1" } } } } }
]=]

r = parse(s)
assert(r == e)

s = [=[
b = 1 & 0 | 1 >> 1 ~ 1
]=]
e = [=[
{ `Set{ { `Id "b" }, { `Op{ "bor", `Op{ "band", `Number "1", `Number "0" }, `Op{ "bxor", `Op{ "shr", `Number "1", `Number "1" }, `Number "1" } } } } }
]=]

r = parse(s)
assert(r == e)

-- break

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

-- arithmetic expressions

s = [=[
a = 3 / / 2
]=]
e = [=[
test.lua:1:9: syntax error, unexpected '/', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
assert(r == e)

-- bitwise expressions

s = [=[
b = 1 && 1
]=]
e = [=[
test.lua:1:8: syntax error, unexpected '&', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
assert(r == e)

s = [=[
b = 1 <> 0
]=]
e = [=[
test.lua:1:8: syntax error, unexpected '>', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
assert(r == e)

s = [=[
b = 1 < < 0
]=]
e = [=[
test.lua:1:9: syntax error, unexpected '<', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
assert(r == e)

-- break

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


-- concatenation expressions

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

r = parse(s)
Expand Down Expand Up @@ -1349,7 +1424,7 @@ s = [=[
for i=1,10, do end
]=]
e = [=[
test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
test.lua:1:13: syntax error, unexpected 'do', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
Expand Down Expand Up @@ -1404,7 +1479,7 @@ s = [=[
goto label
]=]
e = [=[
test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
test.lua:2:1: syntax error, unexpected 'goto', expecting ';', '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
Expand Down Expand Up @@ -1474,7 +1549,7 @@ elseif
end
]=]
e = [=[
test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
test.lua:7:1: syntax error, unexpected 'end', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

r = parse(s)
Expand Down Expand Up @@ -1521,7 +1596,7 @@ s = [=[
local a =
]=]
e = [=[
test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not'
test.lua:2:1: syntax error, unexpected 'EOF', expecting '(', 'Name', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not'
]=]

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

r = parse(s)
Expand All @@ -1604,7 +1679,7 @@ s = [=[
t = { , }
]=]
e = [=[
test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '#', '-', 'not', 'Name', '['
test.lua:1:7: syntax error, unexpected ',', expecting '}', '(', '{', 'function', '...', 'true', 'false', 'nil', 'String', 'Number', '~', '#', '-', 'not', 'Name', '['
]=]

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

r = parse(s)
Expand Down

0 comments on commit f90c67e

Please sign in to comment.