Files
smnp-py/smnp/newast/node/model.py
2019-07-05 20:55:36 +02:00

82 lines
2.2 KiB
Python

class Node:
def __init__(self, pos, children=None):
if children is None:
children = []
self.children = children
self.pos = pos
self.parent = None
for child in self.children:
if isinstance(child, Node):
child.parent = self
def __len__(self):
return len(self.children)
def __getitem__(self, key):
return self.children[key]
def __setitem__(self, key, value):
if isinstance(value, Node):
value.parent = self
self.children[key] = value
def append(self, node):
if isinstance(node, Node):
node.parent = self
self.children.append(node)
def pop(self, index):
return self.children.pop(index)
@classmethod
def _parse(cls, input):
pass
@classmethod
def parse(cls, input):
result = cls._parse(input)
if result is None:
return ParseResult.FAIL()
if not isinstance(result, ParseResult):
raise RuntimeError(f"_parse() method of '{cls.__name__}' class haven't returned ParseResult object")
return result
def print(self):
self._print(first=True)
def _print(self, prefix="", last=True, first=False):
print(prefix, '' if first else '└─' if last else '├─', self.__class__.__name__, sep="")
prefix += ' ' if last else ''
for i, child in enumerate(self.children):
last = i == len(self.children) - 1
if isinstance(child, Node):
child._print(prefix, last)
else:
print(prefix, '' if last else '', f"'{str(child)}'", sep="")
def __str__(self):
return self.__class__.__name__
class ParseResult():
def __init__(self, result, node):
if result and node is None:
raise RuntimeError("Node musn't be None if result is set to True for ParseResult")
self.result = result
self.node = node
@staticmethod
def FAIL():
return ParseResult(False, None)
@staticmethod
def OK(node):
return ParseResult(True, node)
def __str__(self):
return f"{'OK' if self.result else 'FAILED'}[{self.node}]"