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
|
# -*- coding: utf-8 -*-
from setuptools import setup
packages = \
['funcparserlib']
package_data = \
{'': ['*']}
setup_kwargs = {
'name': 'funcparserlib',
'version': '1.0.0',
'description': 'Recursive descent parsing library based on functional combinators',
'long_description': 'Funcparserlib\n=============\n\nRecursive descent parsing library for Python based on functional combinators.\n\n[](https://pypi.org/project/funcparserlib/)\n[](https://pypi.org/project/funcparserlib/)\n\n\nDescription\n-----------\n\nThe primary focus of `funcparserlib` is **parsing little languages** or **external DSLs** (domain specific languages).\n\nParsers made with `funcparserlib` are pure-Python LL(\\*) parsers. It means that it\'s **very easy to write parsers** without thinking about lookaheads and other hardcore parsing stuff. However, recursive descent parsing is a rather slow method compared to LL(k) or LR(k) algorithms. Still, parsing with `funcparserlib` is **at least twice faster than PyParsing**, a very popular library for Python.\n\nThe source code of `funcparserlib` is only 1.2K lines of code, with lots of comments. Its API is fully type hinted. It features the longest parsed prefix error reporting, as well as a tiny lexer generator for token position tracking.\n\nThe idea of parser combinators used in `funcparserlib` comes from the [Introduction to Functional Programming](https://www.cl.cam.ac.uk/teaching/Lectures/funprog-jrh-1996/) course. We have converted it from ML into Python.\n\n\nInstallation\n------------\n\nYou can install `funcparserlib` from [PyPI](https://pypi.org/project/funcparserlib/):\n\n```shell\n$ pip install funcparserlib\n```\n\nThere are no dependencies on other libraries.\n\n\nDocumentation\n-------------\n\n* [Getting Started](https://funcparserlib.pirx.ru/getting-started/)\n * Your **starting point** with `funcparserlib`\n* [API Reference](https://funcparserlib.pirx.ru/api/)\n * Learn the details of the API\n\nThere are several examples available in the `tests/` directory:\n\n* [GraphViz DOT parser](https://github.com/vlasovskikh/funcparserlib/blob/master/tests/dot.py)\n* [JSON parser](https://github.com/vlasovskikh/funcparserlib/blob/master/tests/json.py)\n\nSee also [the changelog](https://funcparserlib.pirx.ru/changes/).\n\n\nExample\n-------\n\nLet\'s consider a little language of **numeric expressions** with a syntax similar to Python expressions. Here are some expression strings in this language:\n\n```\n0\n1 + 2 + 3\n-1 + 2 ** 32\n3.1415926 * (2 + 7.18281828e-1) * 42\n```\n\n\nHere is **the complete source code** of the tokenizer and the parser for this language written using `funcparserlib`:\n\n```python\nfrom typing import List, Tuple, Union\nfrom dataclasses import dataclass\n\nfrom funcparserlib.lexer import make_tokenizer, TokenSpec, Token\nfrom funcparserlib.parser import tok, Parser, many, forward_decl, finished\n\n\n@dataclass\nclass BinaryExpr:\n op: str\n left: "Expr"\n right: "Expr"\n\n\nExpr = Union[BinaryExpr, int, float]\n\n\ndef tokenize(s: str) -> List[Token]:\n specs = [\n TokenSpec("whitespace", r"\\s+"),\n TokenSpec("float", r"[+\\-]?\\d+\\.\\d*([Ee][+\\-]?\\d+)*"),\n TokenSpec("int", r"[+\\-]?\\d+"),\n TokenSpec("op", r"(\\*\\*)|[+\\-*/()]"),\n ]\n tokenizer = make_tokenizer(specs)\n return [t for t in tokenizer(s) if t.type != "whitespace"]\n\n\ndef parse(tokens: List[Token]) -> Expr:\n int_num = tok("int") >> int\n float_num = tok("float") >> float\n number = int_num | float_num\n\n expr: Parser[Token, Expr] = forward_decl()\n parenthesized = -op("(") + expr + -op(")")\n primary = number | parenthesized\n power = primary + many(op("**") + primary) >> to_expr\n term = power + many((op("*") | op("/")) + power) >> to_expr\n sum = term + many((op("+") | op("-")) + term) >> to_expr\n expr.define(sum)\n\n document = expr + -finished\n\n return document.parse(tokens)\n\n\ndef op(name: str) -> Parser[Token, str]:\n return tok("op", name)\n\n\ndef to_expr(args: Tuple[Expr, List[Tuple[str, Expr]]]) -> Expr:\n first, rest = args\n result = first\n for op, expr in rest:\n result = BinaryExpr(op, result, expr)\n return result\n```\n\nNow, consider this numeric expression: `3.1415926 * (2 + 7.18281828e-1) * 42`.\n\nLet\'s `tokenize()` it using the tokenizer we\'ve created with `funcparserlib.lexer`:\n\n```\n[\n Token(\'float\', \'3.1415926\'),\n Token(\'op\', \'*\'),\n Token(\'op\', \'(\'),\n Token(\'int\', \'2\'),\n Token(\'op\', \'+\'),\n Token(\'float\', \'7.18281828e-1\'),\n Token(\'op\', \')\'),\n Token(\'op\', \'*\'),\n Token(\'int\', \'42\'),\n]\n```\n\nLet\'s `parse()` these tokens into an expression tree using our parser created with `funcparserlib.parser`:\n\n```\nBinaryExpr(\n op=\'*\',\n left=BinaryExpr(\n op=\'*\',\n left=3.1415926,\n right=BinaryExpr(op=\'+\', left=2, right=0.718281828),\n ),\n right=42,\n)\n```\n\nLearn how to write this parser using `funcparserlib` in the [Getting Started](https://funcparserlib.pirx.ru/getting-started/) guide!\n\n\nUsed By\n-------\n\nSome open-source projects that use `funcparserlib` as an explicit dependency:\n\n* [Hy](https://github.com/hylang/hy), a Lisp dialect that\'s embedded in Python\n * 4.2K stars, version `>= 1.0.0a0`, Python 3.7+\n* [Splash](https://github.com/scrapinghub/splash), a JavaScript rendering service with HTTP API, by Scrapinghub\n * 3.6K stars, version `*`. Python 3 in Docker\n* [graphite-beacon](https://github.com/klen/graphite-beacon), a simple alerting system for Graphite metrics\n * 459 stars, version `==0.3.6`, Python 2 and 3\n* [blockdiag](https://github.com/blockdiag/blockdiag), generates block-diagram image file from spec-text file\n * 148 stars, version `>= 1.0.0a0`, Python 3.7+\n* [kll](https://github.com/kiibohd/kll), Keyboard Layout Language (KLL) compiler\n * 109 stars, copied source code, Python 3.5+\n\n\nNext\n----\n\nRead the [Getting Started](https://funcparserlib.pirx.ru/getting-started/) guide to start learning `funcparserlib`.\n',
'author': 'Andrey Vlasovskikh',
'author_email': 'andrey.vlasovskikh@gmail.com',
'maintainer': None,
'maintainer_email': None,
'url': 'https://funcparserlib.pirx.ru',
'packages': packages,
'package_data': package_data,
'python_requires': '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*',
}
setup(**setup_kwargs)
|