def _brace_semi_fflatten(acc): """Treatment to remove nesting in the Token lists produced by brace_semi. >>> pstream(brace_semi().treat(_brace_semi_fflatten),'{ a ; b { b1 ; (d) } ; c }') (LexToken({,'{',1,0), [[LexToken(VAR,'a',1,2)], LexToken(;,';',1,4), [LexToken(VAR,'b',1,6), LexToken({,'{',1,8), LexToken(VAR,'b1',1,10)... """ (a,b,c) = acc b[0::2] = [lib.fflatten(u) for u in b[0::2]] # semi at odds return (a,b,c)
def collect(etok, f): """Recursively call f on etok tree. Immutable on etok iff f(etok) does not mutate etok. No return. State can be stored in f to collect data. """ if etok: f(etok) for e in lib.fflatten(etok.etoks): collect(e, f) pass
def validate(self): if not (isinstance(self.name, str)): raise TypeError('Etok string expected in name:' + str(self.name)) if not (isinstance(self.altrepr, str)): raise TypeError('Etok string expected in altrepr:' + str(self.altrepr)) if not (isinstance(self.rule, str)): raise TypeError('Etok string expected in rule:' + str(self.rule)) for e in self.raw: if not (isinstance(e, LexToken)): raise TypeError( f'raw must be list of Tok in {self.name}, not {str(e)}') for e in lib.fflatten(self.etoks): if e and not (isinstance(e, Etok)): raise TypeError( f'etoks must be a list of Etok in {self.name}, not {e}:{type(e).__name__}' ) pass
def s_expression(self): def s2(es): if isinstance(es, Etok): return es.s_expression() if lib.iterable(es): return '[' + ' '.join([s2(e) for e in es if e]) + ']' if not (es): return '' name2 = self.name if self.rule: name2 += '-' + self.rule re = '' if lib.fflatten(self.etoks): re = s2(self.etoks) #' '.join([e.s_expression() for e in lib.fflatten(self.etoks) if e]) if re: re = ' ' + re return (f"({name2}" + re + ')')
def all_tree(p, etok): """Recursively check predicate p is true on etok tree""" return p(etok) and all(p(e) for e in lib.fflatten(etok.etoks) if e)
def get_raw(etoks): """extract the raw fields from a nested list of Etoks and LexTokens""" return lib.flatten([Etok._get_raw1(e) for e in lib.fflatten(etoks)])