58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
from parsimonious.grammar import Grammar
|
||
from parsimonious.nodes import NodeVisitor
|
||
from rich import print
|
||
from .ebnf import ebnf
|
||
|
||
__all__ = ('ZiffersVisitor', 'parse_expression',)
|
||
|
||
GRAMMAR = Grammar(ebnf)
|
||
|
||
class ZiffersVisitor(NodeVisitor):
|
||
|
||
"""
|
||
Visitor for the Ziffers syntax.
|
||
"""
|
||
|
||
def visit_ziffers(self, node, children):
|
||
"""
|
||
Top-level visiter. Will traverse and build something out of a complete and valid
|
||
Ziffers expression.
|
||
"""
|
||
print(f"Node: {node}, Children: {children}")
|
||
result = {'ziffers': []}
|
||
|
||
for i in children:
|
||
if i[0] in (None, [], {}) and isinstance(i[0], dict):
|
||
continue
|
||
try:
|
||
result['ziffers'].append(i[0])
|
||
except Exception as e:
|
||
print(f"[red]Error in ziffers:[/red] {e}")
|
||
pass
|
||
return result
|
||
|
||
def visit_pc(self, node, children):
|
||
return {node.expr_name: node.text}
|
||
|
||
def visit_escape(self, node, children):
|
||
return {node.expr_name: node.text}
|
||
|
||
# def visit_subdiv(self, node, visited_children):
|
||
# key, values = visited_children
|
||
# ret)rn {key, dict(values)}
|
||
|
||
def generic_visit(self, node, children):
|
||
"""
|
||
This method seem to be the generic method to include in any NodeVisitor.
|
||
Probably better to keep it as is for the moment. This is appending a whole
|
||
lot of garbage to the final expression because I don't really know how to
|
||
write it properly...
|
||
"""
|
||
return children or node
|
||
|
||
def parse_expression(expression: str) -> dict:
|
||
tree = GRAMMAR.parse(expression)
|
||
visitor = ZiffersVisitor()
|
||
return visitor.visit(tree)
|
||
|