{"id":13460252,"url":"https://github.com/dabeaz/ply","last_synced_at":"2025-05-14T06:14:22.741Z","repository":{"id":37736180,"uuid":"1214164","full_name":"dabeaz/ply","owner":"dabeaz","description":"Python Lex-Yacc","archived":false,"fork":false,"pushed_at":"2024-07-08T08:54:26.000Z","size":1111,"stargazers_count":2815,"open_issues_count":9,"forks_count":472,"subscribers_count":82,"default_branch":"master","last_synced_at":"2025-01-10T10:07:12.127Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.dabeaz.com/ply/index.html","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dabeaz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2011-01-02T14:27:00.000Z","updated_at":"2025-01-10T06:42:54.000Z","dependencies_parsed_at":"2022-08-08T21:30:47.605Z","dependency_job_id":"30d4a926-2df7-4d50-8066-a0fbd4775a7b","html_url":"https://github.com/dabeaz/ply","commit_stats":{"total_commits":282,"total_committers":37,"mean_commits":7.621621621621622,"dds":"0.25177304964539005","last_synced_commit":"5c4dc94d4c6d059ec127ee1493c735963a5d2645"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabeaz%2Fply","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabeaz%2Fply/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabeaz%2Fply/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dabeaz%2Fply/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dabeaz","download_url":"https://codeload.github.com/dabeaz/ply/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247962605,"owners_count":21024871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T10:00:38.108Z","updated_at":"2025-04-09T02:16:28.316Z","avatar_url":"https://github.com/dabeaz.png","language":"Python","readme":"# PLY - Python Lex-Yacc\n\nAuthor: David Beazley (https://www.dabeaz.com)\n\n## Introduction\n\nPLY is a zero-dependency Python implementation of the traditional\nparsing tools lex and yacc. It uses the same LALR(1) parsing algorithm\nas yacc and has most of its core features. It is compatible with all\nmodern versions of Python.\n\nPLY was originally created in 2001 to support an Introduction to\nCompilers course at the University of Chicago.  As such, it has almost\nno features other than the core LALR(1) parsing algorithm.  This is by\ndesign--students should be made to suffer. Well, at least a little\nbit.  However, from a more practical point of view, there is a lot\nflexibility in terms of how you decide to use it.  You can use PLY to\nbuild Abstract Syntax Trees (ASTs), simple one-pass compilers,\nprotocol decoders, or even a more advanced parsing framework.\n\n## Important Notice - October 27, 2022\n\nThe PLY project will make no further package-installable releases.\nIf you want the latest version, you'll need to download it here\nor clone the repo.\n\n## Requirements\n\nThe current release of PLY requires the use of Python 3.6 or\ngreater. If you need to support an older version, download one of the\nhistorical releases at https://github.com/dabeaz/archive/tree/main/ply.\n\n## How to Install and Use \n\nAlthough PLY is open-source, it is not distributed or installed by\npackage manager.  There are only two files: `lex.py` and `yacc.py`,\nboth of which are contained in a `ply` package directory. To use PLY,\ncopy the `ply` directory into your project and import `lex` and `yacc`\nfrom the associated `ply` subpackage.  Alternatively, you can install\nthese files into your working python using `make install`.\n\n```python\nfrom .ply import lex\nfrom .ply import yacc\n```\n\nPLY has no third-party dependencies and can be freely renamed or moved\naround within your project as you see fit.  It rarely changes. \n\n## Example\n\nThe primary use for PLY is writing parsers for programming languages. Here an\nexample that parses simple expressions into an abstract syntax tree (AST):\n\n```python\n# -----------------------------------------------------------------------------\n# example.py\n#\n# Example of using PLY To parse the following simple grammar.\n#\n#   expression : term PLUS term\n#              | term MINUS term\n#              | term\n#\n#   term       : factor TIMES factor\n#              | factor DIVIDE factor\n#              | factor\n#\n#   factor     : NUMBER\n#              | NAME\n#              | PLUS factor\n#              | MINUS factor\n#              | LPAREN expression RPAREN\n#\n# -----------------------------------------------------------------------------\n\nfrom ply.lex import lex\nfrom ply.yacc import yacc\n\n# --- Tokenizer\n\n# All tokens must be named in advance.\ntokens = ( 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'LPAREN', 'RPAREN',\n           'NAME', 'NUMBER' )\n\n# Ignored characters\nt_ignore = ' \\t'\n\n# Token matching rules are written as regexs\nt_PLUS = r'\\+'\nt_MINUS = r'-'\nt_TIMES = r'\\*'\nt_DIVIDE = r'/'\nt_LPAREN = r'\\('\nt_RPAREN = r'\\)'\nt_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'\n\n# A function can be used if there is an associated action.\n# Write the matching regex in the docstring.\ndef t_NUMBER(t):\n    r'\\d+'\n    t.value = int(t.value)\n    return t\n\n# Ignored token with an action associated with it\ndef t_ignore_newline(t):\n    r'\\n+'\n    t.lexer.lineno += t.value.count('\\n')\n\n# Error handler for illegal characters\ndef t_error(t):\n    print(f'Illegal character {t.value[0]!r}')\n    t.lexer.skip(1)\n\n# Build the lexer object\nlexer = lex()\n    \n# --- Parser\n\n# Write functions for each grammar rule which is\n# specified in the docstring.\ndef p_expression(p):\n    '''\n    expression : term PLUS term\n               | term MINUS term\n    '''\n    # p is a sequence that represents rule contents.\n    #\n    # expression : term PLUS term\n    #   p[0]     : p[1] p[2] p[3]\n    # \n    p[0] = ('binop', p[2], p[1], p[3])\n\ndef p_expression_term(p):\n    '''\n    expression : term\n    '''\n    p[0] = p[1]\n\ndef p_term(p):\n    '''\n    term : factor TIMES factor\n         | factor DIVIDE factor\n    '''\n    p[0] = ('binop', p[2], p[1], p[3])\n\ndef p_term_factor(p):\n    '''\n    term : factor\n    '''\n    p[0] = p[1]\n\ndef p_factor_number(p):\n    '''\n    factor : NUMBER\n    '''\n    p[0] = ('number', p[1])\n\ndef p_factor_name(p):\n    '''\n    factor : NAME\n    '''\n    p[0] = ('name', p[1])\n\ndef p_factor_unary(p):\n    '''\n    factor : PLUS factor\n           | MINUS factor\n    '''\n    p[0] = ('unary', p[1], p[2])\n\ndef p_factor_grouped(p):\n    '''\n    factor : LPAREN expression RPAREN\n    '''\n    p[0] = ('grouped', p[2])\n\ndef p_error(p):\n    print(f'Syntax error at {p.value!r}')\n\n# Build the parser\nparser = yacc()\n\n# Parse an expression\nast = parser.parse('2 * 3 + 4 * (5 - x)')\nprint(ast)\n```\n\n## Documentation\n\nThe [doc/](doc/) directory has more extensive documentation on PLY.\n\n## Examples\n\nThe [example/](example/) directory has various examples of using PLY.\n\n## Test Suite\n\nPLY is not shipped with a test-suite.  However, it is extensively\ntested before releases are made.  The file\n[ply-tests.tar.gz](https://github.com/dabeaz/ply/raw/master/ply-tests.tar.gz)\ncontains a current version of the tests should you want to run them on\nyour own.\n\n## Bug Reports\n\nPLY is mature software and new features are rarely added.  If you think you have\nfound a bug, please report an issue.\n\n## Questions and Answers\n\n*Q: Why does PLY have such a weird API?*\n\nAside from simply being over 20 years old and predating many advanced\nPython features, PLY takes inspiration from two primary sources: the\nUnix `yacc` utility and John Aycock's Spark toolkit. `yacc` uses a\nconvention of referencing grammar symbols by `$1`, `$2`, and so\nforth. PLY mirrors this using `p[1]`, `p[2]`, etc.  Spark was a\nparsing toolkit that utilized introspection and Python docstrings for\nspecifying a grammar. PLY borrowed that because it was clever.\nA modern API can be found in the related [SLY](https://github.com/dabeaz/sly)\nproject.\n\n*Q: Why isn't PLY distributed as a package?*\n\nPLY is highly specialized software that is really only of interest to\npeople creating parsers for programming languages. In such a project,\nI think you should take responsibility for library dependencies.  PLY\nis very small and rarely changes--if it works for your project, there\nis no reason to ever update it.  At the same time, as it's author, I\nreserve the creative right to make occasional updates to the project,\nincluding those that might introduce breaking changes.  The bottom\nline is that I'm not a link in your software supply chain.  If you\nuse PLY, you should copy it into your project.\n\n*Q: Do you accept pull requests and user contributions?*\n\nNo. New features are not being added to PLY at this time.  However, I\nam interested in bug reports should you find a problem with PLY.  Feel\nfree to use the issue-tracker for feature ideas--just because PLY\nis not in active development doesn't mean that good ideas will be\nignored.\n\n*Q: Can I use PLY to make my own parsing tool?*\n\nAbsolutely! It's free software that you are free to copy and modify in\nany way that makes sense. This includes remixing it into something\nthat's more powerful.   I'd just ask that you keep the original\ncopyright notice in files based on the original PLY source code so\nthat others know where it came from.\n\n\n## Acknowledgements\n\nA special thanks is in order for all of the students in CS326 who\nsuffered through about 25 different versions of this.\n\nThe CHANGES file acknowledges those who have contributed patches.\n\nElias Ioup did the first implementation of LALR(1) parsing in PLY-1.x. \nAndrew Waters and Markus Schoepflin were instrumental in reporting bugs\nand testing a revised LALR(1) implementation for PLY-2.0.\n\n## Take a Class!\n\nIf you'd like to learn more about compiler principles or have a go at implementing\na compiler from scratch, come take a course. https://www.dabeaz.com/compiler.html.\n\n\n\n\n","funding_links":[],"categories":["Text Processing","Python","文本处理","语言资源库","Text Processing [🔝](#readme)"],"sub_categories":["python"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabeaz%2Fply","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdabeaz%2Fply","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdabeaz%2Fply/lists"}