{ "info": { "author": "Marko Ristin", "author_email": "marko@parquery.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3.5" ], "description": "Lexery\n======\n.. image:: https://travis-ci.com/Parquery/lexery.svg?branch=master\n :target: https://travis-ci.com/Parquery/lexery\n\n.. image:: https://coveralls.io/repos/github/Parquery/lexery/badge.svg?branch=master\n :target: https://coveralls.io/github/Parquery/lexery?branch=master\n\nA simple lexer based on regular expressions.\n\nInspired by https://eli.thegreenplace.net/2013/06/25/regex-based-lexical-analysis-in-python-and-javascript\n\nUsage\n=====\nYou define the lexing rules and lexery matches them iteratively as a look-up:\n\n.. code-block:: python\n\n >>> import lexery\n >>> import re\n >>> text = 'crop \\t ( 20, 30, 40, 10 ) ;'\n >>>\n >>> lexer = lexery.Lexer(\n ... rules=[\n ... lexery.Rule(identifier='identifier',\n ... pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),\n ... lexery.Rule(identifier='lpar', pattern=re.compile(r'\\(')),\n ... lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),\n ... lexery.Rule(identifier='rpar', pattern=re.compile(r'\\)')),\n ... lexery.Rule(identifier='comma', pattern=re.compile(r',')),\n ... lexery.Rule(identifier='semi', pattern=re.compile(r';'))\n ... ],\n ... skip_whitespace=True)\n >>> tokens = lexer.lex(text=text)\n >>> assert tokens == [[\n ... lexery.Token('identifier', 'crop', 0, 0), \n ... lexery.Token('lpar', '(', 9, 0),\n ... lexery.Token('number', '20', 11, 0),\n ... lexery.Token('comma', ',', 13, 0),\n ... lexery.Token('number', '30', 15, 0),\n ... lexery.Token('comma', ',', 17, 0),\n ... lexery.Token('number', '40', 19, 0),\n ... lexery.Token('comma', ',', 21, 0),\n ... lexery.Token('number', '10', 23, 0),\n ... lexery.Token('rpar', ')', 26, 0),\n ... lexery.Token('semi', ';', 28, 0)]]\n\nMind that if a part of the text can not be matched, a ``lexery.Error`` is raised:\n\n.. code-block:: python\n\n >>> import lexery\n >>> import re\n >>> text = 'some-identifier ( 23 )'\n >>>\n >>> lexer = lexery.Lexer(\n ... rules=[\n ... lexery.Rule(identifier='identifier', pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),\n ... lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),\n ... ],\n ... skip_whitespace=True)\n >>> tokens = lexer.lex(text=text)\n Traceback (most recent call last):\n ...\n lexery.Error: Unmatched text at line 0 and position 4:\n some-identifier ( 23 )\n ^\n\nIf you specify an ``unmatched_identifier``, all the unmatched characters are accumulated in tokens with that identifier:\n\n.. code-block:: python\n\n >>> import lexery\n >>> import re\n >>> text = 'some-identifier ( 23 )-'\n >>>\n >>> lexer = lexery.Lexer(\n ... rules=[\n ... lexery.Rule(identifier='identifier', pattern=re.compile(r'[a-zA-Z_][a-zA-Z_]*')),\n ... lexery.Rule(identifier='number', pattern=re.compile(r'[1-9][0-9]*')),\n ... ],\n ... skip_whitespace=True,\n ... unmatched_identifier='unmatched')\n >>> tokens = lexer.lex(text=text)\n >>> assert tokens == [[\n ... lexery.Token('identifier', 'some', 0, 0),\n ... lexery.Token('unmatched', '-', 4, 0),\n ... lexery.Token('identifier', 'identifier', 5, 0),\n ... lexery.Token('unmatched', '(', 16, 0),\n ... lexery.Token('number', '23', 18, 0),\n ... lexery.Token('unmatched', ')-', 21, 0)]]\n\n\nInstallation\n============\n\n* Install lexery with pip:\n\n.. code-block:: bash\n\n pip3 install lexery\n\nDevelopment\n===========\n\n* Check out the repository.\n\n* In the repository root, create the virtual environment:\n\n.. code-block:: bash\n\n python3 -m venv venv3\n\n* Activate the virtual environment:\n\n.. code-block:: bash\n\n source venv3/bin/activate\n\n* Install the development dependencies:\n\n.. code-block:: bash\n\n pip3 install -e .[dev]\n\nPre-commit Checks\n-----------------\nWe provide a set of pre-commit checks that run unit tests, lint and check code for formatting.\n\nNamely, we use:\n\n* `yapf `_ to check the formatting.\n* The style of the docstrings is checked with `pydocstyle `_.\n* Static type analysis is performed with `mypy `_.\n* Various linter checks are done with `pylint `_.\n\nRun the pre-commit checks locally from an activated virtual environment with development dependencies:\n\n.. code-block:: bash\n\n ./precommit.py\n\n* The pre-commit script can also automatically format the code:\n\n.. code-block:: bash\n\n ./precommit.py --overwrite\n\n\nVersioning\n==========\nWe follow `Semantic Versioning `_. The version X.Y.Z indicates:\n\n* X is the major version (backward-incompatible),\n* Y is the minor version (backward-compatible), and\n* Z is the patch version (backward-compatible bug fix).", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/Parquery/lexery", "keywords": "lexer regexp regular expression", "license": "License :: OSI Approved :: MIT License", "maintainer": "", "maintainer_email": "", "name": "lexery", "package_url": "https://pypi.org/project/lexery/", "platform": "", "project_url": "https://pypi.org/project/lexery/", "project_urls": { "Homepage": "https://github.com/Parquery/lexery" }, "release_url": "https://pypi.org/project/lexery/1.1.0/", "requires_dist": null, "requires_python": "", "summary": "A simple lexer based on regular expressions", "version": "1.1.0" }, "last_serial": 5410386, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "7cd9f9aec65ebc89fcb6ad7d7b1b0b84", "sha256": "a9fb9b03dbe27712cfa7edca6c5928ede11458e928ac75068aeec0f56c6b7173" }, "downloads": -1, "filename": "lexery-1.0.0.tar.gz", "has_sig": false, "md5_digest": "7cd9f9aec65ebc89fcb6ad7d7b1b0b84", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2396, "upload_time": "2018-02-22T05:53:55", "url": "https://files.pythonhosted.org/packages/53/1c/a31acff3cc94bc73b5da77b454bf5131a990e6267b3c7b1116608730cb64/lexery-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "1ea31fb6d1a01598377d472a2603ce3b", "sha256": "54ccddb3e706ed95d230c3bb8e80d9e104dc9ab7a4e103d76f2de83c4db06c59" }, "downloads": -1, "filename": "lexery-1.0.1.tar.gz", "has_sig": false, "md5_digest": "1ea31fb6d1a01598377d472a2603ce3b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2777, "upload_time": "2018-03-24T04:38:39", "url": "https://files.pythonhosted.org/packages/81/69/db6395a4b263d6e44095e50b3b8e3ba90cf6e9504e8baffb43a82d66d371/lexery-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "1e40ea991ca17f127e8a5f63b5ad8694", "sha256": "1fa5373193e80d3c0839e46913b6f328310cef6eaf7c1c467579b24aeb18f7ae" }, "downloads": -1, "filename": "lexery-1.0.2.tar.gz", "has_sig": false, "md5_digest": "1e40ea991ca17f127e8a5f63b5ad8694", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 2965, "upload_time": "2018-08-27T13:54:14", "url": "https://files.pythonhosted.org/packages/b0/37/1bb904586fd3077553abb08cbd4070cff510cc569243aeefeb564b9362dc/lexery-1.0.2.tar.gz" } ], "1.0.3": [ { "comment_text": "", "digests": { "md5": "b2e43c942983bd1ea37c16e991eff930", "sha256": "a5b3cd7b55dafb30011adce0d3bf2deba6b9ab3bea0cf72882f1764bb0a0a6e1" }, "downloads": -1, "filename": "lexery-1.0.3.tar.gz", "has_sig": false, "md5_digest": "b2e43c942983bd1ea37c16e991eff930", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 4348, "upload_time": "2018-08-27T15:31:03", "url": "https://files.pythonhosted.org/packages/e7/b4/e74c6df8a0d2fa891873d63198cead3fa83bbf16ab493608105f85ad4746/lexery-1.0.3.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "13e5caace775d7db092a6dc30da86c60", "sha256": "361c7f2a44f79a884549bceb9f2190d587661d559e4c9bec37bc8678a61e7ec0" }, "downloads": -1, "filename": "lexery-1.1.0.tar.gz", "has_sig": false, "md5_digest": "13e5caace775d7db092a6dc30da86c60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5000, "upload_time": "2018-08-27T16:17:29", "url": "https://files.pythonhosted.org/packages/96/88/5bc1a8dfaa0bdcfdd3e3150f78f7f8384b0e65ac8a78c8d1f40d2fad6518/lexery-1.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "13e5caace775d7db092a6dc30da86c60", "sha256": "361c7f2a44f79a884549bceb9f2190d587661d559e4c9bec37bc8678a61e7ec0" }, "downloads": -1, "filename": "lexery-1.1.0.tar.gz", "has_sig": false, "md5_digest": "13e5caace775d7db092a6dc30da86c60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5000, "upload_time": "2018-08-27T16:17:29", "url": "https://files.pythonhosted.org/packages/96/88/5bc1a8dfaa0bdcfdd3e3150f78f7f8384b0e65ac8a78c8d1f40d2fad6518/lexery-1.1.0.tar.gz" } ] }