{"library":"spark-parser","title":"SPARK Parser Toolkit","type":"library","description":"SPARK is a lightweight, pure-Python Earley-Algorithm context-free grammar parser toolkit. It enables developers to build parsers and scanners for custom languages or data formats using grammar rules defined as Python docstrings. The current version is 1.9.0, with releases occurring periodically to address Python compatibility and improve internal mechanics.","language":"python","status":"active","last_verified":"Mon May 18","install":{"commands":["pip install spark-parser"],"cli":null},"imports":["from spark_parser import GenericParser","from spark_parser import GenericScanner"],"auth":{"required":false,"env_vars":[]},"links":{"homepage":null,"github":"https://github.com/rocky/python-spark","docs":null,"changelog":null,"pypi":"https://pypi.org/project/spark-parser/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null},"quickstart":{"code":"from spark_parser import GenericParser, GenericScanner\n\n# 1. Define your scanner (lexer) by subclassing GenericScanner\nclass SimpleCalcScanner(GenericScanner):\n    def tokenize(self, input_string):\n        tokens = []\n        i = 0\n        while i < len(input_string):\n            char = input_string[i]\n            if char.isspace():\n                i += 1\n                continue\n            if char.isdigit():\n                num_str = \"\"\n                while i < len(input_string) and input_string[i].isdigit():\n                    num_str += input_string[i]\n                    i += 1\n                tokens.append(('NUMBER', int(num_str)))\n            elif char in \"+-*/()\":\n                tokens.append((char, char))\n                i += 1\n            else:\n                raise ValueError(f\"Invalid character: {char}\")\n        return tokens\n\n# 2. Define your parser (grammar rules) by subclassing GenericParser\nclass SimpleCalcParser(GenericParser):\n    def __init__(self, start_symbol='expr'):\n        GenericParser.__init__(self, start_symbol)\n\n    # Define grammar rules using docstrings for methods starting with 'p_'\n    def p_expr_add(self, args):\n        '''\n        expr ::= expr + term\n        '''\n        return args[0] + args[2]\n\n    def p_expr_term(self, args):\n        '''\n        expr ::= term\n        '''\n        return args[0]\n\n    def p_term_num(self, args):\n        '''\n        term ::= NUMBER\n        '''\n        return args[0]\n\n# 3. Instantiate scanner and parser, then tokenize and parse\nscanner = SimpleCalcScanner()\nparser = SimpleCalcParser()\n\ntext_to_parse = \"10 + 5\"\ntokens = scanner.tokenize(text_to_parse)\nresult = parser.parse(tokens)\n\n# print(f\"Parsed result for '{text_to_parse}': {result}\") # Expected: 15\nassert result == 15, \"Parsing failed!\"","lang":"python","description":"This quickstart demonstrates how to define a simple arithmetic scanner and parser using `GenericScanner` and `GenericParser`. It tokenizes an input string and then parses it according to the defined grammar rules to calculate the result.","tag":null,"tag_description":null,"last_tested":null,"results":[]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-18","installed_version":"1.9.0","pypi_latest":"1.9.0","is_stale":false,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":2.1,"avg_import_s":0,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"19.0M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0,"mem_mb":0.1,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0,"mem_mb":0.2,"disk_size":"21.4M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.7,"import_time_s":0,"mem_mb":0.2,"disk_size":"22M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0,"mem_mb":0.2,"disk_size":"13.2M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0,"mem_mb":0.2,"disk_size":"14M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0,"mem_mb":0.4,"disk_size":"12.9M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"spark-parser","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0,"mem_mb":0.2,"disk_size":"13M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"spark-parser","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0,"mem_mb":0.1,"disk_size":"18.7M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"spark-parser","exit_code":0,"wheel_type":"sdist","failure_reason":null,"import_side_effects":"clean","install_time_s":4,"import_time_s":0,"mem_mb":0.1,"disk_size":"19M"}]}}