/usr/share/pyshared/parsley.py is in python-parsley 1.2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | 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.2'
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
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)
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, 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
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)
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',
]
|