minor cleanup, bugfixes, worked on golike parser
This commit is contained in:
@@ -1,11 +1,20 @@
|
|||||||
import gll
|
import gll
|
||||||
|
|
||||||
ws = gll.many(gll.whitespace)
|
ws = gll.skipmany(gll.whitespace())
|
||||||
|
skipped = lambda pat: gll.skip(gll.string(pat))
|
||||||
|
|
||||||
function = function
|
body = gll.seq(skipped("{"), skipped("}"))
|
||||||
|
|
||||||
package_name = gll.seq(gll.skip(gll.string("package")), gl.skip(ws),
|
argument = gll.seq(gll.regex("\w+", tag="argument"), ws,
|
||||||
gll.regex(".*$"), tag="package_name")
|
gll.regex("\w+", tag="type"), gll.skip(gll.regex("[\s,]*")))
|
||||||
|
arguments_list = gll.seq(skipped("("), gll.many(argument), skipped(")"), tag="arguments")
|
||||||
|
|
||||||
|
function = gll.seq(skipped("func"), ws, gll.regex("\w+", tag="function_name"),
|
||||||
|
ws, arguments_list, ws, body, ws, tag="function")
|
||||||
|
|
||||||
|
package_name = gll.seq(skipped("package"), ws, gll.regex("\w+", tag="name"),
|
||||||
|
gll.skipmany(gll.string(" ")), skipped("\n"),
|
||||||
|
tag="package_name")
|
||||||
|
|
||||||
package = gll.seq(package_name, gll.many(function, tag="package_body"),
|
package = gll.seq(package_name, gll.many(function, tag="package_body"),
|
||||||
tag="package")
|
tag="package")
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
|
from gll.util import rename
|
||||||
from gll.result import Success, Failure
|
from gll.result import Success, Failure
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
@@ -11,6 +12,7 @@ class Parser:
|
|||||||
return self.fun(string)
|
return self.fun(string)
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
|
@rename("{}_alt_{}".format(self.tag, other.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = self(string)
|
res = self(string)
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ class Parser:
|
|||||||
return Parser(internal)
|
return Parser(internal)
|
||||||
|
|
||||||
def __rshift__(self, into):
|
def __rshift__(self, into):
|
||||||
|
@rename("{}_into_{}".format(self.tag, self.into))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = self(string)
|
res = self(string)
|
||||||
return Success(into(res.value), res.rest, self.tag)
|
return Success(into(res.value), res.rest, self.tag)
|
||||||
@@ -27,6 +30,7 @@ class Parser:
|
|||||||
|
|
||||||
|
|
||||||
def string(match, tag=None):
|
def string(match, tag=None):
|
||||||
|
@rename("string_{}".format(match))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
ln = len(match)
|
ln = len(match)
|
||||||
if len(string) < ln:
|
if len(string) < ln:
|
||||||
@@ -43,16 +47,20 @@ def string(match, tag=None):
|
|||||||
def regex(match, tag=None, reopts=None):
|
def regex(match, tag=None, reopts=None):
|
||||||
if not reopts:
|
if not reopts:
|
||||||
reopts = []
|
reopts = []
|
||||||
rx = regex.compile(match, *reopts)
|
rx = re.compile(match, *reopts)
|
||||||
|
|
||||||
|
@rename("regex_{}".format(match))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = rx.match(string)
|
res = rx.match(string)
|
||||||
if res:
|
if res:
|
||||||
return Success(res.group(0), string[endpos+1:], tag)
|
group = res.group(0)
|
||||||
|
return Success(group, string[res.end():], tag)
|
||||||
return Failure(string)
|
return Failure(string)
|
||||||
return Parser(internal, tag)
|
return Parser(internal, tag)
|
||||||
|
|
||||||
|
|
||||||
def digit(tag=None):
|
def digit(tag=None):
|
||||||
|
@rename("digit")
|
||||||
def internal(string):
|
def internal(string):
|
||||||
if not string:
|
if not string:
|
||||||
return Failure(string)
|
return Failure(string)
|
||||||
@@ -65,6 +73,7 @@ def digit(tag=None):
|
|||||||
|
|
||||||
|
|
||||||
def many(parser, tag=None):
|
def many(parser, tag=None):
|
||||||
|
@rename("many_{}".format(parser.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
|
|
||||||
@@ -81,6 +90,7 @@ def many(parser, tag=None):
|
|||||||
|
|
||||||
|
|
||||||
def many1(parser, tag=None):
|
def many1(parser, tag=None):
|
||||||
|
@rename("many1_{}".format(parser.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
|
|
||||||
@@ -97,16 +107,20 @@ def many1(parser, tag=None):
|
|||||||
|
|
||||||
|
|
||||||
def whitespace(tag=None):
|
def whitespace(tag=None):
|
||||||
|
@rename("whitespace")
|
||||||
def internal(string):
|
def internal(string):
|
||||||
|
if not string:
|
||||||
|
return Failure(string)
|
||||||
head = string[0]
|
head = string[0]
|
||||||
tail = string[1:]
|
tail = string[1:]
|
||||||
if head.strip == "":
|
if head.strip() == "":
|
||||||
return Success(head, tail, tag)
|
return Success(head, tail, tag)
|
||||||
return Failure(string)
|
return Failure(string)
|
||||||
return Parser(internal, tag)
|
return Parser(internal, tag)
|
||||||
|
|
||||||
|
|
||||||
def skip(parser, tag=None):
|
def skip(parser, tag=None):
|
||||||
|
@rename("skip_{}".format(parser.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
|
|
||||||
@@ -121,6 +135,7 @@ def skipmany(parser, tag=None):
|
|||||||
|
|
||||||
|
|
||||||
def opt(parser, tag=None):
|
def opt(parser, tag=None):
|
||||||
|
@rename("opt_{}".format(parser.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
if res.valid:
|
if res.valid:
|
||||||
@@ -130,6 +145,7 @@ def opt(parser, tag=None):
|
|||||||
|
|
||||||
|
|
||||||
def seq(*parsers, tag=None):
|
def seq(*parsers, tag=None):
|
||||||
|
@rename("seq_{}".format("_".join(str(parser.tag) for parser in parsers)))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
resl = []
|
resl = []
|
||||||
rest = string
|
rest = string
|
||||||
@@ -143,6 +159,7 @@ def seq(*parsers, tag=None):
|
|||||||
return Parser(internal, tag)
|
return Parser(internal, tag)
|
||||||
|
|
||||||
def all(parser, tag=None):
|
def all(parser, tag=None):
|
||||||
|
@rename("all_{}".format(parser.tag))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
|
|
||||||
|
@@ -34,7 +34,7 @@ class Success(Result):
|
|||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
return bool(self.value)
|
return bool(self.value)
|
||||||
|
|
||||||
def tokens(self, purge=False, inner=False):
|
def tokens(self, purge=True, inner=False):
|
||||||
if type(self.value) == list:
|
if type(self.value) == list:
|
||||||
for val in self.value:
|
for val in self.value:
|
||||||
if type(val) == Success:
|
if type(val) == Success:
|
||||||
@@ -43,6 +43,8 @@ class Success(Result):
|
|||||||
yield tok
|
yield tok
|
||||||
else:
|
else:
|
||||||
toks = list(val.tokens(purge, inner=True))
|
toks = list(val.tokens(purge, inner=True))
|
||||||
|
if not len(toks) and purge:
|
||||||
|
continue
|
||||||
if len(toks) == 1:
|
if len(toks) == 1:
|
||||||
toks = toks[0]
|
toks = toks[0]
|
||||||
yield Token(toks, tag=val.tag)
|
yield Token(toks, tag=val.tag)
|
||||||
|
5
gll/util.py
Normal file
5
gll/util.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
def rename(name):
|
||||||
|
def wrapped(f):
|
||||||
|
f.__name__ = name
|
||||||
|
return f
|
||||||
|
return wrapped
|
Reference in New Issue
Block a user