Exemple #1
0
    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
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
    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