{"library":"sly","title":"SLY - Sly Lex Yacc","description":"SLY is a 100% Python implementation of the lex and yacc tools, loosely based on the traditional compiler construction tools lex and yacc, implementing the LALR(1) parsing algorithm. It provides a bare-bones, yet fully capable, library for writing parsers in Python. The current version is 0.5. As of December 21, 2025, the project has been officially retired by its author, and no further maintenance is expected.","language":"python","status":"abandoned","last_verified":"Thu May 21","install":{"commands":["pip install sly"],"cli":null},"imports":["from sly import Lexer","from sly import Parser"],"auth":{"required":false,"env_vars":[]},"quickstart":{"code":"from sly import Lexer, Parser\n\nclass CalcLexer(Lexer):\n    tokens = { NUMBER, ID, PLUS, MINUS, TIMES, DIVIDE, ASSIGN, LPAREN, RPAREN }\n    literals = { '=', '+', '-', '*', '/', '(', ')' }\n\n    # String containing ignored characters\n    ignore = ' \\t'\n\n    # Regular expression rules for tokens\n    NUMBER = r'\\d+'\n    ID = r'[a-zA-Z_][a-zA-Z0-9_]*'\n\n    # Special rules for tokens\n    def NUMBER(self, t):\n        t.value = int(t.value)\n        return t\n\n    def ID(self, t):\n        t.value = str(t.value)\n        return t\n\n    def error(self, t):\n        print(f\"Illegal character '{t.value[0]}' at line {t.lineno}\")\n        self.index += 1\n\nclass CalcParser(Parser):\n    tokens = CalcLexer.tokens\n\n    precedence = (\n        ('left', PLUS, MINUS),\n        ('left', TIMES, DIVIDE)\n    )\n\n    def __init__(self):\n        self.names = { }\n\n    @_('ID ASSIGN expr')\n    def statement(self, p):\n        self.names[p.ID] = p.expr\n        return p.expr\n\n    @_('expr')\n    def statement(self, p):\n        return p.expr\n\n    @_('expr PLUS expr')\n    def expr(self, p):\n        return p.expr0 + p.expr1\n\n    @_('expr MINUS expr')\n    def expr(self, p):\n        return p.expr0 - p.expr1\n\n    @_('expr TIMES expr')\n    def expr(self, p):\n        return p.expr0 * p.expr1\n\n    @_('expr DIVIDE expr')\n    def expr(self, p):\n        return p.expr0 / p.expr1\n\n    @_('LPAREN expr RPAREN')\n    def expr(self, p):\n        return p.expr\n\n    @_('NUMBER')\n    def expr(self, p):\n        return p.NUMBER\n\n    @_('ID')\n    def expr(self, p):\n        try:\n            return self.names[p.ID]\n        except LookupError:\n            print(f\"Undefined name '{p.ID}'\")\n            return 0\n\n    def error(self, p):\n        if p:\n            print(f\"Syntax error at token {p.type}, value '{p.value}'\")\n        else:\n            print(\"Syntax error at EOF\")\n\nif __name__ == '__main__':\n    lexer = CalcLexer()\n    parser = CalcParser()\n    while True:\n        try:\n            text = input('calc > ')\n            if text.lower() == 'quit':\n                break\n            result = parser.parse(lexer.tokenize(text))\n            if result is not None: # Only print if there was a calculable result\n                print(result)\n        except EOFError:\n            break\n        except Exception as e:\n            print(f\"Error: {e}\")","lang":"python","description":"This quickstart demonstrates a simple calculator using SLY. It defines a lexer to tokenize input (numbers, IDs, operators) and a parser to build an abstract syntax tree and evaluate expressions, including variable assignments.","tag":null,"tag_description":null,"last_tested":"2026-04-25","results":[{"runtime":"python:3.10-alpine","exit_code":0},{"runtime":"python:3.10-slim","exit_code":0},{"runtime":"python:3.11-alpine","exit_code":0},{"runtime":"python:3.11-slim","exit_code":0},{"runtime":"python:3.12-alpine","exit_code":0},{"runtime":"python:3.12-slim","exit_code":0},{"runtime":"python:3.13-alpine","exit_code":0},{"runtime":"python:3.13-slim","exit_code":0},{"runtime":"python:3.9-alpine","exit_code":0},{"runtime":"python:3.9-slim","exit_code":0}]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-21","installed_version":"0.5","pypi_latest":"0.5","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.5,"avg_import_s":0.03,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"18.0M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.3,"disk_size":"18.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.01,"mem_mb":1.3,"disk_size":"18M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1.3,"disk_size":"18M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.03,"mem_mb":1.4,"disk_size":"19.8M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"19.8M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.03,"mem_mb":1.4,"disk_size":"20M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"20M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.04,"mem_mb":1.2,"disk_size":"11.7M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.2,"disk_size":"11.7M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.04,"mem_mb":1.2,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":1.2,"disk_size":"12M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.04,"mem_mb":1.9,"disk_size":"11.4M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.5,"disk_size":"11.3M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.4,"import_time_s":0.04,"mem_mb":1.8,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.05,"mem_mb":1.3,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"17.5M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"17.5M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0.01,"mem_mb":1.2,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"sly","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"18M"}]}}