Exemple #1
0
    def __iter__(self):
        if is_forward(self.type):
            if len(self.tokens) != 1:
                Log.error("not expected")

            output = list(self.tokens[0])
            for i in output:
                yield i
            return

        for r in self.tokens:
            if isinstance(r, Annotation):
                continue
            elif isinstance(r, ParseResults):
                if isinstance(r, Annotation):
                    return
                elif isinstance(r.type, Group):
                    yield r
                elif is_forward(r.type) and isinstance(forward_type(r), Group):
                    yield r
                elif not isinstance(r.type, Group):
                    for mm in r:
                        yield mm
            else:
                yield r
 def __init__(self, result_type, start, end, tokens):
     if end == -1:
         Log.error("not allowed")
     self.type = result_type
     self.start = start
     self.end = end
     self.tokens = tokens
Exemple #3
0
    def __init__(self, pattern, flags=0, asGroupList=False, asMatch=False):
        """The parameters ``pattern`` and ``flags`` are passed
        to the ``regex_compile()`` function as-is. See the Python
        `re module <https://docs.python.org/3/library/re.html>`_ module for an
        explanation of the acceptable patterns and flags.
        """
        Token.__init__(self)

        if isinstance(pattern, text):
            if not pattern:
                warnings.warn(
                    "null string passed to Regex; use Empty() instead",
                    SyntaxWarning,
                    stacklevel=2,
                )

            try:
                self.set_config(flags=flags, regex=re.compile(pattern, flags))
            except sre_constants.error as cause:
                Log.error(
                    "invalid pattern {{pattern}} passed to Regex",
                    pattern=pattern,
                    cause=cause,
                )
        elif isinstance(pattern, regex_type):
            self.set_config(flags=flags, regex=pattern)
        else:
            Log.error(
                "Regex may only be constructed with a string or a compiled RE object"
            )

        self.parser_name = text(self)
Exemple #4
0
    def _parse(self, string, start, doActions=True):
        lookup = (self, string, start, doActions)
        value = packrat_cache.get(lookup)
        if value is not None:
            if isinstance(value, Exception):
                raise value
            return value

        try:
            index = self.engine.skip(string, start)
            try:
                result = self.parseImpl(string, index, doActions)
            except Exception as cause:
                self.parser_config.failAction and self.parser_config.failAction(
                    self, start, string, cause
                )
                raise

            if self.parseAction and (doActions or self.parser_config.callDuringTry):
                for fn in self.parseAction:
                    next_result = fn(result, index, string)
                    if next_result.end < result.end:
                        fn(result, index, string)
                        Log.error("parse action not allowed to roll back the end of parsing")
                    result = next_result
        except ParseException as cause:
            packrat_cache.set(lookup, cause)
            raise

        packrat_cache.set(lookup, result)
        return result
Exemple #5
0
 def __init__(self, tokens, loc, string):
     if not isinstance(string, str):
         Log.error("expecting string")
     self.pstr = string
     self.loc = loc
     self.parserElement = tokens
     self._msg = ""
Exemple #6
0
def repeat(tokens):
    if tokens.length() == 1:
        return tokens.value()

    try:
        operand, operator = tokens
    except Exception as cause:
        Log.error("not expected", cause=cause)

    mode = operator["mode"]
    if not mode:
        if operator["exact"]:
            return Many(operand, PLAIN_ENGINE, exact=int(operator["exact"]))
        else:
            return Many(operand,
                        PLAIN_ENGINE,
                        min_match=int(operator["min"]),
                        max_match=int(operator["max"]))
    elif mode in "*?":
        return ZeroOrMore(operand, PLAIN_ENGINE)
    elif mode in "+?":
        return OneOrMore(operand, PLAIN_ENGINE)
    elif mode == "?":
        return Optional(operand, PLAIN_ENGINE)
    else:
        Log.error("not expected")
Exemple #7
0
    def __setitem__(self, k, v):
        if isinstance(k, (slice, int)):
            Log.error("not supported")

        if v is None:
            v = NO_RESULTS

        if is_forward(self):
            self.tokens[0][k] = v
            return

        for i, tok in enumerate(self.tokens):
            if isinstance(tok, ParseResults):
                if tok.name == k:
                    self.tokens[i] = v
                    v = NO_RESULTS  # ERASE ALL OTHERS
                elif isinstance(tok.type, Group):
                    continue
                elif is_forward(tok.type) and isinstance(
                        tok.tokens[0].type, Group):
                    continue
                elif tok.name:
                    continue

                tok.__setitem__(k, NO_RESULTS)  # ERASE ALL CHILDREN

        if v is not NO_RESULTS:
            self.tokens.append(Annotation(k, [v]))
Exemple #8
0
 def __new__(cls, matchString, identChars=None, caseless=None):
     if len(matchString) == 0:
         Log.error("Expecting more than one character in keyword")
     if caseless:
         return object.__new__(CaselessKeyword)
     else:
         return object.__new__(cls)
Exemple #9
0
    def __init__(self, match):
        Token.__init__(self)
        self.set_config(match=match)

        if len(match) == 0:
            Log.error("Literal must be at least one character")
        elif len(match) == 1:
            self.__class__ = SingleCharLiteral
Exemple #10
0
 def min_length(self):
     if not hasattr(self, "min_cache"):
         Log.error("should not happen")
     if self.min_cache >= 0:
         return self.min_cache
     min_ = self._min_length()
     if self.streamlined:
         self.min_cache = min_
     return min_
 def __init__(self, expr, start, string, msg="", cause=None):
     if not isinstance(string, str):
         Log.error("expecting string")
     self.expr = expr
     self.start = start
     self.string = string
     self._msg = msg
     self.unsorted_cause = cause
     self._causes = None
Exemple #12
0
    def output(*args, **kwargs):
        with locker:
            for a in _reset_actions:
                try:
                    a()
                except Exception as e:
                    Log.error("reset action failed", cause=e)

            return func(*args, **kwargs)
Exemple #13
0
def add(obj, key, value):
    if not isinstance(value, list):
        Log.error("not allowed")
    if value and isinstance(value[0], list):
        Log.error("not expected")
    old_v = obj.get(key)
    if old_v is None:
        obj[key] = value
    else:
        old_v.extend(value)
Exemple #14
0
    def __init__(self, matchString):
        Token.__init__(self)
        self.match = matchString
        self.parser_config.mayReturnEmpty = False
        self.parser_config.mayIndexError = False

        if len(matchString) == 0:
            Log.error("Literal must be at least one character")
        if len(matchString) == 1:
            self.__class__ = _SingleCharLiteral
Exemple #15
0
    def __lshift__(self, other):
        self.strRepr = ""
        if other == None:
            Log.error("can not set to None")
        if is_forward(self.expr):
            return self.expr << other

        while is_forward(other):
            other = other.expr
        self.expr = engine.CURRENT.normalize(other)
        return self
Exemple #16
0
 def parseImpl(self, string, loc, doActions=True):
     try:
         result = self.expr._parse(string, loc, doActions)
         return ParseResults(self, result.start, result.end, [result])
     except Exception as cause:
         if is_null(self.expr):
             Log.warning(
                 "Ensure you have assigned a ParserElement (<<) to this Forward",
                 cause=cause,
             )
         raise cause
Exemple #17
0
    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        ENSURE self IS NOT CURRENT
        :return:
        """
        global CURRENT
        if not self.previous:
            Log.error("expecting engine to be released just once")

        CURRENT = self.previous
        self.previous = None
Exemple #18
0
    def __call__(self, name):
        if not name:
            return self

        for e in [self.expr]:
            if isinstance(e, ParserElement) and e.token_name == name:
                Log.error(
                    "can not set token name, already set in one of the other"
                    " expressions")

        return ParseEnhancement.__call__(self, name)
Exemple #19
0
 def clear(self):
     if DEBUG and self.hit + self.miss > 100:
         Log.note(
             "Hit Rate: {{rate|round(places=2)|percent}} (hits={{hits}},"
             " misses={{misses}})",
             rate=self.hit / (self.hit + self.miss),
             hits=self.hit,
             misses=self.miss,
         )
     self.hit = 0
     self.miss = 0
     self.cache.clear()
Exemple #20
0
 def drill(e):
     if isinstance(e, Literal):
         chars.add(e.parser_config.match)
     elif isinstance(e, Char):
         chars.update(c for c in e.parser_config.include)
     elif isinstance(e, MatchFirst):
         for ee in e.exprs:
             drill(ee)
     elif isinstance(e, And):
         drill(e.exprs[0].expr)
     else:
         Log.error("logic error")
Exemple #21
0
def to_bracket(tokens):
    acc = []
    for e in listwrap(tokens["body"].value()):
        if isinstance(e, SingleCharLiteral):
            acc.append(e.parser_config.match)
        elif isinstance(e, Char):
            acc.extend(e.parser_config.include)
        else:
            Log.error("programmer error")
    if tokens["negate"]:
        return Char(exclude=acc)
    else:
        return Char(acc)
Exemple #22
0
 def parseImpl(self, string, loc, doActions=True):
     try:
         temp = self.expr
         result = self.expr._parse(string, loc, doActions)
         loc, output = result
         return loc, ParseResults(self, [output])
     except Exception as cause:
         if self.expr == None:
             Log.warning(
                 "Ensure you have assigned a ParserElement (<<) to this Forward",
                 cause=cause,
             )
         raise cause
Exemple #23
0
    def parseImpl(self, string, start, doActions=True):
        instrlen = len(string)
        fail = self.parser_config.fail
        ignore = self.parser_config.ignore

        loc = start
        while loc <= instrlen:
            if fail:
                # break if failOn expression matches
                if fail.canParseNext(string, loc):
                    before_end = loc
                    break

            if ignore:
                # advance past ignore expressions
                while 1:
                    try:
                        loc = ignore.tryParse(string, loc)
                        if loc == None:
                            Log.error("")
                    except ParseException:
                        break
            try:
                before_end = loc
                loc = self.expr._parse(string, loc, doActions=False).end
                if loc == None:
                    Log.error("")
            except ParseException:
                # no match, advance loc in string
                loc += 1
            else:
                # matched skipto expr, done
                break

        else:
            # ran off the end of the input string without matching skipto expr, fail
            raise ParseException(self, start, string)

        # build up return values
        end = loc
        skiptext = string[start:before_end]
        skip_result = []
        if skiptext:
            skip_result.append(skiptext)

        if self.parser_config.include:
            end_result = self.expr._parse(string, before_end, doActions)
            skip_result.append(end_result)
            return ParseResults(self, start, end, skip_result)
        else:
            return ParseResults(self, start, before_end, skip_result)
Exemple #24
0
 def cond(token, index, string):
     result = fn(token, index, string)
     if not bool(result.tokens[0]):
         if fatal:
             Log.error("fatal error",
                       casue=ParseException(token.type,
                                            index,
                                            string,
                                            msg=message))
         raise ParseException(token.type,
                              index,
                              string,
                              msg=message)
     return token
Exemple #25
0
    def normalize(self, expr):
        if expr == None:
            return None
        if is_text(expr):
            if issubclass(self.literal, Token):
                return self.literal(expr)
            else:
                return self.literal(Literal(expr))
        if isinstance(expr, type) and issubclass(expr, ParserElement):
            return expr()  # ALLOW Empty WHEN Empty() WAS INTENDED
        if not isinstance(expr, ParserElement):
            Log.error("expecting string, or ParserElemenet")

        return expr
Exemple #26
0
 def __getattr__(self, item):
     """
     IF THERE IS ONLY ONE VALUE, THEN DEFER TO IT
     """
     iter = self.__iter__()
     try:
         v1 = iter.__next__()
         try:
             iter.__next__()
             raise Log.error("No attribute {{item}} for mutiple tokens",
                             item=item)
         except Exception:
             return getattr(v1, item)
     except Exception:
         raise Log.error("No attribute {{item}}", item=item)
Exemple #27
0
    def output(*args, **kwargs):
        with locker:
            for a in _reset_actions:
                try:
                    a()
                except Exception as e:
                    Log.error("reset action failed", cause=e)

            self = args[0]
            if not self.streamlined and (
                not is_forward(self) or not self.expr.streamlined
            ):
                Log.alert("Expecting expression to be streamlined before use")
                self = self.streamline()
            return func(self, *args[1:], **kwargs)
Exemple #28
0
    def normalize(self, expr):
        if expr == None:
            return Null
        if is_text(expr):
            if issubclass(self.literal, Token):
                return self.literal(expr)
            else:
                return self.literal(Literal(expr))
        if not isinstance(expr, ParserElement):
            Log.error("expecting string, or ParserElemenet")

        # curr_engine = expr.engine
        # if curr_engine != self and not expr.parser_config.lock_engine:
        #     # UPDATE ENGINE IF NOT LOCKED
        #     expr = expr.copy()
        return expr
Exemple #29
0
 def __eq__(self, other):
     if other == None:
         return not self.__bool__()
     elif is_text(other):
         try:
             return "".join(self) == other
         except Exception as e:
             return False
     elif is_many(other):
         return all(s == o for s, o in zip_longest(self, other))
     elif self.length() == 1:
         return self[0] == other
     elif not self:
         return False
     else:
         Log.error("do not know how to handle")
Exemple #30
0
    def _parse(self, string, start, doActions=True):
        try:
            result = self.parseImpl(string, start, doActions)
        except Exception as cause:
            self.parser_config.failAction and self.parser_config.failAction(
                self, start, string, cause)
            raise

        if doActions or self.parser_config.callDuringTry:
            for fn in self.parseAction:
                next_result = fn(result, result.start, string)
                if next_result.end < result.end:
                    Log.error(
                        "parse action not allowed to roll back the end of parsing"
                    )
                result = next_result
        return result