def __call__(self, inp: str, parse_inp: ParseResult = None, idx: int = 0) -> ParseResult: # Handle the 'zeroth' time empty_result = self.E(inp, parse_inp=parse_inp, idx=idx) result = self.A(inp, parse_inp=empty_result) if len(result) == 0: return empty_result if len(result) == 1: return result # run this zero or more times up to unlimited bound start_idx = result.last_idx() while True: new_result = self.A(inp, idx=result.last_idx()) if new_result.last_idx() <= result.last_idx() or new_result.empty( ): break result = new_result parser_out = ParseResult() parser_out.extend(empty_result) # if we dont accept partial results and haven't consumed the # whole input then return an empty result #if not self.accept_partial and result.last_idx() < len(inp): # return parser_out parser_out.add(result.last_idx(), inp[start_idx - 1:result.last_idx()]) return parser_out
def __call__(self, inp: str, parse_inp: ParseResult = None, idx: int = 0) -> ParseResult: prev_result = parse_inp if parse_inp is not None else ParseResult() start_idx = prev_result.last_idx() # keep parsing more tokens for as long as we can # NOTE: this implementation here seems much more complicated than # it needs to be.... while True: new_result = self.A(inp, idx=prev_result.last_idx()) if new_result.empty( ) or new_result.last_idx() <= prev_result.last_idx(): break prev_result = new_result parser_out = ParseResult() # if we dont accept partial results and haven't consumed the # whole input then return an empty result #if not self.accept_partial and result.last_idx() < len(inp): # return parser_out parser_out.add(prev_result.last_idx(), inp[start_idx:prev_result.last_idx()]) return parser_out
def __call__(self, inp:str, parse_inp:ParseResult=None, idx:int=0) -> ParseResult: if parse_inp is not None: idx = parse_inp.last_idx() else: idx = 0 parse_result = ParseResult() for target_idx, c in enumerate(inp[idx:]): if not c.isspace(): break parse_result.add(idx + target_idx + 1, inp[idx : idx + target_idx+1]) return parse_result
def test_kleene_star_char(self) -> None: p = CharParser('a') ks = combinator.KleeneStar(p) # expected outputs exp_outputs = [ ParseResult(0, ''), # '' ParseResult(0, ''), # 'a' ParseResult(0, ''), # 'aa' ParseResult(0, ''), # 'aaa' ParseResult(0, ''), # 'aaaa' ParseResult(0, ''), # 'aaabcdefg' ] # 'a' exp_outputs[1].add(1, 'a') # 'aa' exp_outputs[2].add(2, 'aa') # 'aaa' exp_outputs[3].add(3, 'aaa') # 'aaaa' exp_outputs[4].add(4, 'aaaa') # 'aaabcdefg' exp_outputs[5].add(3, 'aaa') # Parse the strings results = [] for inp in self.inp_strings_alpha: results.append(ks(inp)) print('%s results for each string :' % str(ks)) for n, r in enumerate(results): print(n, r, repr(ks), self.inp_strings_alpha[n]) assert len(results) == len(exp_outputs) for n, (exp, out) in enumerate(zip(exp_outputs, results)): print("[%d / %d] : comparing %s -> %s" % \ (n, len(results), str(exp), str(out)) ) assert exp == out # if we turn on partial match then we should get 'aaa' as the # result for the input string 'aaabcdefg' exp_partial_match = ParseResult(0, '') exp_partial_match.add(3, 'aaa') ks.accept_partial = True partial_match_result = ks(self.inp_strings_alpha[5]) assert exp_partial_match == partial_match_result
def __call__(self, inp: str, parse_inp: ParseResult = None, idx: int = 0) -> ParseResult: prev_result = parse_inp if parse_inp is not None else ParseResult() start_idx = prev_result.last_idx() while True: new_result = self.A(inp, idx=prev_result.last_idx()) if new_result.empty( ) or new_result.last_idx() <= prev_result.last_idx(): break prev_result = new_result parser_out = ParseResult() parser_out.add(prev_result.last_idx(), inp[start_idx:prev_result.last_idx()]) return parser_out
def __call__(self, inp:str, parse_inp:ParseResult=None, idx:int=0) -> ParseResult: if parse_inp is not None: idx = parse_inp.last_idx() else: idx = 0 parse_result = ParseResult() for target_idx, c in enumerate(inp[idx:]): if c.isalpha(): continue elif target_idx > 0 and (c.isalnum() or c == '-'): continue else: break if target_idx == 0: return parse_result parse_result.add(idx + target_idx + 1, inp[idx : idx + target_idx+1]) return parse_result
def __call__(self, inp: str, parse_inp: ParseResult = None, idx: int = 0) -> ParseResult: result = self.A(inp, parse_inp=parse_inp) if len(result) == 0: return result #if len(result) == 1: # return result # run this zero or more times up to unlimited bound start_idx = result.last_idx() while True: new_result = self.A(inp, idx=result.last_idx()) if new_result.last_idx() <= result.last_idx() or new_result.empty( ): break result = new_result parser_out = ParseResult() parser_out.add(result.last_idx(), inp[start_idx - 1:result.last_idx()]) return parser_out