コード例 #1
0
def parse(input_string, parse_as=None):
    """Attempt to parse a string into a choices dictionary.

    Args:
        input_string: The string to parse
        parse_as: String specifying how to parse `input_string`. Valid values are
            'func' or 'url'. Will try all valid values if None.

    Returns:
        Dictionary containing the parse results

    Raises:
        lark.common.ParseError: Unable to find a valid parsing of `input_string`
    """
    def _parse(_input_string, _parser):
        try:
            return FunctionTransformer().transform(
                _parser.parse(_input_string))
        except (GrammarError, LexError, ParseError) as e:
            raise ParseError(e)

    if parse_as is not None:
        return _parse(input_string, parsers[parse_as])
    else:
        for parser in parsers.values():
            try:
                return _parse(input_string, parser)
            except ParseError:
                continue

    raise ParseError('Unable to successfully parse input "%s"' % input_string)
コード例 #2
0
    def __getattr__(self, attr: str):
        """Also parse propositional logic."""

        if attr.startswith("pl__"):
            return getattr(self._pl_transformer, attr[4:])
        elif attr in self._pl_imported:
            return getattr(self._pl_transformer, attr)
        elif attr.isupper():
            raise AttributeError("Terminals should not be parsed")
        else:
            raise ParseError("No transformation exists for rule", attr)
コード例 #3
0
ファイル: parser.py プロジェクト: defseg/PyLaut
    def member(
        self, args: List[Union[Callable[[Transducer], PyLautAtom], str]]
    ) -> Callable[[PyLautAtom], PyLautAtom]:
        """
        Translates member access on transducer data. Right now all the
        legal options are hard-coded in. In the future, it might be
        desirable to translate everything down into direct method calls
        using the same nomenclature, allowing featuresets / phone subclasses
        to provide them or not.

        :param list args: a fetcher function and a string indicated what should
                          be fetched from its result.
        :returns: Another fetcher function.
        """
        entity = args[0]
        field = args[1]
        if isinstance(entity, tuple):
            entity = entity[1]

        if field == 'nucleus':

            def ret(td, f=entity):
                return f(td).get_nucleus()
        elif field == 'onset':

            def ret(td, f=entity):
                return f(td).get_onset()
        elif field == 'coda':

            def ret(td, f=entity):
                return f(td).get_coda()
        elif field == 'quality':

            def get_vowel_quality(td, f=entity):
                # f(td) must produce a vowel!
                e = f(td)
                if isinstance(e, list):
                    vowel = e[0].copy()
                else:
                    vowel = e.copy()
                vowel.set_features_false("long")
                vowel.set_symbol_from_features()
                return vowel

            ret = get_vowel_quality
        elif field == 'is_monosyllable':

            def ret(td, f=entity):
                return f(td).is_monosyllable()
        else:
            raise ParseError("Unknown field {}!".format(field))

        return ret
コード例 #4
0
 def _parse(_input_string, _parser):
     try:
         return FunctionTransformer().transform(
             _parser.parse(_input_string))
     except (GrammarError, LexError, ParseError) as e:
         raise ParseError(e)
コード例 #5
0
    def relative_expr(self, args):
        """
        This method translates relative position expressions in sound change
        conditions. It is quite convoluted, due to the fact that there are
        many different ways to construct a relative expression and argument
        types may be freely mixed.

        :param list args: The list of position parameters.
        :returns: A predicate function on a transducer.
        """
        # First, check if there are word boundaries specified
        # If yes, check if they are in a legal position.
        # If still yes, set a flag.
        conditions = []
        wordbreak = None
        if "#" in args:
            if args[0] == "#":
                wordbreak = 1
                args = args[1:]
            elif args[-1] == "#":
                wordbreak = -1
                args = args[:-1]
            else:
                raise ParseError("Relative Expr contains '#' that is not at "
                                 "the edge of the expression.")

        this = args.index("_")

        for i in range(len(args)):
            pos = i - this
            arg = args[i]
            # If the argument is a phoneme, we must unpack it.
            if isinstance(arg, list):
                arg = arg[0]
            if isinstance(arg, tuple):
                arg = arg[0]
            if isinstance(arg, str):
                # If the argument is the current position indicator
                # and there is a word break specified: add a check whether
                # the current phoneme is at the correct offset from the
                # word break.
                if arg == "_":
                    if wordbreak:
                        if wordbreak > 0:
                            conditions.append(This.is_at_index(Phone, i))
                        else:
                            relpos = -(len(args) - i)
                            conditions.append(This.is_at_index(Phone, relpos))
                # Otherwise, assume the string is a phone written without
                # slashes.
                else:
                    for p in arg:
                        conditions.append(
                            This.at(Phone, pos, lambda q, p=p: q.is_symbol(p)))
            elif isinstance(arg, dict):
                # If the argument is a dictionary, we have a feature expression
                # Match the features according to the expression
                for k, v in arg.items():
                    conditions.append(
                        This.at(Phone,
                                pos,
                                lambda p, k=k, v=v: p.feature_is(k, v)))
            else:
                # The argument is a Phone
                # Perform by-symbol matching
                s = arg.symbol
                conditions.append(
                    This.at(Phone, pos, lambda q, s=s: q.is_symbol(s)))

        def run_conditions(td, c=conditions):
            """
            Function that closes over the condition list
            from the relative expression translation.
            """
            for f in c:
                try:
                    if not f(td):
                        return False
                except IndexError:
                    return False
            return True

        return run_conditions