lang-bootstrap/06/parser-gen/peg-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

260 lines
No EOL
4.5 KiB
Lua

local peg = require "peg-parser"
local f = peg.pegToAST
local eq = require "equals"
local equals = eq.equals
-- self-description of peg-parser:
--assert(f(peg.gram))
-- ( p ) grouping
e = f("('a')")
res = {t="a"}
assert(equals(e,res))
-- 'string' literal string
e = f("'string'")
res = {t="string"}
assert(equals(e,res))
-- "string" literal string
e = f('"string"')
res = {t="string"}
assert(equals(e,res))
--[class] character class
e = f("[^a-zA-Z01]")
res = {
action = "invert",
op1 = {
action = "or",
op1 = {
action = "or",
op1 = {
action = "or",
op1 = {
action = "range",
op1 = {
s = "az"
}
},
op2 = {
action = "range",
op1 = {
s = "AZ"
}
}
},
op2 = {
t = "0"
}
},
op2 = {
t = "1"
}
}
}
assert(equals(e,res))
--. any character
e = f(".")
res = {action="anychar"}
assert(equals(e,res))
--%name pattern defs[name] or a pre-defined pattern
e = f("%name")
res = {action="%", op1={s="name"}}
assert(equals(e,res))
--name non terminal
e = f("name")
res = {nt="name"}
assert(equals(e,res))
--<name> non terminal
e = f("<name>")
res = {nt="name"}
assert(equals(e,res))
--{} position capture
e = f("{}")
res = {action="poscap"}
assert(equals(e,res))
--{ p } simple capture
e = f("{name}")
res = {action="scap", op1= {nt="name"}}
assert(equals(e,res))
--{: p :} anonymous group capture
e = f("{:name:}")
res = {action="gcap", op1= {nt="name"}}
assert(equals(e,res))
--{:name: p :} named group capture
e = f("{:g: name:}")
res = {action="gcap", op1= {nt="name"} , op2={s="g"}}
assert(equals(e,res))
--{~ p ~} substitution capture
e = f("{~ name ~}")
res = {action="subcap", op1= {nt="name"}}
assert(equals(e,res))
--{| p |} table capture
e = f("{| name |}")
res = {action="tcap", op1= {nt="name"}}
assert(equals(e,res))
--=name back reference
e = f("=name")
res = {action="bref", op1= {s="name"}}
assert(equals(e,res))
--p ? optional match
e = f("name?")
res = {action="?", op1= {nt="name"}}
assert(equals(e,res))
--p * zero or more repetitions
e = f("name*")
res = {action="*", op1= {nt="name"}}
assert(equals(e,res))
--p + one or more repetitions
e = f("name+")
res = {action="+", op1= {nt="name"}}
assert(equals(e,res))
--p^num exactly n repetitions
e = f("name^3")
res = {action="^", op1= {nt="name"}, op2 = {num="3"}}
assert(equals(e,res))
--p^+num at least n repetitions
e = f("name^+3")
res = {action="^", op1= {nt="name"}, op2 = {num="+3"}}
assert(equals(e,res))
--p^-num at most n repetitions
e = f("name^-3")
res = {action="^", op1= {nt="name"}, op2 = {num="-3"}}
assert(equals(e,res))
--p^LABEL error label
e = f("name^err")
res = {action = "^LABEL", op1= {nt="name"}, op2 = {s="err"}}
assert(equals(e,res))
--p -> 'string' string capture
e = f("name -> 'a'")
res = {action="->", op1= {nt="name"}, op2 = {s="a"}}
assert(equals(e,res))
--p -> "string" string capture
e = f('name -> "a"')
res = {action="->", op1= {nt="name"}, op2 = {s="a"}}
assert(equals(e,res))
--p -> num numbered capture
e = f('name -> 3')
res = {action="->", op1= {nt="name"}, op2 = {num="3"}}
assert(equals(e,res))
--p -> name function/query/string capture equivalent to p / defs[name]
e = f('name -> func')
res = {action="->", op1= {nt="name"}, op2 = {func="func"}}
assert(equals(e,res))
--p => name match-time capture equivalent to lpeg.Cmt(p, defs[name])
e = f('name => func')
res = {action="=>", op1= {nt="name"}, op2 = {func="func"}}
assert(equals(e,res))
--& p and predicate
e = f('&name')
res = {action="&", op1= {nt="name"}}
assert(equals(e,res))
--! p not predicate
e = f('!name')
res = {action="!", op1= {nt="name"}}
assert(equals(e,res))
--p1 p2 p3 concatenation with left association
e = f('name name2 name3')
res = {action="and", op1= {action = "and", op1={nt="name"}, op2={nt="name2"}}, op2={nt="name3"}}
assert(equals(e,res))
--p1 / p2 / p3 ordered choice with left association
e = f('name / name2 / name3')
res = {action="or", op1= {action = "or", op1={nt="name"}, op2={nt="name2"}}, op2={nt="name3"}}
assert(equals(e,res))
--(name <- p)+ grammar
e = f('a <- b b <- c')
res = {
{rulename = "a", rule = {nt="b"}},
{rulename = "b", rule = {nt="c"}}
}
assert(equals(e,res))
-- error labels
-- %{errName}
--peg.setlabels({errName=1})
e = f('%{errName}')
res = {action="label", op1={s="errName"}}
assert(equals(e,res))
-- a //{errName,errName2} b
--peg.setlabels({errName=1, errName2=2})
e = f('a //{errName,errName2} b')
res = {action="or", condition={{s="errName"},{s="errName2"}}, op1={nt="a"}, op2={nt="b"}}
assert(equals(e,res))
print("all tests succesful")