From 7ebcc1eb091ae2dd03fec82595519c3ed9c07648 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 28 Oct 2018 00:04:24 -0400 Subject: [PATCH] contexts and backreferences working --- .idea/misc.xml | 2 +- .idea/thue.iml | 2 +- rethue.py | 49 ----------- sub.py | 231 +++++++++++++++++++++++++++++++++++++++++++++++++ testing.ret | 1 + 5 files changed, 234 insertions(+), 51 deletions(-) delete mode 100644 rethue.py create mode 100644 sub.py create mode 100644 testing.ret diff --git a/.idea/misc.xml b/.idea/misc.xml index 06aeaca..e0595e7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/.idea/thue.iml b/.idea/thue.iml index 85c7612..b9b1fff 100644 --- a/.idea/thue.iml +++ b/.idea/thue.iml @@ -4,7 +4,7 @@ - + diff --git a/rethue.py b/rethue.py deleted file mode 100644 index d15ab9b..0000000 --- a/rethue.py +++ /dev/null @@ -1,49 +0,0 @@ -from lark import Lark - -grammar = r''' -suite: prod* - -prod: _named_prod - -_named_prod: _direct_prod | alias -_direct_prod: _compound_prod | _rule_prod | _literal_prod | _abstract_prod -_abstract_prod: output -_compound_prod: cont | sing -_rule_prod: full | part -_literal_prod: lit | ref - -cont: "{" suite "}" // continual production -sing: "[" suite "]" // singular production - -alias: ref "=" prod // production alias -full: _direct_prod "=>" prod // full application -part: ctx "::=" prod // partial application - -output: "~" prod - -lit: STRING -ref: CNAME -ctx: REGEX - -CNAME: /[a-z_][a-z0-9_]*/i -STRING: /(r)?(['"])(.*?)(?" prod // full application +part : ctx "::=" prod // partial application +ref : name // production reference + +lit : STRING // literal production +name : CNAME // named production + +ctx : REGEX + +CNAME : /[a-z_][a-z0-9_]*/i +STRING: /(r)?(['"])(.*?)(? {self.rhs}]' + + +class Partial: + def __init__(self, reg, rhs): + self.reg = reg + self.pat = re.compile(reg) + self.rhs = rhs + + def apply(self, ctx): + match = self.pat.search(ctx.string) + + if match: + 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 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}]' + + +STRING_PAT = re.compile(r'''(r)?(['"])(.*?)(? /(.*)\s+(.*)/ ::= '\g<0> \2 \1' \ No newline at end of file