added memoization for a factor 100 speed improvement
This commit is contained in:
@@ -48,8 +48,8 @@ package_name = gll.seq(skipped("package"), ws, variable,
|
|||||||
gll.skipmany(gll.string(" ")), skipped("\n"),
|
gll.skipmany(gll.string(" ")), skipped("\n"),
|
||||||
tag="package_name")
|
tag="package_name")
|
||||||
|
|
||||||
package = gll.seq(package_name, gll.sep_by(gll.string("\n"), function,
|
package = gll.seq(package_name, gll.many(skipped("\n")),
|
||||||
tag="package_body"),
|
gll.sep_by(gll.string("\n"), function, tag="package_body"),
|
||||||
gll.many(skipped("\n")),
|
gll.many(skipped("\n")),
|
||||||
tag="package")
|
tag="package")
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from gll.util import rename
|
from gll.util import rename, memoize
|
||||||
from gll.result import Success, Failure
|
from gll.result import Success, Failure
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
@@ -16,6 +16,7 @@ class Parser:
|
|||||||
return self.fun.__name__
|
return self.fun.__name__
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
|
@memoize
|
||||||
@rename("{}_alt_{}".format(self.name, other.name))
|
@rename("{}_alt_{}".format(self.name, other.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = self(string)
|
res = self(string)
|
||||||
@@ -26,6 +27,7 @@ class Parser:
|
|||||||
return Parser(internal)
|
return Parser(internal)
|
||||||
|
|
||||||
def __rshift__(self, into):
|
def __rshift__(self, into):
|
||||||
|
@memoize
|
||||||
@rename("{}_into_{}".format(self.name, into))
|
@rename("{}_into_{}".format(self.name, into))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = self(string)
|
res = self(string)
|
||||||
@@ -34,6 +36,7 @@ class Parser:
|
|||||||
|
|
||||||
|
|
||||||
def string(match, tag="string"):
|
def string(match, tag="string"):
|
||||||
|
@memoize
|
||||||
@rename("string_{}".format(match))
|
@rename("string_{}".format(match))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
ln = len(match)
|
ln = len(match)
|
||||||
@@ -53,6 +56,7 @@ def regex(match, tag="regex", reopts=None):
|
|||||||
reopts = []
|
reopts = []
|
||||||
rx = re.compile(match, *reopts)
|
rx = re.compile(match, *reopts)
|
||||||
|
|
||||||
|
@memoize
|
||||||
@rename("regex_{}".format(match))
|
@rename("regex_{}".format(match))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = rx.match(string)
|
res = rx.match(string)
|
||||||
@@ -64,6 +68,7 @@ def regex(match, tag="regex", reopts=None):
|
|||||||
|
|
||||||
|
|
||||||
def digit(tag="digit"):
|
def digit(tag="digit"):
|
||||||
|
@memoize
|
||||||
@rename("digit")
|
@rename("digit")
|
||||||
def internal(string):
|
def internal(string):
|
||||||
if not string:
|
if not string:
|
||||||
@@ -77,6 +82,7 @@ def digit(tag="digit"):
|
|||||||
|
|
||||||
|
|
||||||
def many(parser, tag="many"):
|
def many(parser, tag="many"):
|
||||||
|
@memoize
|
||||||
@rename("many_{}".format(parser.name))
|
@rename("many_{}".format(parser.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
@@ -94,6 +100,7 @@ def many(parser, tag="many"):
|
|||||||
|
|
||||||
|
|
||||||
def many1(parser, tag="many1"):
|
def many1(parser, tag="many1"):
|
||||||
|
@memoize
|
||||||
@rename("many1_{}".format(parser.name))
|
@rename("many1_{}".format(parser.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
@@ -111,6 +118,7 @@ def many1(parser, tag="many1"):
|
|||||||
|
|
||||||
|
|
||||||
def whitespace(tag="whitespace"):
|
def whitespace(tag="whitespace"):
|
||||||
|
@memoize
|
||||||
@rename("whitespace")
|
@rename("whitespace")
|
||||||
def internal(string):
|
def internal(string):
|
||||||
if not string:
|
if not string:
|
||||||
@@ -124,6 +132,7 @@ def whitespace(tag="whitespace"):
|
|||||||
|
|
||||||
|
|
||||||
def skip(parser, tag="skip"):
|
def skip(parser, tag="skip"):
|
||||||
|
@memoize
|
||||||
@rename("skip_{}".format(parser.name))
|
@rename("skip_{}".format(parser.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
@@ -139,6 +148,7 @@ def skipmany(parser, tag="skipmany"):
|
|||||||
|
|
||||||
|
|
||||||
def sep_by(separator, parser, tag="sep_by"):
|
def sep_by(separator, parser, tag="sep_by"):
|
||||||
|
@memoize
|
||||||
@rename("{}_sep_by_{}".format(parser.name, separator.name))
|
@rename("{}_sep_by_{}".format(parser.name, separator.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
if not string:
|
if not string:
|
||||||
@@ -162,6 +172,7 @@ def sep_by(separator, parser, tag="sep_by"):
|
|||||||
|
|
||||||
|
|
||||||
def opt(parser, tag="opt"):
|
def opt(parser, tag="opt"):
|
||||||
|
@memoize
|
||||||
@rename("opt_{}".format(parser.name))
|
@rename("opt_{}".format(parser.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
@@ -172,6 +183,7 @@ def opt(parser, tag="opt"):
|
|||||||
|
|
||||||
|
|
||||||
def seq(*parsers, tag="seq"):
|
def seq(*parsers, tag="seq"):
|
||||||
|
@memoize
|
||||||
@rename("seq_{}".format("_".join(str(parser.name) for parser in parsers)))
|
@rename("seq_{}".format("_".join(str(parser.name) for parser in parsers)))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
resl = []
|
resl = []
|
||||||
@@ -187,6 +199,7 @@ def seq(*parsers, tag="seq"):
|
|||||||
|
|
||||||
|
|
||||||
def all(parser, tag="all"):
|
def all(parser, tag="all"):
|
||||||
|
@memoize
|
||||||
@rename("all_{}".format(parser.name))
|
@rename("all_{}".format(parser.name))
|
||||||
def internal(string):
|
def internal(string):
|
||||||
res = parser(string)
|
res = parser(string)
|
||||||
|
12
gll/util.py
12
gll/util.py
@@ -1,5 +1,17 @@
|
|||||||
|
from functools import wraps
|
||||||
|
|
||||||
def rename(name):
|
def rename(name):
|
||||||
def wrapped(f):
|
def wrapped(f):
|
||||||
f.__name__ = name
|
f.__name__ = name
|
||||||
return f
|
return f
|
||||||
return wrapped
|
return wrapped
|
||||||
|
|
||||||
|
|
||||||
|
def memoize(f):
|
||||||
|
d = {}
|
||||||
|
@wraps(f)
|
||||||
|
def internal(arg):
|
||||||
|
if arg not in d:
|
||||||
|
d[arg] = f(arg)
|
||||||
|
return d[arg]
|
||||||
|
return internal
|
||||||
|
Reference in New Issue
Block a user