Skip to main content
https://secure.travis-ci.org/alex/rply.png

Welcome to RPLY! A pure python parser generator, that also works with RPython. It is a more-or-less direct port of David Beazley’s awesome PLY, with a new public API, and RPython support.

Basic API:

from rply import ParserGenerator, LexerGenerator
from rply.token import BaseBox

lg = LexerGenerator()
# Add takes a rule name, and a regular expression that defines the rule.
lg.add("PLUS", r"\+")
lg.add("MINUS", r"-")
lg.add("NUMBER", r"\d+")

lg.ignore(r"\s+")

# This is a list of the token names. precedence is an optional list of
# tuples which specifies order of operation for avoiding ambiguity.
# precedence must be one of "left", "right", "nonassoc".
# cache_id is an optional string which specifies an ID to use for
# caching. It should *always* be safe to use caching,
# RPly will automatically detect when your grammar is
# changed and refresh the cache for you.
pg = ParserGenerator(["NUMBER", "PLUS", "MINUS"],
        precedence=[("left", ['PLUS', 'MINUS'])], cache_id="myparser")

@pg.production("main : expr")
def main(p):
    # p is a list, of each of the pieces on the right hand side of the
    # grammar rule
    return p[0]

@pg.production("expr : expr PLUS expr")
@pg.production("expr : expr MINUS expr")
def expr_op(p):
    lhs = p[0].getint()
    rhs = p[2].getint()
    if p[1].gettokentype() == "PLUS":
        return BoxInt(lhs + rhs)
    elif p[1].gettokentype() == "MINUS":
        return BoxInt(lhs - rhs)
    else:
        raise AssertionError("This is impossible, abort the time machine!")

@pg.production("expr : NUMBER")
def expr_num(p):
    return BoxInt(int(p[0].getstr()))

lexer = lg.build()
parser = pg.build()

class BoxInt(BaseBox):
    def __init__(self, value):
        self.value = value

    def getint(self):
        return self.value

Then you can do:

parser.parse(lexer.lex("1 + 3 - 2+12-32"))

You can also substitute your own lexer. A lexer is an object with a next() method that returns either the next token in sequence, or None if the token stream has been exhausted.

Why do we have the boxes?

In RPython, like other statically typed languages, a variable must have a specific type, we take advantage of polymorphism to keep values in a box so that everything is statically typed. You can write whatever boxes you need for your project.

If you don’t intend to use your parser from RPython, and just want a cool pure Python parser you can ignore all the box stuff and just return whatever you like from each production method.

Error handling

By default, when a parsing error is encountered, an rply.ParsingError is raised, it has a method getsourcepos(), which returns an rply.token.SourcePosition object.

You may also provide an error handler, which, at the moment, must raise an exception. It receives the Token object that the parser errored on.

pg = ParserGenerator(...)

@pg.error
def error_handler(token):
    raise ValueError("Ran into a %s where it wasn't expected" % token.gettokentype())

Python compatibility

RPly is tested and known to work under Python 2.6, 2.7, 3.1, and 3.2. It is also valid RPython for PyPy checkouts from 6c642ae7a0ea onwards.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rply-0.7.1.tar.gz (14.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rply-0.7.1-py2.py3-none-any.whl (16.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file rply-0.7.1.tar.gz.

File metadata

  • Download URL: rply-0.7.1.tar.gz
  • Upload date:
  • Size: 14.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for rply-0.7.1.tar.gz
Algorithm Hash digest
SHA256 d254901aa80a1de01d1fe25e7e7e97e8c70a756903803d24bd27a6a4e6094604
MD5 5e2970627da13d63d904be9a50187485
BLAKE2b-256 b09307cf4bf4964214cb283a12d3446b7065416f641c6071c35265dcda95c7fa

See more details on using hashes here.

File details

Details for the file rply-0.7.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for rply-0.7.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 d35eb78996dca43a2dbce56c426bd70744121298d77fed376b35ecafb137a189
MD5 11f6498c46f360e52ce7a864feef1253
BLAKE2b-256 05e918dbd2fbc12a84e27ff5d79ded2eca49d8fa11759e3fa083168610038b1b

See more details on using hashes here.

Release history Release notifications | RSS feed

0.7.8

2 files

0.7.7

2 files

0.7.6

2 files

0.7.5

2 files

0.7.4

2 files

0.7.3

2 files

0.7.2

2 files

This release

0.7.1 This release

2 files

0.7.0

1 file

0.6.1

1 file

0.6.0

1 file

0.5.1

1 file

0.5

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page