def bnf(cls): # @formatter:off a = optimize(Name @ "name" + C('cast').optional @ "cast" + (C('as') + Name @ "new_prefix").optional + C(':=') + C('|').optional + Str.one_or_more @ "lexer_factors") b = optimize( V("keyword") @ "keyword" + Name @ "name" + C(':=') + C("|") + Str.one_or_more @ "lexer_factors") return a | b
def delay(): nonlocal atom atom = atom() def ret(): if rev: return ~atom if one_or_more: return atom.one_or_more if zero_or_more: return atom.unlimited if interval: if len(interval) is 1: least = int(interval[0].value) most = -1 else: least, most = map(lambda _: int(_.value), interval) return atom.repeat(least, most) if guard: guard_fn = state.data.namespace[guard.value] guard_fn.name = guard.value return _Atom.Guard(atom, guard_fn) return atom ret: Parser = ret() if bind: name: str = bind.value if is_seq: # noinspection PyTypeChecker ret = ret >> name else: ret = ret @ name return optimize(ret)
def bnf(cls): # @formatter:off return optimize( C('(') + Or @ "or_" + C(')') | C('[') + Or @ "optional" + C(']') | Name @ "name" | Str @ "str")
def bnf(cls): # @formatter:off return optimize(( (C("[") + Name @ "language" + C("]")).optional + C("import") | C("pyimport") @ "python") + Name @ "head" + (C('.') + (C('*') | Name >> "tail")).unlimited + C('.') + C('[') + (C('*') | Name.unlimited @ "import_items") + C(']'))
def bnf(cls): # @formatter:off a = optimize( C('~') @ "rev" + Primitive @ "atom" | Primitive @ "atom" + (C('+') @ "one_or_more" | C('*') @ "zero_or_more" | C('{') + (Number(1, 2) @ "interval" | Name @ "guard") + C('}')).optional) left_assign = optimize(Name @ "bind" + C("=") | Name @ "bind" + C("<<") @ "is_seq") + a right_assign = a + optimize( (C('as') + Name @ "bind" | C("to") + C('[') @ "is_seq" + Name @ "bind" + C("]")).optional) return optimize(left_assign | right_assign)
def test_optimize(): from rbnf.core.ParserC import Literal from rbnf.core.Optimize import optimize AB = Literal.V("a") + Literal.V("b") AC = Literal.V("a") + Literal.V("c") AB_AC = AB | AC assert optimize(AB_AC), Literal.V("a") == (Literal.V("b") | Literal.V("c"))
_ = Atom.Any C = Literal.C V = Literal.V N = Literal.N def rewrite(state: State) -> Named: ctx = state.ctx name = ctx['tag1'].value return Named(name, Nested(tuple(ctx.get('subs', ())))) def constraint(tokenizers: Sequence['Tokenizer'], state: State): context = state.ctx if 'tag2' not in context: return True return context["tag1"].value == context["tag2"].value language_xml = {} XML = Atom.Named("XML") # @formatter:off imp_xml = optimize(C('<') + Name @ "tag1" + C('>') + (XML | ~(C('<') + C('/') + Name + C('>')))(0, -1) @ "subs" + C('<') + C('/') + Name @ "tag2" + C('>') | C('<') + Name @ "tag1" + C('/') + C('>')), None, constraint, rewrite # @formatter:on language_xml[XML[1]] = imp_xml
def bnf(cls): return optimize( C(cls.__name__.lower()) @ "sign" + CodeItem.one_or_more @ "expr")
def bnf(cls): return optimize(END.unlimited + (Statement + END.unlimited).unlimited)
def bnf(cls): # @formatter:off return optimize(Name @ "name" + C('::=') + C('|').optional + Or @ "impl" + When.optional @ "when" + With.optional @ "fail_if" + Rewrite.optional @ "rewrite")
def bnf(cls): return optimize( C("ignore") + C('[') + Name.one_or_more @ "names" + C(']'))
def call(): return optimize(f())
def bnf(cls): return optimize(And @ "head" + (C('|') + (And >> "tail")).unlimited)
def bnf(cls): return optimize((C('rewrite') | C('->')) @ "sign" + CodeItem.one_or_more @ "expr")