added memoization for a factor 100 speed improvement

This commit is contained in:
2017-02-27 18:08:11 +01:00
parent 6a8d39fc88
commit 980188d90c
3 changed files with 28 additions and 3 deletions

View File

@@ -48,8 +48,8 @@ package_name = gll.seq(skipped("package"), ws, variable,
gll.skipmany(gll.string(" ")), skipped("\n"),
tag="package_name")
package = gll.seq(package_name, gll.sep_by(gll.string("\n"), function,
tag="package_body"),
package = gll.seq(package_name, gll.many(skipped("\n")),
gll.sep_by(gll.string("\n"), function, tag="package_body"),
gll.many(skipped("\n")),
tag="package")

View File

@@ -1,6 +1,6 @@
import re
from gll.util import rename
from gll.util import rename, memoize
from gll.result import Success, Failure
class Parser:
@@ -16,6 +16,7 @@ class Parser:
return self.fun.__name__
def __or__(self, other):
@memoize
@rename("{}_alt_{}".format(self.name, other.name))
def internal(string):
res = self(string)
@@ -26,6 +27,7 @@ class Parser:
return Parser(internal)
def __rshift__(self, into):
@memoize
@rename("{}_into_{}".format(self.name, into))
def internal(string):
res = self(string)
@@ -34,6 +36,7 @@ class Parser:
def string(match, tag="string"):
@memoize
@rename("string_{}".format(match))
def internal(string):
ln = len(match)
@@ -53,6 +56,7 @@ def regex(match, tag="regex", reopts=None):
reopts = []
rx = re.compile(match, *reopts)
@memoize
@rename("regex_{}".format(match))
def internal(string):
res = rx.match(string)
@@ -64,6 +68,7 @@ def regex(match, tag="regex", reopts=None):
def digit(tag="digit"):
@memoize
@rename("digit")
def internal(string):
if not string:
@@ -77,6 +82,7 @@ def digit(tag="digit"):
def many(parser, tag="many"):
@memoize
@rename("many_{}".format(parser.name))
def internal(string):
res = parser(string)
@@ -94,6 +100,7 @@ def many(parser, tag="many"):
def many1(parser, tag="many1"):
@memoize
@rename("many1_{}".format(parser.name))
def internal(string):
res = parser(string)
@@ -111,6 +118,7 @@ def many1(parser, tag="many1"):
def whitespace(tag="whitespace"):
@memoize
@rename("whitespace")
def internal(string):
if not string:
@@ -124,6 +132,7 @@ def whitespace(tag="whitespace"):
def skip(parser, tag="skip"):
@memoize
@rename("skip_{}".format(parser.name))
def internal(string):
res = parser(string)
@@ -139,6 +148,7 @@ def skipmany(parser, tag="skipmany"):
def sep_by(separator, parser, tag="sep_by"):
@memoize
@rename("{}_sep_by_{}".format(parser.name, separator.name))
def internal(string):
if not string:
@@ -162,6 +172,7 @@ def sep_by(separator, parser, tag="sep_by"):
def opt(parser, tag="opt"):
@memoize
@rename("opt_{}".format(parser.name))
def internal(string):
res = parser(string)
@@ -172,6 +183,7 @@ def opt(parser, tag="opt"):
def seq(*parsers, tag="seq"):
@memoize
@rename("seq_{}".format("_".join(str(parser.name) for parser in parsers)))
def internal(string):
resl = []
@@ -187,6 +199,7 @@ def seq(*parsers, tag="seq"):
def all(parser, tag="all"):
@memoize
@rename("all_{}".format(parser.name))
def internal(string):
res = parser(string)

View File

@@ -1,5 +1,17 @@
from functools import wraps
def rename(name):
def wrapped(f):
f.__name__ = name
return f
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