Moved examples to tofix because fixing them is besides the point right now.
260 lines
No EOL
4.5 KiB
Lua
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") |