lang-bootstrap/06/parser-gen/parsers/lua-parser-tests.lua
Dawid Sobczak e6b88d5a0f Add stage 06: Lua bootstrap
The goal of stage 06 is to try parse zig synax in lua. I pulled in
lpeglable 1.2.0 and parser-gen off github to get started. All of this
needs to be cleaned up rather soon.

Lua boostraps using tcc and musl from the previous stage. Since musl
0.6.0 doesn't support dynamic linking this build of lua doesn't support
shared libraries. I couldn't easily patch musl with dlopen and friends
so instead I link statically and call deps with c api.
2023-07-06 12:32:47 +01:00

799 lines
No EOL
17 KiB
Lua

local lua = require "lua-parser"
local peg = require "peg-parser"
local eq = require "equals"
local equals = eq.equals
print("\n\n [[ PARSING LUA TEST SUITE FILES ]] \n\n")
local filenames = {
'all.lua',
'main.lua',
'gc.lua',
'db.lua',
'calls.lua',
'strings.lua',
'literals.lua',
'tpack.lua',
'attrib.lua',
'locals.lua',
'constructs.lua',
'code.lua',
'big.lua',
'nextvar.lua',
'pm.lua',
'utf8.lua',
'api.lua',
'events.lua',
'vararg.lua',
'closure.lua',
'coroutine.lua',
'goto.lua',
'errors.lua',
'math.lua',
'sort.lua',
'bitwise.lua',
'verybig.lua',
'files.lua',
}
local errs = 0
for k,v in ipairs(filenames) do
local filename = "lua-5.3.4-tests/"..v
local f = assert(io.open(filename, "r"))
local t = f:read("*all")
local res, err = lua.parse(t)
local s = "OK"
if not res then s = "FAIL" end -- only check if succesful since grammar ensures whole file is read
print("Testing file '"..v.."': ["..s.."]")
if not res then
errs = errs + 1
print("Error: "..err[1]["msg"])
end
f:close()
end
assert(errs == 0)
print("\n\n Test suite files compiled successfully")
print("\n\n [[ TESTING ERROR LABELS ]] ")
local pr = peg.print_r
-- test errors
local s,res, err
local ErrExtra="unexpected character(s), expected EOF"
s = [[ return; ! ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExtra)
local ErrInvalidStat="unexpected token, invalid start of statement"
s = [[ ! ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrInvalidStat)
local ErrEndIf="expected 'end' to close the if statement"
s = [[ if c then b=1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEndIf)
local ErrExprIf="expected a condition after 'if'"
s = [[ if then b=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprIf)
local ErrThenIf="expected 'then' after the condition"
s = [[ if c b=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrThenIf)
local ErrExprEIf="expected a condition after 'elseif'"
s = [[ if a then b=1 elseif then d=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprEIf)
local ErrThenEIf="expected 'then' after the condition"
s = [[ if a b=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrThenEIf)
local ErrEndDo="expected 'end' to close the do block"
s = [[ do x=1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEndDo)
local ErrExprWhile="expected a condition after 'while'"
s = [[ while do c=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprWhile)
local ErrDoWhile="expected 'do' after the condition"
s = [[ while a c=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDoWhile)
local ErrEndWhile="expected 'end' to close the while loop"
s = [[ while a do b=1]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEndWhile)
local ErrUntilRep="expected 'until' at the end of the repeat loop"
s = [[ repeat c=1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrUntilRep)
local ErrExprRep="expected a conditions after 'until'"
s = [[ repeat c=1 until ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprRep)
local ErrForRange="expected a numeric or generic range after 'for'"
s = [[ for 3,4 do x=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrForRange)
local ErrEndFor="expected 'end' to close the for loop"
s = [[ for c=1,3 do a=1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEndFor)
local ErrExprFor1="expected a starting expression for the numeric range"
s = [[ for a=,4 do a=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprFor1)
local ErrCommaFor="expected ',' to split the start and end of the range"
s = [[ for a=4 5 do a=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCommaFor)
local ErrExprFor2="expected an ending expression for the numeric range"
s = [[ for a=4, do a=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprFor2)
local ErrExprFor3="expected a step expression for the numeric range after ','"
s = [[ for a=1,2, do a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprFor3)
local ErrInFor="expected '=' or 'in' after the variable(s)"
s = [[ for a of 1 do a=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrInFor)
local ErrEListFor="expected one or more expressions after 'in'"
s = [[ for a in do a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEListFor)
local ErrDoFor="expected 'do' after the range of the for loop"
s = [[ for a=1,2 a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDoFor)
local ErrDefLocal="expected a function definition or assignment after local"
s = [[ local return c ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDefLocal)
local ErrNameLFunc="expected a function name after 'function'"
s = [[ local function() c=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrNameLFunc)
local ErrEListLAssign="expected one or more expressions after '='"
s = [[ local a = return b ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEListLAssign)
local ErrEListAssign="expected one or more expressions after '='"
s = [[ a = return b ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEListAssign)
local ErrFuncName="expected a function name after 'function'"
s = [[ function () a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrFuncName)
local ErrNameFunc1="expected a function name after '.'"
s = [[ function a.() a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrNameFunc1)
local ErrNameFunc2="expected a method name after ':'"
s = [[ function a:() a=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrNameFunc2)
local ErrOParenPList="expected '(' for the parameter list"
s = [[ function a b=1 end]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrOParenPList)
local ErrCParenPList="expected ')' to close the parameter list"
s = [[
function a(
b=1
end
]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCParenPList)
local ErrEndFunc="expected 'end' to close the function body"
s = [[ function a() b=1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEndFunc)
local ErrParList="expected a variable name or '...' after ','"
s = [[ function a(b, ) b=1 end ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrParList)
local ErrLabel="expected a label name after '::'"
s = [[ :: return b ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrLabel)
local ErrCloseLabel="expected '::' after the label"
s = [[ :: abc return a]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCloseLabel)
local ErrGoto="expected a label after 'goto'"
s = [[ goto return c]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrGoto)
local ErrVarList="expected a variable name after ','"
s = [[ abc,
= 3]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrVarList)
local ErrExprList="expected an expression after ','"
s = [[ return a,;]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprList)
local ErrOrExpr="expected an expression after 'or'"
s = [[ return a or; ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrOrExpr)
local ErrAndExpr="expected an expression after 'and'"
s = [[ return a and;]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrAndExpr)
local ErrRelExpr="expected an expression after the relational operator"
s = [[ return a >;]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrRelExpr)
local ErrBitwiseExpr="expected an expression after bitwise operator"
s = [[ return b & ; ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrBitwiseExpr)
local ErrConcatExpr="expected an expression after '..'"
s = [[ print(a..) ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrConcatExpr)
local ErrAddExpr="expected an expression after the additive operator"
s = [[ return a - ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrAddExpr)
local ErrMulExpr="expected an expression after the multiplicative operator"
s = [[ return a/ ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrMulExpr)
local ErrUnaryExpr="expected an expression after the unary operator"
s = [[ return # ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrUnaryExpr)
local ErrPowExpr="expected an expression after '^'"
s = [[ return a^ ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrPowExpr)
local ErrExprParen="expected an expression after '('"
s = [[ return a + () ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprParen)
local ErrCParenExpr="expected ')' to close the expression"
s = [[ return a + (a ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCParenExpr)
local ErrNameIndex="expected a field name after '.'"
s = [[ return a. ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrNameIndex)
local ErrExprIndex="expected an expression after '['"
s = [[ return a [ ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprIndex)
local ErrCBracketIndex="expected ']' to close the indexing expression"
s = [[ return a[1 ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCBracketIndex)
local ErrNameMeth="expected a method name after ':'"
s = [[ return a: ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrNameMeth)
local ErrMethArgs="expected some arguments for the method call (or '()')"
s = [[ a:b ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrMethArgs)
local ErrCParenArgs="expected ')' to close the argument list"
s = [[ return a(c ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCParenArgs)
local ErrCBraceTable="expected '}' to close the table constructor"
s = [[ return { ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCBraceTable)
local ErrEqField="expected '=' after the table key"
s = [[ a = {[b] b} ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEqField)
local ErrExprField="expected an expression after '='"
s = [[ a = {[a] = } ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprField)
local ErrExprFKey="expected an expression after '[' for the table key"
s = [[ a = {[ = b} ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrExprFKey)
local ErrCBracketFKey="expected ']' to close the table key"
s = [[ a = {[a = b} ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCBracketFKey)
local ErrDigitHex="expected one or more hexadecimal digits after '0x'"
s = [[ a = 0x ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDigitHex)
local ErrDigitDeci="expected one or more digits after the decimal point"
s = [[ a = . ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDigitDeci)
local ErrDigitExpo="expected one or more digits for the exponent"
s = [[ a = 1.0e ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDigitExpo)
local ErrQuote="unclosed string"
s = [[ a = ";]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrQuote)
local ErrHexEsc="expected exactly two hexadecimal digits after '\\x'"
s = [[ a = "a\x1" ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrHexEsc)
local ErrOBraceUEsc="expected '{' after '\\u'"
s = [[ a = "a\u" ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrOBraceUEsc)
local ErrDigitUEsc="expected one or more hexadecimal digits for the UTF-8 code point"
s = [[ a = "\u{}"]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrDigitUEsc)
local ErrCBraceUEsc="expected '}' after the code point"
s = [[ a = "\u{12" ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCBraceUEsc)
local ErrEscSeq="invalid escape sequence"
s = [[ a = "\;" ]]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrEscSeq)
local ErrCloseLStr="unclosed long string"
s = [==[ a = [[ abc return; ]==]
print("Parsing '"..s.."'")
res, err = lua.parse(s)
assert(err[1]["msg"] == ErrCloseLStr)
print("\n\n All error labels generated successfully")
print("\n\n [[ TESTING AST GENERATION ]]\n\n ")
-- TODO: AST
s = [[
if abc > 123 then
abc=123
end]]
rez = {
rule='chunk',
pos=3,
{
rule='block',
pos=3,
{
rule='stat',
pos=3,
'if',
{
rule='exp',
pos=6,
{
rule='exp',
{
rule='exp',
{
rule='expTokens',
pos=6,
{
rule='prefixexp',
pos=6,
{
rule='varOrExp',
pos=6,
{
rule='var',
pos=6,
{
rule='NAME',
pos=6,
'abc',
},
},
},
},
},
},
{
rule='operatorComparison',
pos=10,
'>',
},
{
rule='expTokens',
pos=12,
{
rule='number',
pos=12,
{
rule='INT',
pos=12,
'123',
},
},
},
},
},
'then',
{
rule='block',
pos=23,
{
rule='stat',
pos=23,
{
rule='varlist',
pos=23,
{
rule='var',
pos=23,
{
rule='NAME',
pos=23,
'abc',
},
},
},
'=',
{
rule='explist',
pos=27,
{
rule='exp',
pos=27,
{
rule='expTokens',
pos=27,
{
rule='number',
pos=27,
{
rule='INT',
pos=27,
'123',
},
},
},
},
},
},
},
'end',
},
},
}
print("Parsing '"..s.."'")
res, err = lua.parse(s)
peg.print_t(res)
assert(equals(res,rez))
s = [[
local a = [=[ long string ]=]
-- aaa
return a
--[==[ hi
]==]
]]
rez = {
rule='chunk',
pos=3,
{
rule='block',
pos=3,
{
rule='stat',
pos=3,
'local',
{
rule='localAssign',
pos=9,
{
rule='namelist',
pos=9,
{
rule='NAME',
pos=9,
'a',
},
},
'=',
{
rule='explist',
pos=13,
{
rule='exp',
pos=13,
{
rule='expTokens',
pos=13,
{
rule='string',
pos=13,
' long string ',
},
},
},
},
},
},
{
rule='retstat',
pos=41,
'return',
{
rule='explist',
pos=48,
{
rule='exp',
pos=48,
{
rule='expTokens',
pos=48,
{
rule='prefixexp',
pos=48,
{
rule='varOrExp',
pos=48,
{
rule='var',
pos=48,
{
rule='NAME',
pos=48,
'a',
},
},
},
},
},
},
},
},
},
}
print("Parsing '"..s.."'")
res, err = lua.parse(s)
peg.print_t(res)
assert(equals(res,rez))
print("\n\n All AST's generated successfully")
print("\n\nAll tests passed!")