Install & Compatibility
Where this runs
tested against v1.9.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.920 runs
installs and imports cleanly · install 0.0s · import 0.000s · 19MB
glibcpy 3.10–3.920 runs
installs and imports cleanly · install 2.1s · import 0.000s · 19MB
17MB installed
● package 17MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
GenericParser
✓ from spark_parser import GenericParser
✗ from spark import GenericParser
The package name is `spark-parser`, leading to the import path `spark_parser`. Many users mistakenly try to import from `spark` (without `_parser`), possibly confusing it with Apache Spark.
GenericScanner
✓ from spark_parser import GenericScanner
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.
from spark_parser import GenericParser, GenericScanner
# 1. Define your scanner (lexer) by subclassing GenericScanner
class SimpleCalcScanner(GenericScanner):
def tokenize(self, input_string):
tokens = []
i = 0
while i < len(input_string):
char = input_string[i]
if char.isspace():
i += 1
continue
if char.isdigit():
num_str = ""
while i < len(input_string) and input_string[i].isdigit():
num_str += input_string[i]
i += 1
tokens.append(('NUMBER', int(num_str)))
elif char in "+-*/()":
tokens.append((char, char))
i += 1
else:
raise ValueError(f"Invalid character: {char}")
return tokens
# 2. Define your parser (grammar rules) by subclassing GenericParser
class SimpleCalcParser(GenericParser):
def __init__(self, start_symbol='expr'):
GenericParser.__init__(self, start_symbol)
# Define grammar rules using docstrings for methods starting with 'p_'
def p_expr_add(self, args):
'''
expr ::= expr + term
'''
return args[0] + args[2]
def p_expr_term(self, args):
'''
expr ::= term
'''
return args[0]
def p_term_num(self, args):
'''
term ::= NUMBER
'''
return args[0]
# 3. Instantiate scanner and parser, then tokenize and parse
scanner = SimpleCalcScanner()
parser = SimpleCalcParser()
text_to_parse = "10 + 5"
tokens = scanner.tokenize(text_to_parse)
result = parser.parse(tokens)
# print(f"Parsed result for '{text_to_parse}': {result}") # Expected: 15
assert result == 15, "Parsing failed!"
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'spark'
Attempting to import from `spark` instead of `spark_parser`.
fixChange your import statements from `from spark import ...` to `from spark_parser import ...`.
RecursionError: maximum recursion depth exceeded
Prior to version 1.9.0, `spark-parser`'s internal `BuildTree` used recursion, which could hit Python's recursion limit with large or deeply nested parse trees. Complex grammars can also indirectly lead to this.
fixUpgrade to `spark-parser` version 1.9.0 or higher. If the issue persists with a very complex grammar, review your grammar for excessively deep or recursive rules that could contribute to the problem.
ValueError: Invalid character: '<char>'
Your `GenericScanner` subclass encountered a character in the input string that it doesn't have a rule to tokenize, often due to missing whitespace handling, unhandled special characters, or malformed input.
fixReview your `Scanner`'s `tokenize` method. Ensure it handles all possible characters in the input, including whitespace, numbers, symbols, and any other valid tokens. Add rules or skip unknown characters explicitly.
Upgrade
Version history
1.9.0latest on PyPI · released Oct 8, 2024
Audit
Dependencies
No dependency data recorded yet.