Source code for parsley

import functools

from ometa.grammar import OMeta
from ometa.runtime import ParseError, EOFError, OMetaBase
from terml.parser import parseTerm as term
from terml.quasiterm import quasiterm

__version__ = '1.3'


def wrapGrammar(g, tracefunc=None):
    def makeParser(input):
        """
        Creates a parser for the given input, with methods for
        invoking each rule.

        :param input: The string you want to parse.
        """
        parser = g(input)
        if tracefunc:
            parser._trace = tracefunc
        return _GrammarWrapper(parser, input)
    makeParser._grammarClass = g
    return makeParser


[docs]def makeGrammar(source, bindings, name='Grammar', unwrap=False, extends=wrapGrammar(OMetaBase), tracefunc=None): """ Create a class from a Parsley grammar. :param source: A grammar, as a string. :param bindings: A mapping of variable names to objects. :param name: Name used for the generated class. :param unwrap: If True, return a parser class suitable for subclassing. If False, return a wrapper with the friendly API. :param extends: The superclass for the generated parser class. :param tracefunc: A 3-arg function which takes a fragment of grammar source, the start/end indexes in the grammar of this fragment, and a position in the input. Invoked for terminals and rule applications. """ g = OMeta.makeGrammar(source, name).createParserClass( unwrapGrammar(extends), bindings) if unwrap: return g else: return wrapGrammar(g, tracefunc=tracefunc)
[docs]def unwrapGrammar(w): """ Access the internal parser class for a Parsley grammar object. """ return getattr(w, '_grammarClass', None) or w
class _GrammarWrapper(object): """ A wrapper for Parsley grammar instances. To invoke a Parsley rule, invoke a method with that name -- this turns x(input).foo() calls into grammar.apply("foo") calls. """ def __init__(self, grammar, input): self._grammar = grammar self._input = input #so pydoc doesn't get trapped in the __getattr__ self.__name__ = _GrammarWrapper.__name__ def __getattr__(self, name): """ Return a function that will instantiate a grammar and invoke the named rule. :param name: Rule name. """ def invokeRule(*args, **kwargs): """ Invoke a Parsley rule. Passes any positional args to the rule. """ try: ret, err = self._grammar.apply(name, *args) except ParseError as e: self._grammar.considerError(e) err = self._grammar.currentError else: try: extra, _ = self._grammar.input.head() except EOFError: return ret else: # problem is that input remains, so: err = ParseError(err.input, err.position + 1, [["message", "expected EOF"]], err.trail) raise err return invokeRule
[docs]def makeProtocol(source, senderFactory, receiverFactory, bindings=None, name='Grammar'): """ Create a Twisted ``Protocol`` factory from a Parsley grammar. :param source: A grammar, as a string. :param senderFactory: A one-argument callable that takes a twisted ``Transport`` and returns a :ref:`sender <senders>`. :param receiverFactory: A one-argument callable that takes the sender returned by the ``senderFactory`` and returns a :ref:`receiver <receivers>`. :param bindings: A mapping of variable names to objects which will be accessible from python code in the grammar. :param name: The name used for the generated grammar class. :returns: A nullary callable which will return an instance of :class:`~.ParserProtocol`. """ from ometa.protocol import ParserProtocol if bindings is None: bindings = {} grammar = OMeta(source).parseGrammar(name) return functools.partial( ParserProtocol, grammar, senderFactory, receiverFactory, bindings)
[docs]def stack(*wrappers): """ Stack some senders or receivers for ease of wrapping. ``stack(x, y, z)`` will return a factory usable as a sender or receiver factory which will, when called with a transport or sender as an argument, return ``x(y(z(argument)))``. """ if not wrappers: raise TypeError('at least one argument is required') def factory(arg): ret = wrappers[-1](arg) for wrapper in wrappers[-2::-1]: ret = wrapper(ret) return ret return factory
__all__ = [ 'makeGrammar', 'wrapGrammar', 'unwrapGrammar', 'term', 'quasiterm', 'makeProtocol', 'stack', ]