def match(self, tr): tr = list( map(_SearchTerm, tr)) # XXX: hopefully can remove _SearchTerm w/ new symmetries printq('Complete!\n\nSearching for match...') start, *in_napkin, end = tr if len(in_napkin) != self.trlen: raise Error( None, f'Bad length for match (expected {2+self.trlen} states, got {2+len(in_napkin)})' ) in_trs = [(start, *napkin, end) for napkin in self.symmetries(in_napkin).expand()] question_indices = [i for i, v in enumerate(tr) if v.request_idx] for tr in self._data: for in_tr in in_trs: # to know whether to abort on no match, or to continue in # hopes that the wildcard is valid elsewhere tripped_wildcard = False for cur_len, (in_state, tr_state) in enumerate(zip(in_tr, tr), -1): if in_state.is_wildcard: tripped_wildcard = True continue if (in_state.value not in tr_state if isinstance( tr_state, Iterable) else in_state.value != getattr( tr_state, 'value', tr_state)): if not tripped_wildcard and cur_len == self.trlen: lno, start, end = tr.ctx return ( 'No match\n\n' f'Impossible match!\nOverridden on line {self.start+lno} by:\n {self[lno-1]}\n' f'''{"" if start == 1 else f" {' '*(start-1)}{'^'*(end-start)}"}\n''' # TODO FIXME: deuglify f"Specifically (compiled line):\n {', '.join(map(str, tr.fix_vars()))}" ) break else: lno, start, end = tr.ctx fixed_tr = tr.fix_vars() separator = '\n\n\n' if question_indices else '' _NEWLINE = '\n' # for fstring... return ( 'Found!\n\n' f'Line {self.start+lno}:\n {self[lno-1]}\n' f'''{"" if start == 1 else f" {' '*(start-1)}{'^'*(end-start)}"}\n''' # TODO FIXME: deuglify f"Compiled line:\n {', '.join(map(str, tr.fix_vars()))}" f'''{separator}{_NEWLINE.join( f"* TERM #{n} ('{fixed_tr[n]}') is one of {tr[n].untether()}" if isinstance(tr[n], StateList) else f'* TERM #{n} is {tr[n]}' for n in question_indices ) }''') if start == end: return 'No match\n\nThis transition is the result of unspecified default behavior' return 'No match'
def transpile(fp, *, find=None): """ Performs the parsing process from start to finish """ printq('\nParsing...') parsed = segmentor.parse(fp) if find: print(parsed['@TABLE'].match(find) + '\n') return printq('Complete!', 'Compiling...', sep='\n\n') return compiler.compile(parsed)
def _main(): inp = cli \ .prepare(strict=True, propagate_unknowns=True) \ .set_defaults(quiet=False) \ .result if inp is None: return if 'transpile' in inp: res = _transpile(inp.transpile) elif 'icon' in inp: res = tools.dispatch(inp.icon) for val in res: printq(*val, sep='\n')
def match(self, tr): printq('Complete!\n\nSearching for match...') start, *in_napkin, end = tr if len(in_napkin) != self.trlen: raise Error( None, f'Bad length for match (expected {2+self.trlen} states, got {2+len(in_napkin)})' ) in_trs = [(start, *napkin, end) for napkin in self.symmetries(in_napkin).expand()] for tr in self._data: for in_tr in in_trs: for cur_len, (in_state, tr_state) in enumerate(zip(in_tr, tr), -1): if in_state != '*' and not ( in_state in tr_state if isinstance( tr_state, Iterable) else in_state == getattr( tr_state, 'value', tr_state)): if cur_len == self.trlen: lno, start, end = tr.ctx return ( 'No match\n\n' f'Impossible match!\nOverridden on line {self.start+lno} by:\n {self[lno-1]}\n' f"""{"" if start == 1 else f" {' '*(start-1)}{'^'*(end-start)}"}\n""" # TODO FIXME: deuglify f"Specifically (compiled line):\n {', '.join(map(str, tr.fix_vars()))}" ) break else: lno, start, end = tr.ctx return ( 'Found!\n\n' f'Line {self.start+lno}:\n {self[lno-1]}\n' f"""{"" if start == 1 else f" {' '*(start-1)}{'^'*(end-start)}"}\n""" # TODO FIXME: deuglify f"Compiled line:\n {', '.join(map(str, tr.fix_vars()))}" ) if start == end: return 'No match\n\nThis transition is the result of unspecified default behavior' return 'No match'