Skip to main content

RPly 木兰编程语言定制版

Project description

https://api.travis-ci.com/nobodxbodon/rply.svg

在 rply 0.7.8 的基础上,作了如下修改:

  • 为减小工作量,暂时放弃对 pypy、Python 2 等版本的支持,仅支持 Python 3.7。

  • 各方面中文化:异常信息与标识符命名等;添加中文 API,同时仍然支持原英文 API。

  • 改进:
  • 【试验】通过根据语法规则分词,支持中文无空格语法,演示在此

测试

pytest 运行所有测试用例,或运行单个用例,如 pytest tests/test_both.py

依赖库:py (注:仅支持到 3.10);pytest

在 Python 3.7-3.12 下通过测试:100 passed, 1 skipped

以下为 rply 原始文档。


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.

You can find the documentation online.

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.7, 3.4+, and PyPy. It is also valid RPython for PyPy checkouts from 6c642ae7a0ea onwards.

Project details


Download files

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

Source Distribution

rply_ulang-0.8.4.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

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

rply_ulang-0.8.4-py2.py3-none-any.whl (22.1 kB view details)

Uploaded Python 2Python 3

File details

Details for the file rply_ulang-0.8.4.tar.gz.

File metadata

  • Download URL: rply_ulang-0.8.4.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.1

File hashes

Hashes for rply_ulang-0.8.4.tar.gz
Algorithm Hash digest
SHA256 3e80d84994ff6d4d0228c66d1ecb363f352390d69a914eccc2e6172cf55a95e1
MD5 c82a3c8bbdb1548f795c3f1d23060ec2
BLAKE2b-256 ae8b5b05833a9cc8568601fbaf174d4298b37703784841f633a42e5fdf3e5785

See more details on using hashes here.

File details

Details for the file rply_ulang-0.8.4-py2.py3-none-any.whl.

File metadata

  • Download URL: rply_ulang-0.8.4-py2.py3-none-any.whl
  • Upload date:
  • Size: 22.1 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.0 CPython/3.12.1

File hashes

Hashes for rply_ulang-0.8.4-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 45a1ab5d0c8414fba3690e4208aad1c8b31f1b18fa9bd8c0c66f59f7ed6b7773
MD5 455ab8c5ef1f179133b5c18b79b944f5
BLAKE2b-256 0fc1e98b79c7d7d893c2ff2c12511f4f4caa1c2eae5a2feb3e37742e05e1cde2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page