base production refactor

This commit is contained in:
2018-10-28 03:55:17 -04:00
parent 8fc9bb237a
commit a73a7ada27
6 changed files with 138 additions and 138 deletions

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="JavaScriptSettings"> <component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" /> <option name="languageLevel" value="ES6" />
</component> </component>
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (thue)" project-jdk-type="Python SDK" /> <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (pythue)" project-jdk-type="Python SDK" />
</project> </project>

2
.idea/thue.iml generated
View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" /> <excludeFolder url="file://$MODULE_DIR$/venv" />
</content> </content>
<orderEntry type="jdk" jdkName="Python 3.7 (thue)" jdkType="Python SDK" /> <orderEntry type="jdk" jdkName="Python 3.7 (pythue)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
</component> </component>
<component name="TestRunnerService"> <component name="TestRunnerService">

View File

@@ -1,7 +1,17 @@
::: => { ::: => {
~ "\g<0>" ~ '\g<0>'
/[aeiou]/ ::= '_' '\g<0>_'=> {
/[^aeiou_\W]/ ::= ':' /0_/ ::= '1'
/01_/ ::= '10'
/11_/ ::= '1_0'
/^1_/ ::= '10'
}
}
/_:/ ::= [~ "a" ":"] ::: => {
} ~ '\g<0>'
/[aei]/ ::= ~ 'aei'
/[ou]/ ::= ~ 'ou'
/[aeiou]/ ::= '_'
}

61
thue/core.py Normal file
View File

@@ -0,0 +1,61 @@
import re
import thue.parser
class Context:
def __init__(self, string, match=None):
self.string = self.match = None
self.set(string, match)
def enter(self):
return Context(self.string, self.match)
def set(self, string, match=None):
if match is None:
match = re.match(r'^.*$', string)
self.string = string
self.match = match
def exit(self, ctx):
diff = self.string != ctx.string
self.string = ctx.string
self.match = ctx.match
return diff
def expand(self, fmt):
self.match = thue.parser.ALL_PAT.match(self.string)
self.string = self.match.expand(fmt)
def __str__(self):
return f'Ctx[{self.string!r} {self.match[0]!r} {self.match.groups()}]'
class Production:
fields = ()
def apply_local(self, local):
pass
def apply(self, ctx):
local = ctx.enter()
self.apply_local(local)
return ctx.exit(local)
def __str__(self):
field_list = ' '.join(map(str, self.fields))
return f'{type(self)}[{field_list}]'
class Program(Production):
def __init__(self, prod):
self.prod = prod
self.fields = prod,
def apply_local(self, local):
self.prod.apply(local)
def run(self, init=''):
ctx = Context(init)
self.prod.apply(ctx)
return ctx.string

View File

@@ -3,6 +3,7 @@ import re
import lark import lark
from lark import Lark from lark import Lark
import thue.core
import thue.prods import thue.prods
grammar = r''' grammar = r'''
@@ -87,7 +88,7 @@ class ProductionTransformer(lark.Transformer):
def program(self, prods): def program(self, prods):
suite, = prods suite, = prods
return thue.prods.Program(suite) return thue.core.Program(suite)
THUE_TRANSFORMER = ProductionTransformer() THUE_TRANSFORMER = ProductionTransformer()

View File

@@ -1,160 +1,88 @@
import re import re
import thue.parser import thue.core
class Context: class Literal(thue.core.Production):
def __init__(self, string, match=None):
if match is None:
match = re.match(r'^.*$', string)
self.string = string
self.match = match
def enter(self):
return Context(self.string, self.match)
def exit(self, ctx):
diff = self.string != ctx.string
self.string = ctx.string
self.match = ctx.match
return diff
def expand(self, fmt):
self.match = thue.parser.ALL_PAT.match(self.string)
self.string = self.match.expand(fmt)
def __str__(self):
return f'Ctx[{self.string!r} {self.match[0]!r} {self.match.groups()}]'
class Literal:
def __init__(self, fmt): def __init__(self, fmt):
self.fmt = fmt self.fmt = fmt
self.fields = fmt,
def apply(self, ctx): def apply_local(self, local):
ctx_ = ctx.enter() local.expand(self.fmt)
ctx_.expand(self.fmt)
return ctx.exit(ctx_)
def __str__(self):
return f'Literal[{self.fmt}]'
class Full: class Full(thue.core.Production):
def __init__(self, lhs, rhs): def __init__(self, lhs, rhs):
self.lhs = lhs self.lhs = lhs
self.rhs = rhs self.rhs = rhs
self.fields = (lhs, '=>', rhs)
def apply(self, ctx): def apply_local(self, local):
ctx_ = ctx.enter() self.lhs.apply(local)
self.lhs.apply(ctx_) self.rhs.apply(local)
self.rhs.apply(ctx_)
return ctx.exit(ctx_)
def __str__(self):
return f'Full[{self.lhs} => {self.rhs}]'
class Partial: class Partial(thue.core.Production):
def __init__(self, reg, rhs): def __init__(self, reg, rhs):
self.reg = reg self.reg = reg
self.pat = re.compile(reg) self.pat = re.compile(reg)
self.rhs = rhs self.rhs = rhs
self.fields = reg, '::=', rhs
def apply_local(self, local):
match = self.pat.search(local.string)
if not match:
return
sub = thue.core.Context(match[0], match)
self.rhs.apply(sub)
local.string = local.string[:match.start()] + sub.string + local.string[match.end():]
class Input(thue.core.Production):
def apply_local(self, local):
local.set(input())
class Output(thue.core.Production):
def __init__(self, prod):
self.prod = prod
self.fields = prod,
def apply(self, ctx): def apply(self, ctx):
match = self.pat.search(ctx.string) local = ctx.enter()
self.prod.apply(local)
if match: print(local.string)
inner = Context(match[0], match)
self.rhs.apply(inner)
inner.string = ctx.string[:match.start()] + inner.string + ctx.string[match.end():]
return ctx.exit(inner)
return False
def __str__(self):
return f'Part[{self.reg} ::= {self.rhs}]'
class Input: class Continual(thue.core.Production):
def apply(self, ctx): def __init__(self, prod):
ctx_ = ctx.enter() self.prod = prod
ctx_.string = input() self.fields = prod,
ctx_.match = thue.parser.ALL_PAT.match(ctx_.string)
return ctx.exit(ctx_)
def __str__(self): def apply_local(self, local):
return 'Input' while self.prod.apply(local):
pass
class Output: class Suite(thue.core.Production):
def __init__(self, prods):
self.prods = prods
self.fields = prods
def apply_local(self, local):
for prod in self.prods:
if prod.apply(local):
break
class Singular(thue.core.Production):
def __init__(self, prod): def __init__(self, prod):
self.prod = prod self.prod = prod
def apply(self, ctx): self.fields = prod,
_ctx = ctx.enter()
self.prod.apply(_ctx)
print(_ctx.string)
return False
def __str__(self): def apply_local(self, local):
return f'Output[{self.prod}]' self.prod.apply(local)
class Suite:
def __init__(self, prods, ctx=None):
if ctx is None:
ctx = Context('')
self.prods = prods
self.ctx = ctx
def apply(self, ctx):
ctx_ = ctx.enter()
for prod in self.prods:
if prod.apply(ctx_):
break
return ctx.exit(ctx_)
def __str__(self):
prod_list = ' '.join(map(str, self.prods))
return f'Suite[{prod_list}]'
class Continual:
def __init__(self, suite):
self.suite = suite
def apply(self, ctx):
res = False
while self.suite.apply(ctx):
res = True
return res
def __str__(self):
return f'Continual[{self.suite}]'
class Singular:
def __init__(self, suite):
self.suite = suite
def apply(self, ctx):
self.suite.apply(ctx)
def __str__(self):
return f'Singular[{self.suite}]'
class Program:
def __init__(self, suite):
self.suite = suite
def run(self, init=''):
ctx = Context(init)
self.suite.apply(ctx)
return ctx.string
def __str__(self):
return f'Program[{self.suite}]'