@meta.add_method(node.Node)<EOL>def walk(self, lc: state.LivingContext, user_data=None, parent=None):

global _cacheid<EOL>if parent is None:<EOL><INDENT>parent = self<EOL><DEDENT>if hasattr(self, '<STR_LIT>') and not isinstance(self, node.ListNode):<EOL><INDENT>for k in sorted(vars(self).keys()):<EOL><INDENT>print("<STR_LIT>" % (k, id(getattr(self, k))))<EOL>walk(getattr(self, k), lc, user_data, self)<EOL>lc.checkAttr(k, self)<EOL>lc.checkEventExpr()<EOL>lc.doSubEvent()<EOL><DEDENT><DEDENT>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>for k in sorted(self.keys()):<EOL><INDENT>walk(self[k], lc, user_data, self)<EOL>lc.checkKey(k, self)<EOL>lc.checkEventExpr()<EOL>lc.doSubEvent()<EOL><DEDENT><DEDENT>elif not isinstance(self, str) and hasattr(self, '<STR_LIT>'):<EOL><INDENT>idx = <NUM_LIT:0><EOL>for i in self:<EOL><INDENT>walk(i, lc, user_data, self)<EOL>lc.checkIndice(idx, self)<EOL>idx += <NUM_LIT:1><EOL>lc.checkEventExpr()<EOL>lc.doSubEvent()<EOL><DEDENT><DEDENT>lc.checkType(type(self), self, parent)<EOL>lc.checkValue(self)<EOL>lc.checkEventExpr()<EOL>lc.doResultEvent()<EOL>lc.doResultHook(self, user_data, parent)<EOL>lc.doDefault()<EOL>lc.resetLivingState()<EOL>


ids = id(s)<EOL>uid = len(self.states)<EOL>if ids not in self.states:<EOL><INDENT>self.states[ids] = (uid, s)<EOL><DEDENT>


txt = "<STR_LIT>"<EOL>txt += "<STR_LIT>" % id(self)<EOL>if self.label is not None:<EOL><INDENT>txt += '<STR_LIT>' % (self.label + '<STR_LIT>').replace('<STR_LIT:\n>', '<STR_LIT>')<EOL><DEDENT>txt += "<STR_LIT>"<EOL>txt += '<STR_LIT>'<EOL>txt += "<STR_LIT>"<EOL>txt += '<STR_LIT>'<EOL>txt += "<STR_LIT>"<EOL>txt += "<STR_LIT>"<EOL>for s in self.states.values():<EOL><INDENT>txt += s[<NUM_LIT:1>].to_dot()<EOL><DEDENT>txt += "<STR_LIT>"<EOL>return txt<EOL>

Provide a '.dot' representation of all State in the register.


with open(fname, '<STR_LIT:w>') as f:<EOL><INDENT>f.write(self.to_dot())<EOL><DEDENT>


cmd = pipes.Template()<EOL>cmd.append('<STR_LIT>' % fname, '<STR_LIT>')<EOL>with cmd.open('<STR_LIT>', '<STR_LIT:w>') as f:<EOL><INDENT>f.write(self.to_dot())<EOL><DEDENT>


infos = fmt.end("<STR_LIT>", [])<EOL>s = fmt.sep('<STR_LIT:U+002CU+0020>', [])<EOL>for ids in sorted(self.states.keys()):<EOL><INDENT>s.lsdata.append(str(ids))<EOL><DEDENT>infos.lsdata.append(fmt.block('<STR_LIT:(>', '<STR_LIT:)>', [s]))<EOL>infos.lsdata.append("<STR_LIT>" + repr(self.events))<EOL>infos.lsdata.append(<EOL>"<STR_LIT>" + repr(list(self.named_events.keys()))<EOL>)<EOL>infos.lsdata.append("<STR_LIT>" + repr(list(self.uid_events.keys())))<EOL>return infos<EOL>

Provide a useful representation of the register.


def nextstate(self, newstate, treenode=None, user_data=None):

if newstate is None:<EOL><INDENT>return self<EOL><DEDENT>if isinstance(newstate, State) and id(newstate) != id(self):<EOL><INDENT>return newstate<EOL><DEDENT>elif isinstance(newstate, StateEvent):<EOL><INDENT>self.state_register.named_events[newstate.name] = True<EOL>return newstate.st<EOL><DEDENT>elif isinstance(newstate, StatePrecond):<EOL><INDENT>return newstate.st<EOL><DEDENT>elif isinstance(newstate, StateHook):<EOL><INDENT>newstate.call(treenode, user_data)<EOL>return newstate.st<EOL><DEDENT>return self<EOL>


if self.wild_value:<EOL><INDENT>return self.nextstate(self.values['<STR_LIT:*>'])<EOL><DEDENT>elif str(v) in self.values:<EOL><INDENT>return self.nextstate(self.values[str(v)])<EOL><DEDENT>return self<EOL>

the str() of Values are stored internally for convenience


<EOL>must_delete = []<EOL>l = len(self.ls)<EOL>for idx, ls in zip(range(l), self.ls):<EOL><INDENT>ids = id(ls[<NUM_LIT:1>].thestate())<EOL>if ids == id(ls[<NUM_LIT:0>]) and (ls[<NUM_LIT:1>].have_finish or not ls[<NUM_LIT:1>].alive):<EOL><INDENT>must_delete.append(idx)<EOL><DEDENT>elif ls[<NUM_LIT:1>].alive:<EOL><INDENT>ls[<NUM_LIT:1>].alive = False<EOL><DEDENT><DEDENT>for delete in reversed(must_delete):<EOL><INDENT>self.ls.pop(delete)<EOL><DEDENT>self.init_all()<EOL>

Only one Living State on the S0 of each StateRegister


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_mod(self, seq, mod):

modstr = self.value(mod)<EOL>if modstr == '<STR_LIT>':<EOL><INDENT>seq.parser_tree = parsing.Complement(seq.parser_tree)<EOL><DEDENT>elif modstr == '<STR_LIT>':<EOL><INDENT>seq.parser_tree = parsing.LookAhead(seq.parser_tree)<EOL><DEDENT>elif modstr == '<STR_LIT:!>':<EOL><INDENT>seq.parser_tree = parsing.Neg(seq.parser_tree)<EOL><DEDENT>elif modstr == '<STR_LIT>':<EOL><INDENT>seq.parser_tree = parsing.Until(seq.parser_tree)<EOL><DEDENT>return True<EOL>

Create a tree.{Complement, LookAhead, Neg, Until}


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_ruleclause_name(self, ns_name, rid) -> bool:

ns_name.parser_tree = parsing.Rule(self.value(rid))<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_rules(self, bnf, r) -> bool:

bnf[r.rulename] = r.parser_tree<EOL>return True<EOL>

Attach a parser tree to the dict of rules


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_rule(self, rule, rn, alts) -> bool:

rule.rulename = self.value(rn)<EOL>rule.parser_tree = alts.parser_tree<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_sequences(self, sequences, cla) -> bool:

if not hasattr(sequences, '<STR_LIT>'):<EOL><INDENT>sequences.parser_tree = cla.parser_tree<EOL><DEDENT>else:<EOL><INDENT>oldnode = sequences<EOL>if isinstance(oldnode.parser_tree, parsing.Seq):<EOL><INDENT>oldpt = list(oldnode.parser_tree.ptlist)<EOL><DEDENT>else:<EOL><INDENT>oldpt = [oldnode.parser_tree]<EOL><DEDENT>oldpt.append(cla.parser_tree)<EOL>sequences.parser_tree = parsing.Seq(*tuple(oldpt))<EOL><DEDENT>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_alt(self, alternatives, alt) -> bool:

if not hasattr(alternatives, '<STR_LIT>'):<EOL><INDENT>if hasattr(alt, '<STR_LIT>'):<EOL><INDENT>alternatives.parser_tree = alt.parser_tree<EOL><DEDENT>else:<EOL><INDENT>alternatives.parser_tree = alt<EOL><DEDENT><DEDENT>else:<EOL><INDENT>oldnode = alternatives<EOL>if isinstance(oldnode.parser_tree, parsing.Alt):<EOL><INDENT>oldpt = list(oldnode.parser_tree.ptlist)<EOL><DEDENT>else:<EOL><INDENT>oldpt = [oldnode.parser_tree]<EOL><DEDENT>oldpt.append(alt.parser_tree)<EOL>alternatives.parser_tree = parsing.Alt(*tuple(oldpt))<EOL><DEDENT>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_read_sqstring(self, sequence, s):

v = self.value(s).strip("<STR_LIT:'>")<EOL>if len(v) > <NUM_LIT:1>:<EOL><INDENT>sequence.parser_tree = parsing.Text(v)<EOL>return True<EOL><DEDENT>sequence.parser_tree = parsing.Char(v)<EOL>return True<EOL>

Add a read_char/read_text primitive from simple quote string


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_read_dqstring(self, sequence, s):

v = self.value(s).strip('<STR_LIT:">')<EOL>if len(v) > <NUM_LIT:1>:<EOL><INDENT>sequence.parser_tree = parsing.Text(v)<EOL>return True<EOL><DEDENT>sequence.parser_tree = parsing.Char(v)<EOL>return True<EOL>

Add a read_char/read_text primitive from a double quote string


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_range(self, sequence, begin, end):

sequence.parser_tree = parsing.Range(self.value(begin).strip("<STR_LIT:'>"),<EOL>self.value(end).strip("<STR_LIT:'>"))<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_rpt(self, sequence, mod, pt):

modstr = self.value(mod)<EOL>if modstr == '<STR_LIT>':<EOL><INDENT>self._stream.restore_context()<EOL>self.diagnostic.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>",<EOL>error.LocationInfo.from_stream(self._stream, is_error=True)<EOL>)<EOL>raise self.diagnostic<EOL><DEDENT>if modstr == '<STR_LIT:!>':<EOL><INDENT>self._stream.restore_context()<EOL>self.diagnostic.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>",<EOL>error.LocationInfo.from_stream(self._stream, is_error=True)<EOL>)<EOL>raise self.diagnostic<EOL><DEDENT>oldnode = sequence<EOL>sequence.parser_tree = pt.functor(oldnode.parser_tree)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_capture(self, sequence, cpt):

cpt_value = self.value(cpt)<EOL>sequence.parser_tree = parsing.Capture(cpt_value, sequence.parser_tree)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_bind(self, sequence, cpt):

cpt_value = self.value(cpt)<EOL>sequence.parser_tree = parsing.Bind(cpt_value, sequence.parser_tree)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_subsequence(self, sequence, subsequence):

sequence.parser_tree = subsequence.parser_tree<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_optional(self, repeat):

repeat.functor = parsing.RepOptional<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_0N(self, repeat):

repeat.functor = parsing.Rep0N<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_1N(self, repeat):

repeat.functor = parsing.Rep1N<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_hook(self, sequence, h):

sequence.parser_tree = parsing.Hook(h.name, h.listparam)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def param_num(self, param, n):

param.pair = (int(self.value(n)), int)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def param_str(self, param, s):

param.pair = (self.value(s).strip('<STR_LIT:">'), str)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def param_char(self, param, c):

param.pair = (self.value(c).strip("<STR_LIT:'>"), str)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def param_id(self, param, i):

param.pair = (self.value(i), parsing.Node)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def hook_name(self, hook, n):

hook.name = self.value(n)<EOL>hook.listparam = []<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def hook_param(self, hook, p):

hook.listparam.append(p.pair)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_directive2(self, sequence, d, s):

sequence.parser_tree = parsing.Directive2(<EOL>d.name,<EOL>d.listparam,<EOL>s.parser_tree<EOL>)<EOL>return True<EOL>


@meta.hook(EBNF, "<STR_LIT>")<EOL>def add_directive(self, sequence, d, s):

if d.name in meta._directives:<EOL><INDENT>the_class = meta._directives[d.name]<EOL>sequence.parser_tree = parsing.Directive(the_class(), d.listparam,<EOL>s.parser_tree)<EOL><DEDENT>elif d.name in meta._decorators:<EOL><INDENT>the_class = meta._decorators[d.name]<EOL>sequence.parser_tree = parsing.Decorator(the_class, d.listparam,<EOL>s.parser_tree)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>" % d.name)<EOL><DEDENT>return True<EOL>


res = None<EOL>try:<EOL><INDENT>res = self.eval_rule('<STR_LIT>')<EOL>if not res:<EOL><INDENT>self.diagnostic.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>" % self._lastRule,<EOL>error.LocationInfo.from_maxstream(self._stream)<EOL>)<EOL>raise self.diagnostic<EOL><DEDENT><DEDENT>except error.Diagnostic as d:<EOL><INDENT>d.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>" % self._lastRule<EOL>)<EOL>raise d<EOL><DEDENT>return res<EOL>

Parse the DSL and provide a dictionnaries of all resulting rules.
Call by the MetaGrammar class.

TODO: could be done in the rules property of parsing.BasicParser???


def __init__(self, content='<STR_LIT>', sname=None):


<EOL>enums = dict(zip(sequential, range(len(sequential))), **named)<EOL>enums['<STR_LIT>'] = copy.copy(enums)<EOL>enums['<STR_LIT>'] = {}<EOL>for key, value in enums.items():<EOL><INDENT>if type(value) is int:<EOL><INDENT>enums['<STR_LIT>'][value] = key<EOL><DEDENT><DEDENT>return type('<STR_LIT>', (), enums)<EOL>


sig = inspect.signature(func)<EOL>types = {}<EOL>for param in sig.parameters.values():<EOL><INDENT>param_type = param.annotation<EOL>if param_type is param.empty or not inspect.isclass(param_type):<EOL><INDENT>continue<EOL><DEDENT>types[param.name] = param_type<EOL>if (param.default is not param.empty and<EOL>not isinstance(param.default, param_type)):<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>".format(<EOL>func=func.__qualname__, arg=param.name)<EOL>)<EOL><DEDENT><DEDENT>def check_type(sig, arg_name, arg_type, arg_value):<EOL><INDENT>if not isinstance(arg_value, arg_type):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>".<EOL>format(func=func.__qualname__, arg=arg_name,<EOL>exp=arg_type.__name__,<EOL>got=type(arg_value).__name__))<EOL><DEDENT><DEDENT>@functools.wraps(func)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>ba = sig.bind(*args, **kwargs)<EOL>for arg_name, arg in ba.arguments.items():<EOL><INDENT>try:<EOL><INDENT>type_ = types[arg_name]<EOL><DEDENT>except KeyError:<EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>param = sig.parameters[arg_name]<EOL>if param.kind == param.VAR_POSITIONAL:<EOL><INDENT>for value in arg:<EOL><INDENT>check_type(sig, arg_name, type_, value)<EOL><DEDENT><DEDENT>elif param.kind == param.VAR_KEYWORD:<EOL><INDENT>for subname, value in arg.items():<EOL><INDENT>check_type(sig, arg_name + '<STR_LIT::>' + subname, type_, value)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>check_type(sig, arg_name, type_, arg)<EOL><DEDENT><DEDENT><DEDENT>result = func(*ba.args, **ba.kwargs)<EOL>return_type = sig.return_annotation<EOL>if (return_type is not sig.empty and<EOL>isinstance(return_type, type) and<EOL>not isinstance(result, return_type)):<EOL><INDENT>raise ValueError(<EOL>'<STR_LIT>'.format(<EOL>func=func.__qualname__, exp=return_type.__name__,<EOL>got=type(result).__name__)<EOL>)<EOL><DEDENT>return result<EOL><DEDENT>return wrapper<EOL>

Decorator to verify arguments and return types.


def set_one(chainmap, thing_name, callobject):

namespaces = reversed(thing_name.split("<STR_LIT:.>"))<EOL>lstname = []<EOL>for name in namespaces:<EOL><INDENT>lstname.insert(<NUM_LIT:0>, name)<EOL>strname = '<STR_LIT:.>'.join(lstname)<EOL>chainmap[strname] = callobject<EOL><DEDENT>

Add a mapping with key thing_name for callobject in chainmap with
        namespace handling.


def wrapper(f):<EOL><INDENT>setattr(cls, f.__name__, f)<EOL>return f<EOL><DEDENT>return wrapper<EOL>


def hook(cls, hookname=None, erase=False):

if not hasattr(cls, '<STR_LIT>'):<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>" % cls.__name__)<EOL><DEDENT>class_hook_list = cls._hooks<EOL>class_rule_list = cls._rules<EOL>def wrapper(f):<EOL><INDENT>nonlocal hookname<EOL>add_method(cls)(f)<EOL>if hookname is None:<EOL><INDENT>hookname = f.__name__<EOL><DEDENT>if not erase and (hookname in class_hook_list or hookname in class_rule_list):<EOL><INDENT>raise TypeError("<STR_LIT>" % hookname)<EOL><DEDENT>if '<STR_LIT:.>' not in hookname:<EOL><INDENT>hookname = '<STR_LIT:.>'.join([cls.__module__, cls.__name__, hookname])<EOL><DEDENT>set_one(class_hook_list, hookname, f)<EOL>return f<EOL><DEDENT>return wrapper<EOL>

Attach a method to a parsing class and register it as a parser hook.

       The method is registered with its name unless hookname is provided.


def rule(cls, rulename=None, erase=False):

if not hasattr(cls, '<STR_LIT>'):<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>" % cls.__name__)<EOL><DEDENT>class_hook_list = cls._hooks<EOL>class_rule_list = cls._rules<EOL>def wrapper(f):<EOL><INDENT>nonlocal rulename<EOL>add_method(cls)(f)<EOL>if rulename is None:<EOL><INDENT>rulename = f.__name__<EOL><DEDENT>if not erase and (rulename in class_hook_list or rulename in class_rule_list):<EOL><INDENT>raise TypeError("<STR_LIT>" % rulename)<EOL><DEDENT>if '<STR_LIT:.>' not in rulename:<EOL><INDENT>rulename = cls.__module__ + '<STR_LIT:.>' + cls.__name__ + '<STR_LIT:.>' + rulename<EOL><DEDENT>set_one(class_rule_list, rulename, f)<EOL>return f<EOL><DEDENT>return wrapper<EOL>

Attach a method to a parsing class and register it as a parser rule.

       The method is registered with its name unless rulename is provided.


global _directives<EOL>class_dir_list = _directives<EOL>def wrapper(f):<EOL><INDENT>nonlocal directname<EOL>if directname is None:<EOL><INDENT>directname = f.__name__<EOL><DEDENT>f.ns_name = directname<EOL>set_one(class_dir_list, directname, f)<EOL>return f<EOL><DEDENT>return wrapper<EOL>

Attach a class to a parsing class and register it as a parser directive.

        The class is registered with its name unless directname is provided.


global _decorators<EOL>class_deco_list = _decorators<EOL>def wrapper(f):<EOL><INDENT>nonlocal directname<EOL>if directname is None:<EOL><INDENT>directname = f.__name__<EOL><DEDENT>f.ns_name = directname<EOL>set_one(class_deco_list, directname, f)<EOL><DEDENT>return wrapper<EOL>

Attach a class to a parsing decorator and register it to the global
decorator list.
The class is registered with its name unless directname is provided


@meta.hook(BasicParser)<EOL>def bind(self, dst: str, src: Node) -> bool:

for m in self.rule_nodes.maps:<EOL><INDENT>for k, v in m.items():<EOL><INDENT>if k == dst:<EOL><INDENT>m[k] = src<EOL>return True<EOL><DEDENT><DEDENT><DEDENT>raise Exception('<STR_LIT>' % dst)<EOL>

Allow to alias a node to another name.

    Useful to bind a node to _ as return of Rule::

        R = [
            __scope__:L [item:I #add_item(L, I]* #bind('_', L)
        ]

    It's also the default behaviour of ':>'


@meta.rule(BasicParser, "<STR_LIT>")<EOL>def read_eof(self) -> bool:

<EOL>return self._stream.index == self._stream.eos_index<EOL>

Returns true if reached end of the stream.


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_eol(self) -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>self.read_char('<STR_LIT:\r>')<EOL>if self.read_char('<STR_LIT:\n>'):<EOL><INDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

Return True if the parser can consume an EOL byte sequence.


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_hex_integer(self) -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>c = self._stream.peek_char<EOL>if c.isdigit() or ('<STR_LIT:a>' <= c.lower() and c.lower() <= '<STR_LIT:f>'):<EOL><INDENT>self._stream.incpos()<EOL>while not self.read_eof():<EOL><INDENT>c = self._stream.peek_char<EOL>if not (c.isdigit() or ('<STR_LIT:a>' <= c.lower() and c.lower() <= '<STR_LIT:f>')):<EOL><INDENT>break<EOL><DEDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

read a hexadecimal number
Read the following BNF rule else return False::

    readHexInteger = [
        [ '0'..'9' | 'a'..'f' | 'A'..'F' ]+
    ]


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_oct_integer(self) -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>c = self._stream.peek_char<EOL>if c.isdigit() and <NUM_LIT:0> <= int(c) and int(c) <= <NUM_LIT:7>:<EOL><INDENT>self._stream.incpos()<EOL>while not self.read_eof():<EOL><INDENT>c = self._stream.peek_char<EOL>if not (c.isdigit() and <NUM_LIT:0> <= int(c) and int(c) <= <NUM_LIT:7>):<EOL><INDENT>break<EOL><DEDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

read an octal number
Read the following BNF rule else return False::

    readOctInteger = [
        [ '0'..'7' ]+
    ]


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_integer(self) -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>c = self._stream.peek_char<EOL>if c.isdigit():<EOL><INDENT>self._stream.incpos()<EOL>while not self.read_eof():<EOL><INDENT>c = self._stream.peek_char<EOL>if not c.isdigit():<EOL><INDENT>break<EOL><DEDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

read a number
Read following BNF rule else return False::

    readInteger = [
        ['0'..'9']+
    ]


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_identifier(self) -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>c = self._stream.peek_char<EOL>if c.isalpha() or c == '<STR_LIT:_>':<EOL><INDENT>self._stream.incpos()<EOL>while not self.read_eof():<EOL><INDENT>c = self._stream.peek_char<EOL>if not (c.isalpha() or c.isdigit() or c == '<STR_LIT:_>'):<EOL><INDENT>break<EOL><DEDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

read an identifier
Read following BNF rule else return False::

    readIdentifier = [
        ['a'..'z'|'A'..'Z'|'_']['0'..'9'|'a'..'z'|'A'..'Z'|'_']*
    ]


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_cstring(self) -> bool:

self._stream.save_context()<EOL>idx = self._stream.index<EOL>if self.read_char("<STR_LIT>") and self.read_until("<STR_LIT>", "<STR_LIT:\\>"):<EOL><INDENT>txt = self._stream[idx:self._stream.index]<EOL>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

read a double quoted string
Read following BNF rule else return False::

    '"' -> ['\\' #char | ~'\\'] '"'


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_cchar(self) -> bool:<EOL>

Read following BNF rule else return False::

    "'" -> ['\\' #char | ~'\\'] "'"


@meta.rule(Parser, "<STR_LIT>")<EOL>def read_cchar(self) -> bool:

read a quoted string ''
Read following BNF rule else return False::

    "'" -> ['\\' #char | ~'\\'] "'"


@meta.rule(Parser, "<STR_LIT>")<EOL>def scope_nodes(self) -> bool:

return True<EOL>


@property<EOL><INDENT>def _stream(self) -> Stream:<DEDENT>

return self._streams[-<NUM_LIT:1>]<EOL>


@property<EOL><INDENT>def nstream(self) -> int:<DEDENT>

return len(self._streams)<EOL>


@property<EOL><INDENT>def rules(self) -> dict:<DEDENT>

return self._rules<EOL>


if self.rule_nodes is None:<EOL><INDENT>self.rule_nodes = collections.ChainMap()<EOL>self.tag_cache = collections.ChainMap()<EOL>self.id_cache = collections.ChainMap()<EOL><DEDENT>else:<EOL><INDENT>self.rule_nodes = self.rule_nodes.new_child()<EOL>self.tag_cache = self.tag_cache.new_child()<EOL>self.id_cache = self.id_cache.new_child()<EOL><DEDENT>return True<EOL>

Push context variable to store rule nodes.


self.rule_nodes = self.rule_nodes.parents<EOL>self.tag_cache = self.tag_cache.parents<EOL>self.id_cache = self.id_cache.parents<EOL>return True<EOL>

Pop context variable that store rule nodes


id_n = id(n)<EOL>idcache = self.id_cache<EOL>if id_n not in idcache:<EOL><INDENT>return "<STR_LIT>"<EOL><DEDENT>name = idcache[id_n]<EOL>tag_cache = self.tag_cache<EOL>if name not in tag_cache:<EOL><INDENT>raise Exception("<STR_LIT>")<EOL><DEDENT>tag = tag_cache[name]<EOL>k = "<STR_LIT>" % (tag._begin, tag._end)<EOL>valcache = self._streams[-<NUM_LIT:1>].value_cache<EOL>if k not in valcache:<EOL><INDENT>valcache[k] = str(tag)<EOL><DEDENT>return valcache[k]<EOL>


def parsed_stream(self, content: str, name: str=None):

self._streams.append(Stream(content, name))<EOL>

Push a new Stream into the parser.
        All subsequent called functions will parse this new stream,
        until the 'popStream' function is called.


s = self._streams.pop()<EOL>self.clean_tmp(s)<EOL>

Pop the last Stream pushed on to the parser stack.


<EOL>self.tag_cache[name] = Tag(self._stream, self._stream.index)<EOL>return True<EOL>

Save the current index under the given name.


self.tag_cache[name].set_end(self._stream.index)<EOL>return True<EOL>

Extract the string between saved and current index.


return self.tag_cache[name]<EOL>


@classmethod<EOL><INDENT>def set_rules(cls, rules: dict) -> bool:<DEDENT>

cls._rules = cls._rules.new_child()<EOL>for rule_name, rule_pt in rules.items():<EOL><INDENT>if '<STR_LIT:.>' not in rule_name:<EOL><INDENT>rule_name = cls.__module__+ '<STR_LIT:.>' + cls.__name__+ '<STR_LIT:.>' + rule_name<EOL><DEDENT>meta.set_one(cls._rules, rule_name, rule_pt)<EOL><DEDENT>return True<EOL>

Merge internal rules set with the given rules


@classmethod<EOL><INDENT>def set_hooks(cls, hooks: dict) -> bool:<DEDENT>

cls._hooks = cls._hooks.new_child()<EOL>for hook_name, hook_pt in hooks.items():<EOL><INDENT>if '<STR_LIT:.>' not in hook_name:<EOL><INDENT>hook_name = cls.__module__+ '<STR_LIT:.>' + cls.__name__+ '<STR_LIT:.>' + hook_name<EOL><DEDENT>meta.set_one(cls._hooks, hook_name, hook_pt)<EOL><DEDENT>return True<EOL>

Merge internal hooks set with the given hooks


@classmethod<EOL><INDENT>def set_directives(cls, directives: dict) -> bool:<DEDENT>

meta._directives = meta._directives.new_child()<EOL>for dir_name, dir_pt in directives.items():<EOL><INDENT>meta.set_one(meta._directives, dir_name, dir_pt)<EOL>dir_pt.ns_name = dir_name<EOL><DEDENT>return True<EOL>

Merge internal directives set with the given directives.
For working directives, attach it only in the dsl.Parser class


<EOL>n = Node()<EOL>id_n = id(n)<EOL>self.rule_nodes['<STR_LIT:_>'] = n<EOL>self.id_cache[id_n] = '<STR_LIT:_>'<EOL>if name not in self.__class__._rules:<EOL><INDENT>self.diagnostic.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>" % name,<EOL>error.LocationInfo.from_stream(self._stream, is_error=True)<EOL>)<EOL>raise self.diagnostic<EOL><DEDENT>self._lastRule = name<EOL>rule_to_eval = self.__class__._rules[name]<EOL>res = rule_to_eval(self)<EOL>if res:<EOL><INDENT>res = self.rule_nodes['<STR_LIT:_>']<EOL><DEDENT>return res<EOL>


def eval_hook(self, name: str, ctx: list) -> Node:

if name not in self.__class__._hooks:<EOL><INDENT>self.diagnostic.notify(<EOL>error.Severity.ERROR,<EOL>"<STR_LIT>" % name,<EOL>error.LocationInfo.from_stream(self._stream, is_error=True)<EOL>)<EOL>raise self.diagnostic<EOL><DEDENT>self._lastRule = '<STR_LIT:#>' + name<EOL>res = self.__class__._hooks[name](self, *ctx)<EOL>if type(res) is not bool:<EOL><INDENT>raise TypeError("<STR_LIT>" % name)<EOL><DEDENT>return res<EOL>


start = self._stream.index<EOL>stop = start + len(text)<EOL>if stop > self._stream.eos_index:<EOL><INDENT>return False<EOL><DEDENT>return self._stream[self._stream.index:stop] == text<EOL>

Same as readText but doesn't consume the stream.


if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.incpos()<EOL>return True<EOL>


if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>if c == self._stream.peek_char:<EOL><INDENT>self._stream.incpos()<EOL>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

Consume the c head byte, increment current index and return True
else return False. It use peekchar and it's the same as '' in BNF.


def read_until(self, c: str, inhibitor='<STR_LIT:\\>') -> bool:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>while not self.read_eof():<EOL><INDENT>if self.peek_char(inhibitor):<EOL><INDENT>self.one_char()<EOL>self.one_char()<EOL><DEDENT>if self.peek_char(c):<EOL><INDENT>self._stream.incpos()<EOL>return self._stream.validate_context()<EOL><DEDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.restore_context()<EOL>

Consume the stream while the c byte is not read, else return false
ex : if stream is " abcdef ", read_until("d"); consume "abcd".


if self.read_eof():<EOL><INDENT>return True<EOL><DEDENT>self._stream.save_context()<EOL>while not self.read_eof():<EOL><INDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL>

Consume all the stream. Same as EOF in BNF.


if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>self._stream.save_context()<EOL>if self.peek_text(text):<EOL><INDENT>self._stream.incpos(len(text))<EOL>return self._stream.validate_context()<EOL><DEDENT>return self._stream.restore_context()<EOL>

Consume a strlen(text) text at current position in the stream
else return False.
Same as "" in BNF
ex : read_text("ls");.


def read_range(self, begin: str, end: str) -> int:

if self.read_eof():<EOL><INDENT>return False<EOL><DEDENT>c = self._stream.peek_char<EOL>if begin <= c <= end:<EOL><INDENT>self._stream.incpos()<EOL>return True<EOL><DEDENT>return False<EOL>

Consume head byte if it is >= begin and <= end else return false
Same as 'a'..'z' in BNF


return True<EOL>


self._stream.save_context()<EOL>if not self.read_eof() and self._stream.peek_char in "<STR_LIT>":<EOL><INDENT>while (not self.read_eof()<EOL>and self._stream.peek_char in "<STR_LIT>"):<EOL><INDENT>self._stream.incpos()<EOL><DEDENT>return self._stream.validate_context()<EOL><DEDENT>return self._stream.validate_context()<EOL>


def push_ignore(self, ignoreConvention) -> bool:

self._ignores.append(ignoreConvention)<EOL>return True<EOL>


self._ignores.pop()<EOL>return True<EOL>


def __init__(self, convention: str="<STR_LIT>"):

self.convention = convention<EOL>

TODO: Could be better to implement Directive thru functors???


if idx >= <NUM_LIT:0>:<EOL><INDENT>idx = (idx * <NUM_LIT:2>) + <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>idx = len(self.ptlist) - ((idx + <NUM_LIT:1>) * <NUM_LIT:2>) - <NUM_LIT:2><EOL><DEDENT>return self.ptlist[idx]<EOL>


def do_call(self, parser: BasicParser) -> Node:

valueparam = []<EOL>for v, t in self.param:<EOL><INDENT>if t is Node:<EOL><INDENT>valueparam.append(parser.rule_nodes[v])<EOL><DEDENT>elif type(v) is t:<EOL><INDENT>valueparam.append(v)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError(<EOL>"<STR_LIT>".format(t, type(v)))<EOL><DEDENT><DEDENT>if not self.checkParam(self.decorator_class, valueparam):<EOL><INDENT>return False<EOL><DEDENT>decorator = self.decorator_class(*valueparam)<EOL>global _decorators<EOL>_decorators.append(decorator)<EOL>res = self.pt(parser)<EOL>_decorators.pop()<EOL>return res<EOL>

The Decorator call is the one that actually pushes/pops
the decorator in the active decorators list (parsing._decorators)


@property<EOL><INDENT>def index(self) -> int:<DEDENT>

return self._index<EOL>


@property<EOL><INDENT>def lineno(self) -> int:<DEDENT>

return self._lineno<EOL>


@property<EOL><INDENT>def col_offset(self) -> int:<DEDENT>

return self._col_offset<EOL>

The current column offset of the cursor.


@property<EOL><INDENT>def position(self) -> Position:<DEDENT>

return Position(self._index, self._lineno, self._col_offset)<EOL>


@property<EOL><INDENT>def max_readed_position(self) -> Position:<DEDENT>

return Position(self._maxindex, self._maxline, self._maxcol)<EOL>

The index of the deepest character readed.


self._index += <NUM_LIT:1><EOL>self._col_offset += <NUM_LIT:1><EOL>if self._index > self._maxindex:<EOL><INDENT>self._maxindex = self._index<EOL>self._maxcol = self._col_offset<EOL>self._maxline = self._lineno<EOL><DEDENT>


self._col_offset -= <NUM_LIT:1><EOL>self._index -= <NUM_LIT:1><EOL>

Puts the cursor on the previous character.


self._eol.append(self.position)<EOL>self._lineno += <NUM_LIT:1><EOL>self._col_offset = <NUM_LIT:0><EOL>


<EOL>if len(self._eol) > <NUM_LIT:0>:<EOL><INDENT>self.position = self._eol.pop()<EOL><DEDENT>


@property<EOL><INDENT>def name(self) -> int:<DEDENT>

return self._name<EOL>


@property<EOL><INDENT>def eos_index(self) -> int:<DEDENT>

return self._len<EOL>


return self._cursor.position.index<EOL>


return self._cursor.lineno<EOL>


return self._cursor.col_offset<EOL>


@property<EOL><INDENT>def peek_char(self) -> str:<DEDENT>

return self._content[self._cursor.index]<EOL>


@property<EOL><INDENT>def last_readed_line(self) -> str:<DEDENT>

mpos = self._cursor.max_readed_position<EOL>mindex = mpos.index<EOL>prevline = mindex - <NUM_LIT:1> if mindex == self.eos_index else mindex<EOL>while prevline >= <NUM_LIT:0> and self._content[prevline] != '<STR_LIT:\n>':<EOL><INDENT>prevline -= <NUM_LIT:1><EOL><DEDENT>nextline = mindex<EOL>while nextline < self.eos_index and self._content[nextline] != '<STR_LIT:\n>':<EOL><INDENT>nextline += <NUM_LIT:1><EOL><DEDENT>last_line = self._content[prevline + <NUM_LIT:1>:nextline]<EOL>return last_line<EOL>

Usefull string to compute error message.


def incpos(self, length: int=<NUM_LIT:1>) -> int:

if length < <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>i = <NUM_LIT:0><EOL>while (i < length):<EOL><INDENT>if self._cursor.index < self._len:<EOL><INDENT>if self.peek_char == '<STR_LIT:\n>':<EOL><INDENT>self._cursor.step_next_line()<EOL><DEDENT>self._cursor.step_next_char()<EOL><DEDENT>i += <NUM_LIT:1><EOL><DEDENT>return self._cursor.index<EOL>

Increment the cursor to the next character.


self._contexts.append(self._cursor.position)<EOL>return True<EOL>


self._cursor.position = self._contexts.pop()<EOL>return False<EOL>


del self._contexts[-<NUM_LIT:1>]<EOL>return True<EOL>


res = ast<EOL>typemap = {DictNode, ListNode, TupleNode}<EOL>if type(ast) is dict:<EOL><INDENT>res = DictNode(ast)<EOL><DEDENT>elif type(ast) is list:<EOL><INDENT>res = ListNode(ast)<EOL><DEDENT>elif type(ast) is tuple:<EOL><INDENT>res = TupleNode(ast)<EOL><DEDENT>if hasattr(res, '<STR_LIT>'):<EOL><INDENT>for k, v in res.items():<EOL><INDENT>res[k] = normalize(v)<EOL><DEDENT><DEDENT>elif hasattr(res, '<STR_LIT>'):<EOL><INDENT>for idx, v in zip(range(len(res)), res):<EOL><INDENT>res[idx] = normalize(v)<EOL><DEDENT><DEDENT>if type(res) not in typemap and hasattr(res, '<STR_LIT>'):<EOL><INDENT>subattr = vars(res)<EOL>for k, v in subattr.items():<EOL><INDENT>setattr(res, k, normalize(v))<EOL><DEDENT><DEDENT>return res<EOL>

Normalize an AST nodes.

all builtins containers are replace by referencable subclasses


def check(self, ndict: dict, info="<STR_LIT>") -> bool:

def iscycle(thing, ndict: dict, info: str) -> bool:<EOL><INDENT>idthing = id(thing)<EOL>ndict[info] = idthing<EOL>if idthing not in ndict:<EOL><INDENT>ndict[idthing] = "<STR_LIT>" % (type(thing), info)<EOL>return False<EOL><DEDENT>else:<EOL><INDENT>ndict[idthing] += "<STR_LIT>" % (type(thing), info)<EOL>return True<EOL><DEDENT><DEDENT>def recurs(thing, ndict: dict, info: str) -> bool:<EOL><INDENT>if not iscycle(thing, ndict, info):<EOL><INDENT>res = False<EOL>if isinstance(thing, list):<EOL><INDENT>idx = <NUM_LIT:0><EOL>for i in thing:<EOL><INDENT>res |= recurs(i, ndict, "<STR_LIT>" % (info, idx))<EOL>idx += <NUM_LIT:1><EOL><DEDENT><DEDENT>elif isinstance(thing, Node):<EOL><INDENT>res |= thing.check(ndict, info)<EOL><DEDENT>elif isinstance(thing, dict):<EOL><INDENT>for k, v in thing.items():<EOL><INDENT>res |= recurs(v, ndict, "<STR_LIT>" % (info, k))<EOL><DEDENT><DEDENT>return res<EOL><DEDENT>return True<EOL><DEDENT>if len(ndict) == <NUM_LIT:0>:<EOL><INDENT>ndict['<STR_LIT>'] = id(self)<EOL>info = '<STR_LIT>'<EOL><DEDENT>if not iscycle(self, ndict, info):<EOL><INDENT>res = False<EOL>if len(self) > <NUM_LIT:0>:<EOL><INDENT>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>keys = list(self.keys())<EOL>for k in keys:<EOL><INDENT>ndict["<STR_LIT:[>" + repr(k) + "<STR_LIT:]>"] = id(self[k])<EOL>res |= recurs(self[k], ndict, "<STR_LIT>" % (info, k))<EOL><DEDENT><DEDENT><DEDENT>keys = list(vars(self).keys())<EOL>for k in keys:<EOL><INDENT>ndict["<STR_LIT:.>" + k] = id(getattr(self, k))<EOL>res |= recurs(getattr(self, k), ndict, "<STR_LIT>" % (info, k))<EOL><DEDENT>return res<EOL><DEDENT>return True<EOL>

Debug method, help detect cycle and/or
other incoherence in a tree of Node


self.__class__ = othernode.__class__<EOL>self.clean()<EOL>if len(othernode) > <NUM_LIT:0>:<EOL><INDENT>for k, v in othernode.items():<EOL><INDENT>self[k] = v<EOL><DEDENT><DEDENT>for k, v in vars(othernode).items():<EOL><INDENT>setattr(self, k, v)<EOL><DEDENT>

allow to completly mutate the node into any subclasses of Node


tmp = self<EOL>while tmp is not None:<EOL><INDENT>yield tmp.data<EOL>tmp = tmp.next<EOL><DEDENT>


tmp = self<EOL>while tmp is not None:<EOL><INDENT>yield tmp.data<EOL>tmp = tmp.prev<EOL><DEDENT>


def from_string(bnf: str, entry=None, *optional_inherit) -> Grammar:

inherit = [Grammar] + list(optional_inherit)<EOL>scope = {'<STR_LIT>': bnf, '<STR_LIT>': entry}<EOL>return build_grammar(tuple(inherit), scope)<EOL>


def from_file(fn: str, entry=None, *optional_inherit) -> Grammar:

import os.path<EOL>if os.path.exists(fn):<EOL><INDENT>f = open(fn, '<STR_LIT:r>')<EOL>bnf = f.read()<EOL>f.close()<EOL>inherit = [Grammar] + list(optional_inherit)<EOL>scope = {'<STR_LIT>': bnf, '<STR_LIT>': entry, '<STR_LIT:source>': fn}<EOL>return build_grammar(tuple(inherit), scope)<EOL><DEDENT>raise Exception("<STR_LIT>")<EOL>


def after_parse(self, node: parsing.Node) -> parsing.Node:

return node<EOL>

If you want to do some stuff after parsing, overload this...


def parse(self, source: str=None, entry: str=None) -> parsing.Node:

self.from_string = True<EOL>if source is not None:<EOL><INDENT>self.parsed_stream(source)<EOL><DEDENT>if entry is None:<EOL><INDENT>entry = self.entry<EOL><DEDENT>if entry is None:<EOL><INDENT>raise ValueError("<STR_LIT>".format(<EOL>self.__class__.__name__))<EOL><DEDENT>return self._do_parse(entry)<EOL>


def parse_file(self, filename: str, entry: str=None) -> parsing.Node:

self.from_string = False<EOL>import os.path<EOL>with open(filename, '<STR_LIT:r>') as f:<EOL><INDENT>self.parsed_stream(f.read(), os.path.abspath(filename))<EOL><DEDENT>if entry is None:<EOL><INDENT>entry = self.entry<EOL><DEDENT>if entry is None:<EOL><INDENT>raise ValueError("<STR_LIT>".format(<EOL>self.__class__.__name__))<EOL><DEDENT>return self._do_parse(entry)<EOL>


return False<EOL>

False in parser. Go to alternative...

example::

    R = [
        #false | R2
    ]


return True<EOL>

True in parser. Do nothing

example::

    R = [
        R2 | #true
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def pred_eq(self, n, val):

v1 = n.value<EOL>v2 = val<EOL>if hasattr(val, '<STR_LIT:value>'):<EOL><INDENT>v2 = val.value<EOL><DEDENT>if isinstance(v1, int) and not isinstance(v2, int):<EOL><INDENT>return v1 == int(v2)<EOL><DEDENT>return v1 == v2<EOL>

Test if a node set with setint or setstr equal a certain value

example::

    R = [
        __scope__:n
        ['a' #setint(n, 12) | 'b' #setint(n, 14)]
        C
        [#eq(n, 12) D]
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def pred_neq(self, n, val):

v1 = n.value<EOL>v2 = val<EOL>if hasattr(val, '<STR_LIT:value>'):<EOL><INDENT>v2 = val.value<EOL><DEDENT>if isinstance(v1, int) and not isinstance(v2, int):<EOL><INDENT>return v1 != int(v2)<EOL><DEDENT>return v1 != v2<EOL>

Test if a node set with setint or setstr not equal a certain value

example::

    R = [
        __scope__:n
        ['a' #setint(n, 12) | 'b' #setint(n, 14)]
        C
        [#neq(n, 12) D]
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def vars_nodes(self, rest):

print(vars(rest))<EOL>return True<EOL>

Vars one node instance.

example::

    R = [
        In : node #vars(node)
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def echo_nodes(self, *rest):

txt = "<STR_LIT>"<EOL>for thing in rest:<EOL><INDENT>if isinstance(thing, Node):<EOL><INDENT>txt += self.value(thing)<EOL><DEDENT>else:<EOL><INDENT>txt += str(thing)<EOL><DEDENT><DEDENT>print(txt)<EOL>return True<EOL>

Print nodes.

example::

    R = [
        In : node #echo("coucou", 12, node)
    ]


print("<STR_LIT>")<EOL>try:<EOL><INDENT>print("<STR_LIT>")<EOL>for k, v in self.id_cache.items():<EOL><INDENT>print("<STR_LIT>" % (k, v))<EOL><DEDENT>print("<STR_LIT>")<EOL>for k, v in self.tag_cache.items():<EOL><INDENT>print("<STR_LIT>" % (k, v))<EOL><DEDENT>print("<STR_LIT>")<EOL>for k, v in self.rule_nodes.items():<EOL><INDENT>txt = "<STR_LIT>" % (k, id(v))<EOL>if k in self.tag_cache:<EOL><INDENT>tag = self.tag_cache[k]<EOL>txt += "<STR_LIT>" % tag<EOL>k = "<STR_LIT>" % (tag._begin, tag._end)<EOL>if k in self._stream.value_cache:<EOL><INDENT>txt += "<STR_LIT>" % self._stream.value_cache[k]<EOL><DEDENT><DEDENT>print(txt)<EOL><DEDENT><DEDENT>except Exception as err:<EOL><INDENT>print("<STR_LIT>" % err)<EOL><DEDENT>import sys<EOL>sys.stdout.flush()<EOL>return True<EOL>

Dump tag,rule,id and value cache. For debug.

example::

    R = [
        #dump_nodes
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def set_node(self, dst, src):

if not isinstance(src, Node):<EOL><INDENT>dst.value = src<EOL><DEDENT>else:<EOL><INDENT>dst.set(src)<EOL>idsrc = id(src)<EOL>iddst = id(dst)<EOL>if iddst not in self.id_cache:<EOL><INDENT>print("<STR_LIT>" % repr(dst))<EOL>print("<STR_LIT>" % repr(self.rule_nodes))<EOL>print("<STR_LIT>" % repr(self.id_cache))<EOL><DEDENT>if idsrc in self.id_cache:<EOL><INDENT>k = self.id_cache[idsrc]<EOL>k2 = self.id_cache[iddst]<EOL>if k in self.rule_nodes:<EOL><INDENT>self.tag_cache[k2] = self.tag_cache[k]<EOL><DEDENT><DEDENT><DEDENT>return True<EOL>

Basically copy one node to another.
usefull to transmit a node from a terminal
rule as result of the current rule.

example::

    R = [
        In : node #set(_, node)
    ]

here the node return by the rule In is
also the node return by the rule R


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def set_node_as_int(self, dst, src):

dst.value = self.value(src)<EOL>return True<EOL>

Set a node to a value captured from another node

example::

    R = [
        In : node #setcapture(_, node)
    ]


dst.value = int(src)<EOL>return True<EOL>

Set a int literal to a node

example::

    R = [
        In : node #setint(node, 12)
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def set_node_as_str(self, dst, src):

dst.value = src<EOL>return True<EOL>

Set a str literal to a node

example::

    R = [
        In : node #setstr(node, "toto")
    ]


@meta.hook(BasicParser, "<STR_LIT>")<EOL>def get_subnode(self, dst, ast, expr):

dst.value = eval('<STR_LIT>' + expr)<EOL>return True<EOL>

get the value of subnode

example::

    R = [
        __scope__:big  getsomethingbig:>big
        #get(_, big, '.val') // copy big.val into _
    ]


@meta.add_method(functors.SkipIgnore)<EOL>def to_cython(self, genstate) -> fmt.indentable:

return '<STR_LIT:\n>'<EOL>

TODO: A quite important part of C transform... rethink directive/decoration/etc...


@meta.add_method(Scope)<EOL>def to_fmt(self) -> fmt.indentable:

qual = "<STR_LIT>"<EOL>txt = fmt.sep("<STR_LIT:U+0020>", [qual])<EOL>name = self.show_name()<EOL>if name != "<STR_LIT>":<EOL><INDENT>txt.lsdata.append(name)<EOL><DEDENT>if len(self._hsig) > <NUM_LIT:0> or len(self.mapTypeTranslate) > <NUM_LIT:0>:<EOL><INDENT>lsb = []<EOL>if len(self.mapTypeTranslate) > <NUM_LIT:0>:<EOL><INDENT>lsb.append("<STR_LIT>")<EOL>lsb.append(fmt.end("<STR_LIT:\n>", self.mapTypeTranslate.to_fmt()))<EOL><DEDENT>for k in sorted(self._hsig.keys()):<EOL><INDENT>s = self._hsig[k]<EOL>lsb.append(fmt.end("<STR_LIT:\n>", [s.to_fmt()]))<EOL><DEDENT>block = fmt.block("<STR_LIT>", "<STR_LIT>", fmt.tab(lsb))<EOL>txt.lsdata.append(block)<EOL><DEDENT>return txt<EOL>

Return an Fmt representation for pretty-printing


@meta.add_method(Type)<EOL>def to_fmt(self) -> fmt.indentable:

qual = "<STR_LIT:type>"<EOL>txt = fmt.sep("<STR_LIT:U+0020>", [qual])<EOL>txt.lsdata.append(self.show_name())<EOL>if hasattr(self, '<STR_LIT>') and len(self._hsig) > <NUM_LIT:0>:<EOL><INDENT>lsb = []<EOL>for k in sorted(self._hsig.keys()):<EOL><INDENT>s = self._hsig[k]<EOL>lsb.append(fmt.end("<STR_LIT:\n>", [s.to_fmt()]))<EOL><DEDENT>block = fmt.block("<STR_LIT>", "<STR_LIT>", fmt.tab(lsb))<EOL>txt.lsdata.append(block)<EOL><DEDENT>return txt<EOL>


qual = "<STR_LIT>"<EOL>lseval = []<EOL>block = fmt.block("<STR_LIT>", "<STR_LIT>", fmt.tab(lseval))<EOL>txt = fmt.sep("<STR_LIT:U+0020>", [qual, block])<EOL>lseval.append(self._sig.to_fmt())<EOL>if len(self.resolution) > <NUM_LIT:0>:<EOL><INDENT>lsb = []<EOL>for k in sorted(self.resolution.keys()):<EOL><INDENT>s = self.resolution[k]<EOL>if s is not None:<EOL><INDENT>lsb.append(<EOL>fmt.end(<EOL>"<STR_LIT:\n>",<EOL>["<STR_LIT>" % (k, s, s().show_name())]<EOL>)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>lsb.append(fmt.end("<STR_LIT:\n>", ["<STR_LIT>" % (k)]))<EOL><DEDENT><DEDENT>if self._translate_to is not None:<EOL><INDENT>lsb.append("<STR_LIT>")<EOL>lsb.append(self._translate_to.to_fmt())<EOL><DEDENT>if self._variadic_types is not None:<EOL><INDENT>lsb.append("<STR_LIT>")<EOL>arity = self._sig.arity<EOL>for t in self._variadic_types:<EOL><INDENT>lsb.append("<STR_LIT>" % (arity, t))<EOL>arity += <NUM_LIT:1><EOL><DEDENT><DEDENT>lseval.append(fmt.block("<STR_LIT>", "<STR_LIT>", fmt.tab(lsb)))<EOL><DEDENT>return txt<EOL>


@meta.add_method(Translator)<EOL>def to_fmt(self, with_from=False) -> fmt.indentable:

Return a Fmt representation of Translator for pretty-printing


params = "<STR_LIT>"<EOL>txt = fmt.sep("<STR_LIT:U+0020>", ['<STR_LIT>'])<EOL>name = self.show_name()<EOL>if name != "<STR_LIT>":<EOL><INDENT>txt.lsdata.append(name)<EOL><DEDENT>txt.lsdata.append('<STR_LIT>' % self.value)<EOL>txt.lsdata.append('<STR_LIT>' + self.tret)<EOL>return txt<EOL>


params = "<STR_LIT>"<EOL>txt = fmt.sep("<STR_LIT:U+0020>", ['<STR_LIT>'])<EOL>name = self.show_name()<EOL>if name != "<STR_LIT>":<EOL><INDENT>txt.lsdata.append(name)<EOL><DEDENT>txt.lsdata.append('<STR_LIT>' + self.tret)<EOL>return txt<EOL>


params = "<STR_LIT>"<EOL>txt = fmt.sep("<STR_LIT:U+0020>", ['<STR_LIT>'])<EOL>name = self.show_name()<EOL>if name != "<STR_LIT>":<EOL><INDENT>txt.lsdata.append(name)<EOL><DEDENT>tparams = []<EOL>if self.tparams is not None:<EOL><INDENT>tparams = list(self.tparams)<EOL><DEDENT>if self.variadic:<EOL><INDENT>tparams.append('<STR_LIT>')<EOL><DEDENT>params = '<STR_LIT:(>' + "<STR_LIT:U+002CU+0020>".join(tparams) + '<STR_LIT:)>'<EOL>txt.lsdata.append('<STR_LIT>' + params)<EOL>txt.lsdata.append('<STR_LIT>' + self.tret)<EOL>return txt<EOL>


lsb = []<EOL>if len(self._lsig) > <NUM_LIT:0>:<EOL><INDENT>for s in self._lsig:<EOL><INDENT>lsb.append(s.to_fmt())<EOL><DEDENT><DEDENT>block = fmt.block("<STR_LIT:(>", "<STR_LIT:)>", fmt.sep('<STR_LIT:U+002CU+0020>', lsb))<EOL>qual = "<STR_LIT>"<EOL>txt = fmt.sep("<STR_LIT>", [qual, block])<EOL>return txt<EOL>


return repr(self._lsig)<EOL>


return str(self.to_fmt())<EOL>


return self._sig.set_parent(parent)<EOL>


return [self._sig]<EOL>

Make EvalCtx iterable (to update a scope with it)


tret = []<EOL>tparams = []<EOL>for t in self.tret.components:<EOL><INDENT>if t in self.resolution and self.resolution[t] is not None:<EOL><INDENT>tret.append(self.resolution[t]().show_name())<EOL><DEDENT>else:<EOL><INDENT>tret.append(t)<EOL><DEDENT><DEDENT>if hasattr(self, '<STR_LIT>'):<EOL><INDENT>for p in self.tparams:<EOL><INDENT>tp = []<EOL>for t in p.components:<EOL><INDENT>if t in self.resolution and self.resolution[t] is not None:<EOL><INDENT>tp.append(self.resolution[t]().show_name())<EOL><DEDENT>else:<EOL><INDENT>tp.append(t)<EOL><DEDENT><DEDENT>tparams.append("<STR_LIT:U+0020>".join(tp))<EOL><DEDENT>if self.variadic:<EOL><INDENT>if self._variadic_types is None:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>+ "<STR_LIT>"<EOL>)<EOL><DEDENT>for p in self._variadic_types:<EOL><INDENT>tp = []<EOL>for t in p.components:<EOL><INDENT>if (t in self.resolution<EOL>and self.resolution[t] is not None<EOL>):<EOL><INDENT>tp.append(self.resolution[t]().show_name())<EOL><DEDENT>else:<EOL><INDENT>tp.append(t)<EOL><DEDENT><DEDENT>tparams.append("<STR_LIT:U+0020>".join(tp))<EOL><DEDENT><DEDENT><DEDENT>ret = Fun(self.name, "<STR_LIT:U+0020>".join(tret), tparams)<EOL>ret.__class__ = self._sig.__class__<EOL>return ret<EOL>

Compute a signature Using resolution!!!

TODO: discuss of relevance of a final generation for a signature


ret = self<EOL>if parent is not None:<EOL><INDENT>ret = self._sig.set_parent(parent)<EOL>self.resolve()<EOL><DEDENT>elif not hasattr(self, '<STR_LIT>'):<EOL><INDENT>self.parent = None<EOL><DEDENT>return ret<EOL>

When we add a parent (from Symbol), don't forget to resolve.


self._translate_to = translator<EOL>self.resolve()<EOL>

Attach a translator to an EvalCtx to convert output of the function
into another type


def use_variadic_types(self, list_type: [TypeName]):

self._variadic_types = list_type<EOL>self.resolve()<EOL>

Attach a list of types for extra variadic argument of a call


<EOL>t2resolv = []<EOL>if hasattr(self._sig, '<STR_LIT>'):<EOL><INDENT>t2resolv.append(self._sig.tret)<EOL><DEDENT>if hasattr(self._sig, '<STR_LIT>') and self._sig.tparams is not None:<EOL><INDENT>for p in self._sig.tparams:<EOL><INDENT>t2resolv.append(p)<EOL><DEDENT><DEDENT>if self._translate_to is not None:<EOL><INDENT>t2resolv.append(self._translate_to.target)<EOL><DEDENT>if self._variadic_types is not None:<EOL><INDENT>for t in self._variadic_types:<EOL><INDENT>t2resolv.append(t)<EOL><DEDENT><DEDENT>for t in t2resolv:<EOL><INDENT>for c in t.components:<EOL><INDENT>if c not in self.resolution or self.resolution[c] is None:<EOL><INDENT>parent = self.get_parent()<EOL>if parent is not None:<EOL><INDENT>sc = parent.get_by_symbol_name(c)<EOL>if len(sc) == <NUM_LIT:1>:<EOL><INDENT>sc = list(sc.values())[<NUM_LIT:0>]<EOL>if isinstance(sc, EvalCtx):<EOL><INDENT>sc = sc._sig<EOL><DEDENT>rtyp = weakref.ref(sc)<EOL>self.resolution[c] = rtyp<EOL>continue<EOL><DEDENT><DEDENT>self.resolution[c] = None<EOL><DEDENT><DEDENT><DEDENT>

Process the signature and find definition for type.


def get_resolved_names(self, type_name: TypeName) -> list:

if not isinstance(type_name, TypeName):<EOL><INDENT>raise Exception("<STR_LIT>"<EOL>% type(type_name))<EOL><DEDENT>rnames = []<EOL>for name in type_name.components:<EOL><INDENT>if name not in self.resolution:<EOL><INDENT>raise Exception("<STR_LIT>" % name)<EOL><DEDENT>rname = self.resolution[name]<EOL>if rname is not None:<EOL><INDENT>rname = rname().show_name()<EOL><DEDENT>else:<EOL><INDENT>rname = name<EOL><DEDENT>rnames.append(rname)<EOL><DEDENT>return rnames<EOL>

Use self.resolution to subsitute type_name.
Allow to instanciate polymorphic type ?1, ?toto


def set_resolved_name(self, ref: dict, type_name2solve: TypeName,<EOL>type_name_ref: TypeName):

if self.resolution[type_name2solve.value] is None:<EOL><INDENT>self.resolution[type_name2solve.value] = ref[type_name_ref.value]<EOL><DEDENT>

Warning!!! Need to rethink it when global poly type


unq = super().internal_name()<EOL>if self.tret is not None:<EOL><INDENT>unq += "<STR_LIT:_>" + self.tret<EOL><DEDENT>return unq<EOL>


state = self.__dict__.copy()<EOL>del state['<STR_LIT>']<EOL>return state<EOL>


if hasattr(self, '<STR_LIT>') and self.parent is not None:<EOL><INDENT>return self.parent()<EOL><DEDENT>return None<EOL>

Auto deref parent and return the instance.


<EOL>lstparent = [self]<EOL>p = self.get_parent()<EOL>while p is not None:<EOL><INDENT>lstparent.append(p)<EOL>p = p.get_parent()<EOL><DEDENT>return lstparent<EOL>

Return the list of all contained scope from global to local


<EOL>lscope = []<EOL>for scope in reversed(self.get_scope_list()):<EOL><INDENT>if scope.name is not None:<EOL><INDENT>lscope.append(scope.name)<EOL><DEDENT><DEDENT>return lscope<EOL>


return "<STR_LIT:.>".join(self.get_scope_names())<EOL>

Return a convenient name for type checking


unq = "<STR_LIT:_>".join(self.get_scope_names())<EOL>return unq<EOL>


def type_algos(self) -> ('<STR_LIT>',<EOL>'<STR_LIT>', ['<STR_LIT:args>']):

raise Exception(("<STR_LIT>" +<EOL>"<STR_LIT>" +<EOL>"<STR_LIT>") % type(self).__name__)<EOL>

Sub class must return a Tuple of 3 elements:
    - the method to use to infer type.
    - the list of params to used when infer a type.
    - the method to use when feedback a type.

This is useful to connect AST members to generic algo or
to overload some specific semantic for your language.


def infer_type(self, init_scope: Scope=None, diagnostic=None):

<EOL>if not hasattr(self, '<STR_LIT>'):<EOL><INDENT>self.infer_node = InferNode(init_scope)<EOL><DEDENT>elif init_scope is not None:<EOL><INDENT>self.infer_node.scope_node = init_scope<EOL><DEDENT>type_algo = self.type_algos()<EOL>if diagnostic is None and hasattr(self, '<STR_LIT>'):<EOL><INDENT>diagnostic = self.diagnostic<EOL><DEDENT>type_algo[<NUM_LIT:0>](type_algo[<NUM_LIT:1>], diagnostic)<EOL>

Do inference. Write infos into diagnostic object, if this parameter
is not provide and self is a AST (has is own diagnostic object),
use the diagnostic of self.


<EOL>type_algo = self.type_algos()<EOL>if diagnostic is None and hasattr(self, '<STR_LIT>'):<EOL><INDENT>diagnostic = self.diagnostic<EOL><DEDENT>type_algo[<NUM_LIT:2>](diagnostic)<EOL>

Do feedback. Write infos into diagnostic object, if this parameter
is not provide and self is a AST (has is own diagnostic object),
use the diagnostic of self.


def infer_block(self, body, diagnostic=None):

<EOL>for e in body:<EOL><INDENT>e.infer_node = InferNode(parent=self.infer_node)<EOL>e.infer_type(diagnostic=diagnostic)<EOL><DEDENT>

Infer type on block is to type each of is sub-element


def infer_subexpr(self, expr, diagnostic=None):

expr.infer_node = InferNode(parent=self.infer_node)<EOL>expr.infer_type(diagnostic=diagnostic)<EOL>


def infer_id(self, ident, diagnostic=None):

<EOL>defined = self.infer_node.scope_node.get_by_symbol_name(ident)<EOL>if len(defined) > <NUM_LIT:0>:<EOL><INDENT>self.infer_node.scope_node.update(defined)<EOL><DEDENT>else:<EOL><INDENT>diagnostic.notify(<EOL>Severity.ERROR,<EOL>"<STR_LIT>" % self.value,<EOL>self.info<EOL>)<EOL><DEDENT>

Infer type from an ID!
- check if ID is declarated in the scope
- if no ID is polymorphic type


def infer_literal(self, args, diagnostic=None):

literal, t = args<EOL>self.infer_node.scope_node.add(EvalCtx.from_sig(Val(literal, t)))<EOL>

Infer type from an LITERAL!
Type of literal depend of language.
We adopt a basic convention


unq = '<STR_LIT>' + super().internal_name()<EOL>if self.tparams is not None:<EOL><INDENT>unq += "<STR_LIT:_>" + "<STR_LIT:_>".join(self.tparams)<EOL><DEDENT>if self.tret is not None:<EOL><INDENT>unq += "<STR_LIT:_>" + self.tret<EOL><DEDENT>return unq<EOL>


@property<EOL><INDENT>def is_polymorphic(self) -> bool:<DEDENT>

for c in self.components:<EOL><INDENT>if c[<NUM_LIT:0>] == '<STR_LIT:?>':<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Check if one of composed type name is poly


def __init__(self, name: str=None, sig: [Signature]=None,<EOL>state=StateScope.FREE, is_namespace=True):

if name is not None and not isinstance(name, str):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>super().__init__(name)<EOL>self.need_feedback = False<EOL>self.state = state<EOL>self.is_namespace = is_namespace<EOL>self.mapTypeTranslate = MapSourceTranslate()<EOL>self.astTranslatorInjector = None<EOL>self._ntypes = <NUM_LIT:0><EOL>self._nvars = <NUM_LIT:0><EOL>self._nfuns = <NUM_LIT:0><EOL>self._hsig = {}<EOL>if sig is not None:<EOL><INDENT>if isinstance(sig, Signature) or isinstance(sig, Scope):<EOL><INDENT>self.add(sig)<EOL><DEDENT>elif len(sig) > <NUM_LIT:0>:<EOL><INDENT>self.update(sig)<EOL><DEDENT><DEDENT>

Unnamed scope for global scope

        A Scope have basically 3 possibles states:

            FREE: it's a standalone Scope, generally the global Scope
            LINKED: the Scope is related to another Scope for type resolution,
                like compound statement
            EMBEDDED: the Scope was added into another Scope,
                it forwards all 'in' calls...like namespacing

        A Scope could or couldn't act like a namespace.
        All Signature added into a 'namespaced' Scope was prefixed
        by the Scope name.


self.name = name<EOL>lsig = self._hsig.values()<EOL>self._hsig = {}<EOL>for s in lsig:<EOL><INDENT>self._hsig[s.internal_name()] = s<EOL><DEDENT>

You could set the name after construction


n = <NUM_LIT:0><EOL>for s in self._hsig.values():<EOL><INDENT>if type(s).__name__ == '<STR_LIT>':<EOL><INDENT>n += <NUM_LIT:1><EOL><DEDENT><DEDENT>return n<EOL>


n = <NUM_LIT:0><EOL>for s in self._hsig.values():<EOL><INDENT>if hasattr(s, '<STR_LIT>') and s.is_var:<EOL><INDENT>n += <NUM_LIT:1><EOL><DEDENT><DEDENT>return n<EOL>


n = <NUM_LIT:0><EOL>for s in self._hsig.values():<EOL><INDENT>if hasattr(s, '<STR_LIT>') and s.is_fun:<EOL><INDENT>n += <NUM_LIT:1><EOL><DEDENT><DEDENT>return n<EOL>


self._ntypes = self.count_types()<EOL>self._nvars = self.count_vars()<EOL>self._nfuns = self.count_funs()<EOL>


return repr(self._hsig)<EOL>


state = self.__dict__.copy()<EOL>del state['<STR_LIT>']<EOL>return state<EOL>


def __contains__(self, s: Signature) -> bool:

<EOL>from pyrser.type_system.type import Type<EOL>found = False<EOL>txt = "<STR_LIT>"<EOL>if isinstance(s, Signature):<EOL><INDENT>txt = s.internal_name()<EOL><DEDENT>elif isinstance(s, Type):<EOL><INDENT>txt = s.type_name<EOL><DEDENT>elif isinstance(s, str):<EOL><INDENT>txt = s<EOL><DEDENT>found = (txt in self._hsig)<EOL>if not found and self.parent is not None:<EOL><INDENT>if self.state != StateScope.FREE and isinstance(s, Type):<EOL><INDENT>found = (s.type_name in self.parent())<EOL><DEDENT>if self.state == StateScope.EMBEDDED:<EOL><INDENT>found = (txt in self.parent())<EOL><DEDENT><DEDENT>return found<EOL>

check if a Signature or a Type is declared in a Scope


def __ior__(self, sig: list or Scope) -> Scope:

return self.update(sig)<EOL>


def update(self, sig: list or Scope) -> Scope:

values = sig<EOL>if hasattr(sig, '<STR_LIT>'):<EOL><INDENT>values = sig.values()<EOL><DEDENT>for s in values:<EOL><INDENT>if self.is_namespace:<EOL><INDENT>s.set_parent(self)<EOL><DEDENT>if isinstance(s, Scope):<EOL><INDENT>s.state = StateScope.EMBEDDED<EOL><DEDENT>self._hsig[s.internal_name()] = s<EOL><DEDENT>self.__update_count()<EOL>return self<EOL>

Update the Set with values of another Set


return self.union(sig)<EOL>


new = Scope(sig=self._hsig.values(), state=self.state)<EOL>new |= sig<EOL>return new<EOL>

Create a new Set produce by the union of 2 Set


def __iand__(self, sig: Scope) -> Scope:

return self.intersection_update(sig)<EOL>


def intersection_update(self, oset: Scope) -> Scope:

keys = list(self._hsig.keys())<EOL>for k in keys:<EOL><INDENT>if k not in oset:<EOL><INDENT>del self._hsig[k]<EOL><DEDENT>else:<EOL><INDENT>self._hsig[k] = oset.get(k)<EOL><DEDENT><DEDENT>return self<EOL>

Update Set with common values of another Set


return self.intersection(sig)<EOL>


def intersection(self, sig: Scope) -> Scope:

new = Scope(sig=self._hsig.values(), state=self.state)<EOL>new &= sig<EOL>return new<EOL>

Create a new Set produce by the intersection of 2 Set


def __isub__(self, sig: Scope) -> Scope:

return self.difference_update(sig)<EOL>


def difference_update(self, oset: Scope) -> Scope:

keys = list(self._hsig.keys())<EOL>for k in keys:<EOL><INDENT>if k in oset:<EOL><INDENT>del self._hsig[k]<EOL><DEDENT><DEDENT>return self<EOL>


return self.difference(sig)<EOL>


def difference(self, sig: Scope) -> Scope:

new = Scope(sig=self._hsig.values(), state=self.state)<EOL>new -= sig<EOL>return new<EOL>

Create a new Set produce by a Set subtracted by another Set


def __ixor__(self, sig: Scope) -> Scope:

return self.symmetric_difference_update(sig)<EOL>


def symmetric_difference_update(self, oset: Scope) -> Scope:

skey = set()<EOL>keys = list(self._hsig.keys())<EOL>for k in keys:<EOL><INDENT>if k in oset:<EOL><INDENT>skey.add(k)<EOL><DEDENT><DEDENT>for k in oset._hsig.keys():<EOL><INDENT>if k not in skey:<EOL><INDENT>self._hsig[k] = oset.get(k)<EOL><DEDENT><DEDENT>for k in skey:<EOL><INDENT>del self._hsig[k]<EOL><DEDENT>return self<EOL>

Remove common values
            and Update specific values from another Set


return self.symmetric_difference(sig)<EOL>


def symmetric_difference(self, sig: Scope) -> Scope:

new = Scope(sig=self._hsig.values(), state=self.state)<EOL>new ^= sig<EOL>return new<EOL>

Create a new Set with values present in only one Set


if isinstance(it, Scope):<EOL><INDENT>it.state = StateScope.EMBEDDED<EOL><DEDENT>txt = it.internal_name()<EOL>it.set_parent(self)<EOL>if self.is_namespace:<EOL><INDENT>txt = it.internal_name()<EOL><DEDENT>if txt == "<STR_LIT>":<EOL><INDENT>txt = '<STR_LIT:_>' + str(len(self._hsig))<EOL><DEDENT>if txt in self._hsig:<EOL><INDENT>raise KeyError("<STR_LIT>" % txt)<EOL><DEDENT>self._hsig[txt] = it<EOL>self.__update_count()<EOL>return True<EOL>


def remove(self, it: Signature) -> bool:

txt = it.internal_name()<EOL>if txt not in self._hsig:<EOL><INDENT>raise KeyError(it.show_name() + '<STR_LIT>')<EOL><DEDENT>sig = self._hsig[txt]<EOL>if isinstance(sig, Scope):<EOL><INDENT>sig.state = StateScope.LINKED<EOL><DEDENT>del self._hsig[txt]<EOL>return True<EOL>

Remove it but raise KeyError if not found


def discard(self, it: Signature) -> bool:

txt = it.internal_name()<EOL>if txt in self._hsig:<EOL><INDENT>sig = self._hsig[txt]<EOL>if isinstance(sig, Scope):<EOL><INDENT>sig.state = StateScope.LINKED<EOL><DEDENT>del self._hsig[txt]<EOL>return True<EOL><DEDENT>return False<EOL>


self._hsig.clear()<EOL>return True<EOL>


return self._hsig.popitem()<EOL>


return len(self._hsig)<EOL>


if self.state == StateScope.EMBEDDED and self.parent is not None:<EOL><INDENT>return list(self._hsig.values()) + list(self.parent().values())<EOL><DEDENT>else:<EOL><INDENT>return self._hsig.values()<EOL><DEDENT>


return self._hsig.keys()<EOL>


k = sorted(self._hsig.keys())<EOL>return self._hsig[k[<NUM_LIT:0>]]<EOL>

Retrieve the first Signature ordered by mangling descendant


k = sorted(self._hsig.keys())<EOL>return self._hsig[k[-<NUM_LIT:1>]]<EOL>

Retrieve the last Signature ordered by mangling descendant


def get(self, key: str, default=None) -> Signature:

item = default<EOL>if key in self._hsig:<EOL><INDENT>item = self._hsig[key]<EOL><DEDENT>return item<EOL>

Get a signature instance by its internal_name


def get_by_symbol_name(self, name: str) -> Scope:

lst = []<EOL>for s in self.values():<EOL><INDENT>if s.name == name:<EOL><INDENT>lst.append(EvalCtx.from_sig(s))<EOL><DEDENT><DEDENT>if len(lst) == <NUM_LIT:0>:<EOL><INDENT>p = self.get_parent()<EOL>if p is not None:<EOL><INDENT>return p.get_by_symbol_name(name)<EOL><DEDENT><DEDENT>rscope = Scope(sig=lst, state=StateScope.LINKED, is_namespace=False)<EOL>rscope.set_parent(self)<EOL>return rscope<EOL>

Retrieve a Set of all signature by symbol name


def getsig_by_symbol_name(self, name: str) -> Signature:

subscope = self.get_by_symbol_name(name)<EOL>if len(subscope) != <NUM_LIT:1>:<EOL><INDENT>raise KeyError("<STR_LIT>" % name)<EOL><DEDENT>v = list(subscope.values())<EOL>return v[<NUM_LIT:0>]<EOL>

Retrieve the unique Signature of a symbol.
        Fail if the Signature is not unique


def get_by_return_type(self, tname: str) -> Scope:

lst = []<EOL>for s in self.values():<EOL><INDENT>if hasattr(s, '<STR_LIT>') and s.tret == tname:<EOL><INDENT>lst.append(EvalCtx.from_sig(s))<EOL><DEDENT><DEDENT>rscope = Scope(sig=lst, state=StateScope.LINKED, is_namespace=False)<EOL>rscope.set_parent(self)<EOL>return rscope<EOL>

Retrieve a Set of all signature by (return) type


def get_all_polymorphic_return(self) -> bool:

lst = []<EOL>for s in self.values():<EOL><INDENT>if hasattr(s, '<STR_LIT>') and s.tret.is_polymorphic:<EOL><INDENT>lst.append(EvalCtx.from_sig(s))<EOL><DEDENT><DEDENT>rscope = Scope(sig=lst, state=StateScope.LINKED, is_namespace=False)<EOL>rscope.set_parent(self)<EOL>return rscope<EOL>

For now, polymorphic return type are handle by symbol artefact.

        --> possible multi-polymorphic but with different constraint attached!


def get_by_params(self, params: [Scope]) -> (Scope, [[Scope]]):

lst = []<EOL>scopep = []<EOL>for s in self.values():<EOL><INDENT>if hasattr(s, '<STR_LIT>'):<EOL><INDENT>mcnt = <NUM_LIT:0><EOL>nbparam_sig = (<NUM_LIT:0> if s.tparams is None else len(s.tparams))<EOL>nbparam_candidates = len(params)<EOL>if nbparam_sig > nbparam_candidates:<EOL><INDENT>continue<EOL><DEDENT>if nbparam_candidates > nbparam_sig and not s.variadic:<EOL><INDENT>continue<EOL><DEDENT>tmp = [None] * nbparam_candidates<EOL>variadic_types = []<EOL>for i in range(nbparam_candidates):<EOL><INDENT>tmp[i] = Scope(state=StateScope.LINKED)<EOL>tmp[i].set_parent(self)<EOL>if i < nbparam_sig:<EOL><INDENT>if params[i].state == StateScope.EMBEDDED:<EOL><INDENT>raise ValueError(<EOL>("<STR_LIT>"<EOL>+ "<STR_LIT>"<EOL>+ "<STR_LIT>"<EOL>+ "<STR_LIT>") % i<EOL>)<EOL><DEDENT>m = params[i].get_by_return_type(s.tparams[i])<EOL>if len(m) > <NUM_LIT:0>:<EOL><INDENT>mcnt += <NUM_LIT:1><EOL>tmp[i].update(m)<EOL><DEDENT>else:<EOL><INDENT>t1 = params[i]<EOL>t2 = s.tparams[i]<EOL>(is_convertible,<EOL>signature,<EOL>translator<EOL>) = t1.findTranslationTo(t2)<EOL>if is_convertible:<EOL><INDENT>signature.use_translator(translator)<EOL>mcnt += <NUM_LIT:1><EOL>nscope = Scope(<EOL>sig=[signature],<EOL>state=StateScope.LINKED,<EOL>is_namespace=False<EOL>)<EOL>nscope.set_parent(self)<EOL>tmp[i].update(nscope)<EOL><DEDENT>elif s.tparams[i].is_polymorphic:<EOL><INDENT>mcnt += <NUM_LIT:1><EOL>if not isinstance(params[i], Scope):<EOL><INDENT>raise Exception(<EOL>"<STR_LIT>" % i<EOL>)<EOL><DEDENT>tmp[i].update(params[i])<EOL><DEDENT>else:<EOL><INDENT>m = params[i].get_all_polymorphic_return()<EOL>if len(m) > <NUM_LIT:0>:<EOL><INDENT>mcnt += <NUM_LIT:1><EOL>tmp[i].update(m)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>mcnt += <NUM_LIT:1><EOL>if not isinstance(params[i], Scope):<EOL><INDENT>raise Exception("<STR_LIT>" % i)<EOL><DEDENT>variadic_types.append(params[i].first().tret)<EOL>tmp[i].update(params[i])<EOL><DEDENT><DEDENT>if mcnt == len(params):<EOL><INDENT>lst.append(EvalCtx.from_sig(s))<EOL>lastentry = lst[-<NUM_LIT:1>]<EOL>if lastentry.variadic:<EOL><INDENT>lastentry.use_variadic_types(variadic_types)<EOL><DEDENT>scopep.append(tmp)<EOL><DEDENT><DEDENT><DEDENT>rscope = Scope(sig=lst, state=StateScope.LINKED, is_namespace=False)<EOL>rscope.set_parent(self)<EOL>return (rscope, scopep)<EOL>

Retrieve a Set of all signature that match the parameter list.
        Return a pair:

            pair[0] the overloads for the functions
            pair[1] the overloads for the parameters
                (a list of candidate list of parameters)


if self.astTranslatorInjector is not None:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>self.astTranslatorInjector = ast_method<EOL>


def callInjector(self, old: Node, trans: Translator) -> Node:

if self.astTranslatorInjector is None:<EOL><INDENT>if self.parent is not None:<EOL><INDENT>return self.parent().callInjector(old, trans)<EOL><DEDENT>else:<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT><DEDENT>return self.astTranslatorInjector(old, trans)<EOL>


def findTranslationTo(self, t2: str) -> (bool, Signature, Translator):

if not t2.is_polymorphic:<EOL><INDENT>collect = []<EOL>for s in self.values():<EOL><INDENT>t1 = s.tret<EOL>if t1.is_polymorphic:<EOL><INDENT>continue<EOL><DEDENT>if (s.tret in self.mapTypeTranslate):<EOL><INDENT>if (t2 in self.mapTypeTranslate[t1]):<EOL><INDENT>collect.append((<EOL>True,<EOL>s,<EOL>self.mapTypeTranslate[t1][t2]<EOL>))<EOL><DEDENT><DEDENT><DEDENT>if len(collect) == <NUM_LIT:1>:<EOL><INDENT>return collect[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>return (False, None, None)<EOL>

Find an arrow (->)
        aka a function able to translate something to t2


unq = '<STR_LIT>' + super().internal_name()<EOL>if self.tret is not None:<EOL><INDENT>unq += "<STR_LIT:_>" + self.tret<EOL><DEDENT>return unq<EOL>


pp = fmt.tab([])<EOL>to_yml_item(self, pp.lsdata, "<STR_LIT>")<EOL>return str(pp)<EOL>

Allow to get the YML string representation of a Node.::

    from pyrser.passes import to_yml

    t = Node()
    ...
    print(str(t.to_yml()))


def parserrule_topython(parser: parsing.BasicParser,<EOL>rulename: str) -> ast.FunctionDef:

visitor = RuleVisitor()<EOL>rule = parser._rules[rulename]<EOL>fn_args = ast.arguments([ast.arg('<STR_LIT>', None)], None, None, [], None,<EOL>None, [], [])<EOL>body = visitor._clause(rule_topython(rule))<EOL>body.append(ast.Return(ast.Name('<STR_LIT:True>', ast.Load())))<EOL>return ast.FunctionDef(rulename, fn_args, body, [], None)<EOL>

Generates code for a rule.

    def rulename(self):
        <code for the rule>
        return True


if self.in_optional:<EOL><INDENT>return ast.Pass()<EOL><DEDENT>if self.in_try:<EOL><INDENT>return ast.Raise(<EOL>ast.Call(ast.Name('<STR_LIT>', ast.Load()), [], [], None, None),<EOL>None)<EOL><DEDENT>if self.in_loop:<EOL><INDENT>return ast.Break()<EOL><DEDENT>return ast.Return(ast.Name('<STR_LIT:False>', ast.Load()))<EOL>

Create the appropriate scope exiting statement.

        The documentation only shows one level and always uses
        'return False' in examples.

        'raise AltFalse()' within a try.
        'break' within a loop.
        'return False' otherwise.


def _clause(self, pt: parsing.ParserTree) -> [ast.stmt]:

if isinstance(pt, list):<EOL><INDENT>return pt<EOL><DEDENT>return [ast.If(ast.UnaryOp(ast.Not(), pt),<EOL>[self.__exit_scope()],<EOL>[])]<EOL>

Normalize a test expression into a statements list.

        Statements list are returned as-is.
        Expression is packaged as:
        if not expr:
            return False


def visit_Call(self, node: parsing.Call) -> ast.expr:

return ast.Call(<EOL>ast.Attribute(<EOL>ast.Name('<STR_LIT>', ast.Load),<EOL>node.callObject.__name__,<EOL>ast.Load()),<EOL>[ast.Str(param) for param in node.params],<EOL>[],<EOL>None,<EOL>None)<EOL>

Generates python code calling the function.

        fn(*args)


def visit_CallTrue(self, node: parsing.CallTrue) -> ast.expr:

return ast.Lambda(<EOL>ast.arguments([], None, None, [], None, None, [], []),<EOL>ast.BoolOp(<EOL>ast.Or(),<EOL>[<EOL>self.visit_Call(node),<EOL>ast.Name('<STR_LIT:True>', ast.Load())]))<EOL>

Generates python code calling the function and returning True.

        lambda: fn(*args) or True


def visit_Hook(self, node: parsing.Hook) -> ast.expr:

return ast.Call(<EOL>ast.Attribute(<EOL>ast.Name('<STR_LIT>', ast.Load()), '<STR_LIT>', ast.Load()),<EOL>[<EOL>ast.Str(node.name),<EOL>ast.Subscript(<EOL>ast.Attribute(<EOL>ast.Name('<STR_LIT>', ast.Load()), '<STR_LIT>', ast.Load()),<EOL>ast.Index(ast.UnaryOp(ast.USub(), ast.Num(<NUM_LIT:1>))),<EOL>ast.Load())],<EOL>[],<EOL>None,<EOL>None)<EOL>

Generates python code calling a hook.

        self.evalHook('hookname', self.ruleNodes[-1])


def visit_Rule(self, node: parsing.Rule) -> ast.expr:

return ast.Call(<EOL>ast.Attribute(ast.Name('<STR_LIT>', ast.Load()),<EOL>'<STR_LIT>', ast.Load()),<EOL>[ast.Str(node.name)], [], None, None)<EOL>

Generates python code calling a rule.

        self.evalRule('rulename')


def visit_Capture(self, node: parsing.Capture) -> [ast.stmt] or ast.expr:

begintag = ast.Attribute(<EOL>ast.Name('<STR_LIT>', ast.Load()), '<STR_LIT>', ast.Load())<EOL>endtag = ast.Attribute(<EOL>ast.Name('<STR_LIT>', ast.Load()), '<STR_LIT>', ast.Load())<EOL>begin = ast.Call(begintag, [ast.Str(node.tagname)], [], None, None)<EOL>end = ast.Call(endtag, [ast.Str(node.tagname)], [], None, None)<EOL>result = [begin, self.visit(node.pt), end]<EOL>for clause in result:<EOL><INDENT>if not isinstance(clause, ast.expr):<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return ast.BoolOp(ast.And(), result)<EOL><DEDENT>res = []<EOL>for stmt in map(self._clause, result):<EOL><INDENT>res.extend(stmt)<EOL><DEDENT>return res<EOL>

Generates python code to capture text consumed by a clause.

        #If all clauses can be inlined
        self.beginTag('tagname') and clause and self.endTag('tagname')

        if not self.beginTag('tagname'):
            return False
        <code for the clause>
        if not self.endTag('tagname'):
            return False


def visit_Scope(self, node: parsing.Capture) -> [ast.stmt] or ast.expr:

return ast.Name('<STR_LIT>', ast.Load())<EOL>raise NotImplementedError()<EOL>

Generates python code for a scope.

        if not self.begin():
            return False
        res = self.pt()
        if not self.end():
            return False
        return res


def visit_Alt(self, node: parsing.Alt) -> [ast.stmt]:

clauses = [self.visit(clause) for clause in node.ptlist]<EOL>for clause in clauses:<EOL><INDENT>if not isinstance(clause, ast.expr):<EOL><INDENT>break<EOL><DEDENT><DEDENT>else:<EOL><INDENT>return ast.BoolOp(ast.Or(), clauses)<EOL><DEDENT>res = ast.Try([], [ast.ExceptHandler(<EOL>ast.Name('<STR_LIT>', ast.Load()), None, [ast.Pass()])], [], [])<EOL>alt_true = [ast.Raise(ast.Call(<EOL>ast.Name('<STR_LIT>', ast.Load()), [], [], None, None), None)]<EOL>alt_false = [ast.ExceptHandler(<EOL>ast.Name('<STR_LIT>', ast.Load()), None, [ast.Pass()])]<EOL>self.in_try += <NUM_LIT:1><EOL>for clause in node.ptlist:<EOL><INDENT>res.body.append(<EOL>ast.Try(self._clause(self.visit(clause)) + alt_true,<EOL>alt_false, [], []))<EOL><DEDENT>self.in_try -= <NUM_LIT:1><EOL>res.body.append(self.__exit_scope())<EOL>return [res]<EOL>

Generates python code for alternatives.

        try:
            try:
                <code for clause>  #raise AltFalse when alternative is False
                raise AltTrue()
            except AltFalse:
                pass
            return False
        except AltTrue:
            pass


def visit_Seq(self, node: parsing.Seq) -> [ast.stmt] or ast.expr:

exprs, stmts = [], []<EOL>for clause in node.ptlist:<EOL><INDENT>clause_ast = self.visit(clause)<EOL>if isinstance(clause_ast, ast.expr):<EOL><INDENT>exprs.append(clause_ast)<EOL><DEDENT>else:<EOL><INDENT>if exprs:<EOL><INDENT>stmts.extend(self.combine_exprs_for_clauses(exprs))<EOL>exprs = []<EOL><DEDENT>stmts.extend(self._clause(clause_ast))<EOL><DEDENT><DEDENT>if not stmts:<EOL><INDENT>return ast.BoolOp(ast.And(), exprs)<EOL><DEDENT>if exprs:<EOL><INDENT>stmts.extend(self.combine_exprs_for_clauses(exprs))<EOL><DEDENT>return stmts<EOL>

Generates python code for clauses.

        #Continuous clauses which can can be inlined are combined with and
        clause and clause

        if not clause:
            return False
        if not clause:
            return False


def visit_RepOptional(self, node: parsing.RepOptional) -> ([ast.stmt] or<EOL>ast.expr):

cl_ast = self.visit(node.pt)<EOL>if isinstance(cl_ast, ast.expr):<EOL><INDENT>return ast.BoolOp(ast.Or(), [cl_ast, ast.Name('<STR_LIT:True>', ast.Load())])<EOL><DEDENT>self.in_optional += <NUM_LIT:1><EOL>cl_ast = self.visit(node.pt)<EOL>self.in_optional -= <NUM_LIT:1><EOL>return cl_ast<EOL>

Generates python code for an optional clause.

        <code for the clause>


def visit_Rep0N(self, node: parsing.Rep0N) -> [ast.stmt]:

cl_ast = self.visit(node.pt)<EOL>if isinstance(cl_ast, ast.expr):<EOL><INDENT>return [ast.While(cl_ast, [ast.Pass()], [])]<EOL><DEDENT>self.in_loop += <NUM_LIT:1><EOL>clause = self._clause(self.visit(node.pt))<EOL>self.in_loop -= <NUM_LIT:1><EOL>return [ast.While(ast.Name('<STR_LIT:True>', ast.Load()), clause, [])]<EOL>

Generates python code for a clause repeated 0 or more times.

        #If all clauses can be inlined
        while clause:
            pass

        while True:
            <code for the clause>


def visit_Rep1N(self, node: parsing.Rep0N) -> [ast.stmt]:

clause = self.visit(node.pt)<EOL>if isinstance(clause, ast.expr):<EOL><INDENT>return (self._clause(clause) + self.visit_Rep0N(node))<EOL><DEDENT>self.in_loop += <NUM_LIT:1><EOL>clause = self._clause(self.visit(node.pt))<EOL>self.in_loop -= <NUM_LIT:1><EOL>return self._clause(self.visit(node.pt)) + [<EOL>ast.While(ast.Name('<STR_LIT:True>', ast.Load()), clause, [])]<EOL>

Generates python code for a clause repeated 1 or more times.

        <code for the clause>
        while True:
            <code for the clause>


def __init__(self, html_string, tokens=[]):

self.soup = BeautifulSoup(html_string, '<STR_LIT>')<EOL>self.tags_blacklist = []<EOL>self.tokens = tokens<EOL>self.parse()<EOL>

Constructor takes an HTML string and sets up object.


for tag in self.soup.findAll('<STR_LIT>'):<EOL><INDENT>self.create_italic(tag)<EOL>self.create_strong(tag)<EOL>self.create_underline(tag)<EOL>self.unwrap_span(tag)<EOL><DEDENT>for tag in self.soup.findAll('<STR_LIT:a>'):<EOL><INDENT>self.remove_comments(tag)<EOL>self.check_next(tag)<EOL><DEDENT>if self.soup.body:<EOL><INDENT>for tag in self.soup.body.findAll():<EOL><INDENT>self.remove_empty(tag)<EOL>self.remove_inline_comment(tag)<EOL>self.parse_attrs(tag)<EOL>for token, target in self.tokens:<EOL><INDENT>self.find_token(tag, token, target)<EOL><DEDENT>self.remove_blacklisted_tags(tag)<EOL><DEDENT><DEDENT>


if tag.get('<STR_LIT:id>', '<STR_LIT>').startswith('<STR_LIT>'):<EOL><INDENT>tag.parent.extract()<EOL><DEDENT>


if (type(tag.next_sibling) == element.Tag and<EOL>tag.next_sibling.name == '<STR_LIT:a>'):<EOL><INDENT>next_tag = tag.next_sibling<EOL>if tag.get('<STR_LIT>') and next_tag.get('<STR_LIT>'):<EOL><INDENT>href = self._parse_href(tag.get('<STR_LIT>'))<EOL>next_href = self._parse_href(next_tag.get('<STR_LIT>'))<EOL>if href == next_href:<EOL><INDENT>next_text = next_tag.get_text()<EOL>tag.append(next_text)<EOL>self.tags_blacklist.append(next_tag)<EOL><DEDENT><DEDENT><DEDENT>

If next tag is link with same href, combine them.


style = tag.get('<STR_LIT>')<EOL>if style and '<STR_LIT>' in style:<EOL><INDENT>tag.wrap(self.soup.new_tag('<STR_LIT>'))<EOL><DEDENT>

See if span tag has italic style and wrap with em tag.


style = tag.get('<STR_LIT>')<EOL>if (style and<EOL>('<STR_LIT>' in style or '<STR_LIT>' in style)):<EOL><INDENT>tag.wrap(self.soup.new_tag('<STR_LIT>'))<EOL><DEDENT>

See if span tag has bold style and wrap with strong tag.


style = tag.get('<STR_LIT>')<EOL>if style and '<STR_LIT>' in style:<EOL><INDENT>tag.wrap(self.soup.new_tag('<STR_LIT:u>'))<EOL><DEDENT>

See if span tag has underline style and wrap with u tag.


tag.unwrap()<EOL>

Remove span tags while preserving contents.


if tag.name in ATTR_WHITELIST.keys():<EOL><INDENT>attrs = copy(tag.attrs)<EOL>for attr, value in attrs.items():<EOL><INDENT>if attr in ATTR_WHITELIST[tag.name]:<EOL><INDENT>tag.attrs[attr] = self._parse_attr(tag.name, attr, value)<EOL><DEDENT>else:<EOL><INDENT>del tag.attrs[attr]<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>tag.attrs = {}<EOL><DEDENT>

Reject attributes not defined in ATTR_WHITELIST.


has_children = len(tag.contents)<EOL>has_text = len(list(tag.stripped_strings))<EOL>if not has_children and not has_text and not tag.is_empty_element:<EOL><INDENT>tag.extract()<EOL><DEDENT>

Remove non-self-closing tags with no children *and* no content.


stripped = tag.decode(formatter=None)<EOL>stripped = re.sub('<STR_LIT>', '<STR_LIT:U+0020>', stripped)<EOL>stripped = re.sub('<STR_LIT:\n>', '<STR_LIT>', stripped)<EOL>return stripped<EOL>

get unicode string without any other content transformation.
and clean extra spaces


params = parse_qs(urlsplit(href).query)<EOL>return params.get('<STR_LIT:q>')<EOL>

Extract "real" URL from Google redirected url by getting `q`
querystring parameter.


def _parse_attr(self, tagname, attr, value):

if tagname == '<STR_LIT:a>' and attr == '<STR_LIT>':<EOL><INDENT>return self._parse_href(value)<EOL><DEDENT>else:<EOL><INDENT>return value<EOL><DEDENT>

Parse attribute. Delegate to href parser for hrefs, otherwise return
value.


pkg = Package("<STR_LIT>")<EOL>class Container(Injector):<EOL><INDENT>itself = pkg<EOL>submodule = pkg.submodule<EOL>instance = pkg.submodule.Foo<EOL>instance_method = pkg.submodule.Foo.do<EOL>function = pkg.submodule.function<EOL>variable = pkg.submodule.variable<EOL>keep_class = pkg.submodule.Foo<EOL><DEDENT>return Container<EOL>


pkg = Package("<STR_LIT>")<EOL>sub = Package("<STR_LIT>")<EOL>class Container(Injector):<EOL><INDENT>itself = pkg<EOL>submodule = sub<EOL>instance = sub.Bar<EOL>instance_method = sub.Bar.do<EOL>function = sub.function<EOL>variable = sub.variable<EOL>keep_class = sub.Bar<EOL>a = -<NUM_LIT:1><EOL>b = <NUM_LIT:2><EOL><DEDENT>return Container<EOL>


pkg = Package("<STR_LIT>")<EOL>class Container(Injector):<EOL><INDENT>foo = pkg.injected.Container.foo<EOL>bar = pkg.injected.Container.bar<EOL>baz = <NUM_LIT:2><EOL><DEDENT>return Container<EOL>


injected = Package("<STR_LIT>")<EOL>class Container(Injector):<EOL><INDENT>foo = injected.Container.foo<EOL>bar = injected.Container.bar<EOL>baz = <NUM_LIT:2><EOL><DEDENT>return Container<EOL>


class Container(Injector):<EOL><INDENT>foo = {"<STR_LIT>": <NUM_LIT:1>}<EOL>one = this.foo["<STR_LIT>"]<EOL><DEDENT>result = Container.one<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = {"<STR_LIT>": {"<STR_LIT>": <NUM_LIT:1>}}<EOL>two = this.foo["<STR_LIT>"]["<STR_LIT>"]<EOL><DEDENT>result = Container.two<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = {"<STR_LIT:bar>": {"<STR_LIT>": <NUM_LIT:1>}}<EOL>class SubContainer(Injector):<EOL><INDENT>spam = (this << <NUM_LIT:1>).foo["<STR_LIT:bar>"]["<STR_LIT>"]<EOL><DEDENT><DEDENT>result = Container.SubContainer.spam<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = {"<STR_LIT:bar>": {"<STR_LIT>": <NUM_LIT:1>}}<EOL>class SubContainer(Injector):<EOL><INDENT>class SubSubContainer(Injector):<EOL><INDENT>spam = (this << <NUM_LIT:2>).foo["<STR_LIT:bar>"]["<STR_LIT>"]<EOL><DEDENT><DEDENT><DEDENT>result = Container.SubContainer.SubSubContainer.spam<EOL>return result<EOL>

Get item from the outer container of any depth level.


class Container(Injector):<EOL><INDENT>foo = [<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>]<EOL>bar = this.foo[<NUM_LIT:0>]<EOL><DEDENT>result = Container.bar<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = {<NUM_LIT:2>: <NUM_LIT:1>}<EOL>bar = this.foo[<NUM_LIT:2>]<EOL><DEDENT>result = Container.bar<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = {("<STR_LIT:x>", <NUM_LIT:1>): <NUM_LIT:1>}<EOL>bar = this.foo[("<STR_LIT:x>", <NUM_LIT:1>)]<EOL><DEDENT>result = Container.bar<EOL>return result<EOL>


class Container(Injector):<EOL><INDENT>foo = this.bar()<EOL>bar = lambda: <NUM_LIT:1>  <EOL><DEDENT>return Container<EOL>


return Injector.let(foo=this.bar(), bar=lambda: <NUM_LIT:1>)<EOL>


class Container(Injector):<EOL><INDENT>foo = this<EOL><DEDENT>


class Container(Injector):<EOL><INDENT>foo = this << <NUM_LIT:1><EOL><DEDENT>

Declarative injector with parent access.


Injector.let(foo=this)<EOL>


Injector.let(foo=(this << <NUM_LIT:1>))<EOL>


this << -<NUM_LIT:1><EOL>


this << <NUM_LIT:0><EOL>


class Container(Injector):<EOL><INDENT>foo = (this << <NUM_LIT:1>).bar<EOL><DEDENT>Container.foo<EOL>


class Container(Injector):<EOL><INDENT>class SubContainer(Injector):<EOL><INDENT>foo = (this << <NUM_LIT:2>).bar<EOL><DEDENT><DEDENT>Container.SubContainer.foo<EOL>


Injector.let(foo=(this << <NUM_LIT:1>).bar).foo<EOL>


Injector.let(SubContainer=Injector.let(foo=(this << <NUM_LIT:2>).bar)).SubContainer.foo<EOL>


class Container(Injector):<EOL><INDENT>foo = this.bar<EOL><DEDENT>Container.foo<EOL>


class Container(Injector):<EOL><INDENT>class SubContainer(Injector):<EOL><INDENT>foo = (this << <NUM_LIT:1>).bar<EOL><DEDENT><DEDENT>Container.SubContainer.foo<EOL>


Injector.let(foo=this.bar).foo<EOL>


Injector.let(SubContainer=Injector.let(foo=(this << <NUM_LIT:1>).bar)).SubContainer.foo<EOL>


@contrib.task<EOL>class Container(Injector):<EOL><INDENT>app = _app<EOL>name = "<STR_LIT>"<EOL>run = Run<EOL><DEDENT>return Container<EOL>


@contrib.shared_task<EOL>class Container(Injector):<EOL><INDENT>name = "<STR_LIT>"<EOL>run = Run<EOL><DEDENT>return Container<EOL>


sign = container.signature((<NUM_LIT:2>, <NUM_LIT:2>), {"<STR_LIT>": True}, immutable=True, countdown=<NUM_LIT:10>)<EOL>return sign<EOL>


sign = container.signature(<EOL>(<NUM_LIT:2>, <NUM_LIT:2>), {"<STR_LIT>": True}, immutable=True, options={"<STR_LIT>": <NUM_LIT:10>}<EOL>)<EOL>return sign<EOL>


class NewContainer(container):<EOL><INDENT>immutable = True<EOL>options = {"<STR_LIT>": <NUM_LIT:10>}<EOL>subtask_type = "<STR_LIT>"<EOL><DEDENT>sign = NewContainer.signature((<NUM_LIT:2>, <NUM_LIT:2>), {"<STR_LIT>": True})<EOL>return sign, True, "<STR_LIT>"<EOL>

Verbose signature with attributes from container.


class NewContainer(container):<EOL><INDENT>immutable = False<EOL>options = {"<STR_LIT>": <NUM_LIT:1>}<EOL>subtask_type = "<STR_LIT>"<EOL><DEDENT>sign = NewContainer.signature(<EOL>(<NUM_LIT:2>, <NUM_LIT:2>), {"<STR_LIT>": True}, immutable=True, countdown=<NUM_LIT:10>, subtask_type="<STR_LIT>"<EOL>)<EOL>return sign, True, "<STR_LIT>"<EOL>

Verbose signature override attributes from container.


class NewContainer(container):<EOL><INDENT>options = {"<STR_LIT>": <NUM_LIT:10>}<EOL>subtask_type = "<STR_LIT>"<EOL><DEDENT>sign = NewContainer.s(<NUM_LIT:2>, <NUM_LIT:2>, debug=True)<EOL>return sign, False, "<STR_LIT>"<EOL>


class NewContainer(container):<EOL><INDENT>options = {"<STR_LIT>": <NUM_LIT:10>}<EOL><DEDENT>sign = NewContainer.si(<NUM_LIT:2>, <NUM_LIT:2>, debug=True)<EOL>return sign<EOL>


@contrib.task<EOL>class Container(container):<EOL><INDENT>app = _app<EOL>name = "<STR_LIT>"<EOL>run = this.bar.do<EOL><DEDENT>


@contrib.shared_task<EOL>class Container(container):<EOL><INDENT>name = "<STR_LIT>"<EOL>run = this.bar.do<EOL><DEDENT>


class Container(Injector):<EOL><INDENT>foo = <NUM_LIT:1><EOL>SubContainer = sub<EOL><DEDENT>return Container<EOL>


return Injector.let(foo=<NUM_LIT:1>, SubContainer=sub)<EOL>


class SubContainer(Injector):<EOL><INDENT>bar = (this << <NUM_LIT:1>).foo<EOL><DEDENT>return SubContainer<EOL>


return Injector.let(bar=(this << <NUM_LIT:1>).foo)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubContainer<EOL>


class Container(Injector):<EOL><INDENT>foo = <NUM_LIT:1><EOL>SubContainer = middle<EOL><DEDENT>return Container<EOL>


return Injector.let(foo=<NUM_LIT:1>, SubContainer=middle)<EOL>


class SubContainer(Injector):<EOL><INDENT>SubSubContainer = lowest<EOL><DEDENT>return SubContainer<EOL>


return Injector.let(SubSubContainer=lowest)<EOL>


class SubSubContainer(Injector):<EOL><INDENT>bar = (this << <NUM_LIT:2>).foo<EOL><DEDENT>return SubSubContainer<EOL>


return Injector.let(bar=(this << <NUM_LIT:2>).foo)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubSubContainer<EOL>


class Container(Injector):<EOL><INDENT>pass<EOL><DEDENT>Container.foo = <NUM_LIT:1><EOL>


Injector.foo = <NUM_LIT:1><EOL>


Container = Injector.let()<EOL>Container.foo = <NUM_LIT:1><EOL>


class Container(Injector):<EOL><INDENT>foo = <NUM_LIT:1><EOL><DEDENT>del Container.foo<EOL>


Container = Injector.let(foo=<NUM_LIT:1>)<EOL>del Container.foo<EOL>


del Injector.let<EOL>

Delete attribute from `Injector` directly.


x = Container.a<EOL>assert x.b.d is x.c.d<EOL>

Each dependency evaluated once during injection.


assert Container.a.b.d is not Container.a.b.d<EOL>assert Container.a.b.d is not Container.a.c.d<EOL>

We reevaluate each dependency for different injections.


@multiple_inheritance<EOL>def edf946cc6077(Foo, FooContainer, BarContainer, BazContainer):

class Container(FooContainer, BarContainer, BazContainer):<EOL><INDENT>pass<EOL><DEDENT>assert isinstance(Container.baz.bar.foo, Foo)<EOL>


@multiple_inheritance<EOL>def efdc426cd096(Foo, FooContainer, BarContainer, BazContainer):

assert isinstance((FooContainer & BarContainer & BazContainer).baz.bar.foo, Foo)<EOL>


@inheritance_order<EOL>def aa10c7747a1f(Container1, Container2, Container3):

class Foo(Container1, Container2, Container3):<EOL><INDENT>pass<EOL><DEDENT>assert Foo.x == <NUM_LIT:1><EOL>


@inheritance_order<EOL>def e056e22f3fd5(Container1, Container2, Container3):

class Foo(Container1, Container2, Container3):<EOL><INDENT>x = <NUM_LIT:4><EOL><DEDENT>assert Foo.x == <NUM_LIT:4><EOL>


@inheritance_order<EOL>def d851e0414bdf(Container1, Container2, Container3):

assert (Container1 & Container2 & Container3).x == <NUM_LIT:1><EOL>


class Bar(Injector, Foo):<EOL><INDENT>pass<EOL><DEDENT>


Injector & Foo<EOL>


class Bar(Injector):<EOL><INDENT>def __eq__(self, other):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>


class Foo(Injector):<EOL><INDENT>pass<EOL><DEDENT>Foo.let(__eq__=lambda self, other: False)<EOL>


class Foo(Injector):<EOL><INDENT>pass<EOL><DEDENT>Foo.test<EOL>


Foo = Injector.let()<EOL>Foo.test<EOL>


class Foo(Injector):<EOL><INDENT>pass<EOL><DEDENT>Foo.let().test<EOL>


class Bar(object):<EOL><INDENT>def __init__(self, test, two=<NUM_LIT:2>):<EOL><INDENT>self.test = test<EOL>self.two = two<EOL><DEDENT><DEDENT>class Foo(Injector):<EOL><INDENT>bar = Bar<EOL><DEDENT>Foo.bar<EOL>


class Bar(object):<EOL><INDENT>def __init__(self, test):<EOL><INDENT>self.test = test<EOL><DEDENT><DEDENT>Foo = Injector.let(bar=Bar)<EOL>Foo.bar<EOL>


class Container(Injector):<EOL><INDENT>foo = <NUM_LIT:1><EOL><DEDENT>return Container<EOL>


return Injector.let(foo=<NUM_LIT:1>)<EOL>


class Summator(Injector):<EOL><INDENT>foo = Foo<EOL>args = (<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>)<EOL><DEDENT>


Injector.let(foo=Foo, args=(<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>))<EOL>


class Summator(Injector):<EOL><INDENT>foo = Foo<EOL>kwargs = {"<STR_LIT:start>": <NUM_LIT:5>}<EOL><DEDENT>


Injector.let(foo=Foo, kwargs={"<STR_LIT:start>": <NUM_LIT:5>})<EOL>


class Summator(Injector):<EOL><INDENT>foo = Foo<EOL>args = (<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>)<EOL>kwargs = {"<STR_LIT:start>": <NUM_LIT:5>}<EOL><DEDENT>


Injector.let(foo=Foo, args=(<NUM_LIT:1>, <NUM_LIT:2>, <NUM_LIT:3>), kwargs={"<STR_LIT:start>": <NUM_LIT:5>})<EOL>


class Foo(Injector):<EOL><INDENT>let = <NUM_LIT:2><EOL><DEDENT>


class Foo(Injector):<EOL><INDENT>pass<EOL><DEDENT>Foo.let(let=<NUM_LIT:1>)<EOL>


Injector()<EOL>


class Foo(Injector):<EOL><INDENT>pass<EOL><DEDENT>Foo()<EOL>


class Container(Injector):<EOL><INDENT>bar = Bar<EOL><DEDENT>


Injector.let(bar=Bar)<EOL>


class Container(Injector):<EOL><INDENT>foo = this.foo<EOL><DEDENT>Container.foo<EOL>


Injector.let(foo=this.foo).foo<EOL>


class Container(Injector):<EOL><INDENT>foo = this.bar<EOL>bar = this.foo<EOL><DEDENT>Container.foo<EOL>


Injector.let(foo=this.bar, bar=this.foo).foo<EOL>


class Container(Injector):<EOL><INDENT>foo = this.bar<EOL>bar = this.baz<EOL>baz = this.foo<EOL><DEDENT>Container.foo<EOL>


class Container(Injector):<EOL><INDENT>foo = this.SubContainer.bar<EOL>SubContainer = sub<EOL><DEDENT>Container.foo<EOL>


Injector.let(foo=this.SubContainer.bar, SubContainer=sub).foo<EOL>


class SubContainer(Injector):<EOL><INDENT>bar = (this << <NUM_LIT:1>).foo<EOL><DEDENT>return SubContainer<EOL>


return Injector.let(bar=(this << <NUM_LIT:1>).foo)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubContainer<EOL>


class Container(Injector):<EOL><INDENT>foo = this.SubContainer.SubSubContainer.bar<EOL>SubContainer = middle<EOL><DEDENT>Container.foo<EOL>


Injector.let(foo=this.SubContainer.SubSubContainer.bar, SubContainer=middle).foo<EOL>


class SubContainer(Injector):<EOL><INDENT>SubSubContainer = lowest<EOL><DEDENT>return SubContainer<EOL>


return Injector.let(SubSubContainer=lowest)<EOL>


class SubSubContainer(Injector):<EOL><INDENT>bar = (this << <NUM_LIT:2>).foo<EOL><DEDENT>return SubSubContainer<EOL>


return Injector.let(bar=(this << <NUM_LIT:2>).foo)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubSubContainer<EOL>


class Container(Injector):<EOL><INDENT>foo = this.SubContainer.baz<EOL>SubContainer = middle<EOL><DEDENT>Container.foo<EOL>


Injector.let(foo=this.SubContainer.baz, SubContainer=middle).foo<EOL>


class SubContainer(Injector):<EOL><INDENT>baz = this.SubSubContainer.bar<EOL>SubSubContainer = lowest<EOL><DEDENT>return SubContainer<EOL>


return Injector.let(baz=this.SubSubContainer.bar, SubSubContainer=lowest)<EOL>


class Container(Injector):<EOL><INDENT>SubContainer1 = sub1<EOL>SubContainer2 = sub2<EOL><DEDENT>Container.SubContainer1.bar<EOL>


Injector.let(SubContainer1=sub1, SubContainer2=sub2).SubContainer1.bar<EOL>


class SubContainer1(Injector):<EOL><INDENT>bar = (this << <NUM_LIT:1>).SubContainer2.baz<EOL><DEDENT>return SubContainer1<EOL>


return Injector.let(bar=(this << <NUM_LIT:1>).SubContainer2.baz)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubContainer1<EOL>


class SubContainer2(Injector):<EOL><INDENT>baz = (this << <NUM_LIT:1>).SubContainer1.bar<EOL><DEDENT>return SubContainer2<EOL>


return Injector.let(baz=(this << <NUM_LIT:1>).SubContainer1.bar)<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.injected.SubContainer2<EOL>


class Container(Injector):<EOL><INDENT>class SubContainer(Injector):<EOL><INDENT>foo = (this << <NUM_LIT:1>).bar["<STR_LIT>"].foo<EOL><DEDENT>bar = {"<STR_LIT>": SubContainer}<EOL><DEDENT>Container.SubContainer.foo<EOL>


SubContainer = Injector.let(foo=(this << <NUM_LIT:1>).bar["<STR_LIT>"].foo)<EOL>Injector.let(SubContainer=SubContainer, bar={"<STR_LIT>": SubContainer}).SubContainer.foo<EOL>


class Container(Injector):<EOL><INDENT>method = arg<EOL><DEDENT>


Injector.let(method=arg)<EOL>


class Container(Injector):<EOL><INDENT>func = arg<EOL><DEDENT>


Injector.let(func=arg)<EOL>


class Summator(Injector):<EOL><INDENT>foo = Foo<EOL><DEDENT>Summator.foo<EOL>


Summator = Injector.let(foo=Foo)<EOL>Summator.foo<EOL>


class Foo(object):<EOL><INDENT>def __init__(self, foo):<EOL><INDENT>self.foo = foo<EOL><DEDENT><DEDENT>return Foo<EOL>


@operation<EOL>def Foo(foo):<EOL><INDENT>pass<EOL><DEDENT>return Foo<EOL>


@value<EOL>def Foo(foo):<EOL><INDENT>pass<EOL><DEDENT>return Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.simple_class.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.simple_operation.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.simple_value.Foo<EOL>


class Summator(Injector):<EOL><INDENT>foo = Foo<EOL>bar = Bar<EOL><DEDENT>Summator.foo<EOL>


class First(Injector):<EOL><INDENT>foo = Foo<EOL><DEDENT>class Second(First):<EOL><INDENT>bar = Bar<EOL><DEDENT>Second.foo<EOL>


Summator = Injector.let(foo=Foo, bar=Bar)<EOL>Summator.foo<EOL>


Summator = Injector.let(foo=Foo).let(bar=Bar)<EOL>Summator.foo<EOL>


class Foo(object):<EOL><INDENT>def __init__(self, bar):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return Foo<EOL>


@operation<EOL>def Foo(bar):<EOL><INDENT>pass<EOL><DEDENT>return Foo<EOL>


@value<EOL>def Foo(bar):<EOL><INDENT>pass<EOL><DEDENT>return Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_class.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_operation.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_value.Foo<EOL>


class Bar(object):<EOL><INDENT>def __init__(self, foo):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return Bar<EOL>


@operation<EOL>def Bar(foo):<EOL><INDENT>pass<EOL><DEDENT>return Bar<EOL>


@value<EOL>def Bar(foo):<EOL><INDENT>pass<EOL><DEDENT>return Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_class.Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_operation.Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.complex_value.Bar<EOL>


@long_circle_deps<EOL>def d2b809c03bfa(Foo, Bar, Baz):

class Summator(Injector):<EOL><INDENT>foo = Foo<EOL>bar = Bar<EOL>baz = Baz<EOL><DEDENT>Summator.foo<EOL>


@long_circle_deps<EOL>def fc13db5b9fda(Foo, Bar, Baz):

class First(Injector):<EOL><INDENT>foo = Foo<EOL><DEDENT>class Second(First):<EOL><INDENT>bar = Bar<EOL>baz = Baz<EOL><DEDENT>Second.foo<EOL>


@long_circle_deps<EOL>def c729e6952fee(Foo, Bar, Baz):

Summator = Injector.let(foo=Foo, bar=Bar, baz=Baz)<EOL>Summator.foo<EOL>


@long_circle_deps<EOL>def d701f88a5c42(Foo, Bar, Baz):

Summator = Injector.let(foo=Foo).let(bar=Bar).let(baz=Baz)<EOL>Summator.foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_class.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_operation.Foo<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_value.Foo<EOL>


class Bar(object):<EOL><INDENT>def __init__(self, baz):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return Bar<EOL>


@operation<EOL>def Bar(baz):<EOL><INDENT>pass<EOL><DEDENT>return Bar<EOL>


@value<EOL>def Bar(baz):<EOL><INDENT>pass<EOL><DEDENT>return Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_class.Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_operation.Bar<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_value.Bar<EOL>


class Baz(object):<EOL><INDENT>def __init__(self, foo):<EOL><INDENT>pass<EOL><DEDENT><DEDENT>return Baz<EOL>


@operation<EOL>def Baz(foo):<EOL><INDENT>pass<EOL><DEDENT>return Baz<EOL>


@value<EOL>def Baz(foo):<EOL><INDENT>pass<EOL><DEDENT>return Baz<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_class.Baz<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_operation.Baz<EOL>


pkg = Package("<STR_LIT>")<EOL>return pkg.circles.long_value.Baz<EOL>


class Container(Injector):<EOL><INDENT>method = arg<EOL><DEDENT>


Injector.let(method=arg)<EOL>


class Container(Injector):<EOL><INDENT>func = arg<EOL><DEDENT>


Injector.let(func=arg)<EOL>


if "<STR_LIT>" not in injector:<EOL><INDENT>injector.fixture<EOL><DEDENT>options = {"<STR_LIT:name>": injector.name}<EOL>for option in ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]:<EOL><INDENT>if option in injector:<EOL><INDENT>options[option] = getattr(injector, option)<EOL><DEDENT><DEDENT>@pytest.fixture(**options)<EOL>def __fixture(request):<EOL><INDENT>return injector.let(request=request).fixture<EOL><DEDENT>__fixture.injector = injector<EOL>return __fixture<EOL>

Register Py.test fixture performing injection in it's scope.


return type(Requirement.__name__, (Requirement,), {"<STR_LIT>": fixturename})<EOL>

Mark fixture as a dependency for injection process.


return decorate_with(injector.app.task, injector)<EOL>


return decorate_with(celery.shared_task, injector)<EOL>

Create Celery shared task from injector class.


handler = create_handler(View, injector)<EOL>apply_http_methods(handler, injector)<EOL>return injector.let(as_view=handler.as_view)<EOL>

Create Django class-based view from injector class.


handler = create_handler(FormView, injector)<EOL>apply_form_methods(handler, injector)<EOL>return injector.let(as_view=handler.as_view)<EOL>

Create Django form processing class-based view from injector class.


handler = create_handler(APIView, injector)<EOL>apply_http_methods(handler, injector)<EOL>apply_api_view_methods(handler, injector)<EOL>return injector.let(as_view=handler.as_view)<EOL>

Create DRF class-based API view from injector class.


handler = create_handler(GenericAPIView, injector)<EOL>apply_http_methods(handler, injector)<EOL>apply_api_view_methods(handler, injector)<EOL>apply_generic_api_view_methods(handler, injector)<EOL>return injector.let(as_view=handler.as_view)<EOL>

Create DRF generic class-based API view from injector class.


handler = create_handler(ModelViewSet, injector)<EOL>apply_api_view_methods(handler, injector)<EOL>apply_generic_api_view_methods(handler, injector)<EOL>apply_model_view_set_methods(handler, injector)<EOL>return injector.let(as_viewset=lambda: handler)<EOL>

Create DRF model view set from injector class.


handler = create_handler(MethodView)<EOL>apply_http_methods(handler, injector)<EOL>return injector.let(as_view=handler.as_view)<EOL>

Create Flask method based dispatching view from injector class.


return type(cls.__name__, (cls,), kwargs)<EOL>

Produce new Injector with some dependencies overwritten.


def get_scores(self, avg=False, ignore_empty=False):

hyp_path, ref_path = self.hyp_path, self.ref_path<EOL>with io.open(hyp_path, encoding="<STR_LIT:utf-8>", mode="<STR_LIT:r>") as hyp_file:<EOL><INDENT>hyps = [line[:-<NUM_LIT:1>] for line in hyp_file]<EOL><DEDENT>with io.open(ref_path, encoding="<STR_LIT:utf-8>", mode="<STR_LIT:r>") as ref_file:<EOL><INDENT>refs = [line[:-<NUM_LIT:1>] for line in ref_file]<EOL><DEDENT>return self.rouge.get_scores(hyps, refs, avg=avg,<EOL>ignore_empty=ignore_empty)<EOL>

Calculate ROUGE scores between each pair of
        lines (hyp_file[i], ref_file[i]).
        Args:
          * hyp_path: hypothesis file path
          * ref_path: references file path
          * avg (False): whether to get an average scores or a list


ngram_set = set()<EOL>text_length = len(text)<EOL>max_index_ngram_start = text_length - n<EOL>for i in range(max_index_ngram_start + <NUM_LIT:1>):<EOL><INDENT>ngram_set.add(tuple(text[i:i + n]))<EOL><DEDENT>return ngram_set<EOL>

Calcualtes n-grams.

    Args:
      n: which n-grams to calculate
      text: An array of tokens

    Returns:
      A set of n-grams


return list(itertools.chain(*[_.split("<STR_LIT:U+0020>") for _ in sentences]))<EOL>

Splits multiple sentences into words and flattens the result