Files
@ cbabe0bae003
Branch filter:
Location: Diana/src/diana/sgfParser/node.py - annotation
cbabe0bae003
3.2 KiB
text/x-python
changed tests imports
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | 616c96178973 36b0271e7393 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 616c96178973 686166c7d5bc 616c96178973 616c96178973 616c96178973 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 616c96178973 e3e6dfbb44f6 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 686166c7d5bc 686166c7d5bc e3e6dfbb44f6 616c96178973 686166c7d5bc 686166c7d5bc e3e6dfbb44f6 686166c7d5bc 686166c7d5bc 686166c7d5bc 616c96178973 686166c7d5bc 686166c7d5bc 616c96178973 616c96178973 | from collections import deque
import logging as log
from . import skipWhitespace, ParserWarning
from .property import Property, GAME_INFO
class Node:
def __init__(self):
self.properties = dict()
self.parent = None
self.children = []
@staticmethod
def fits(s, i):
return i < len(s) and s[i] == ";"
@staticmethod
def create(s, start):
assert Node.fits(s, start)
res = Node()
i = skipWhitespace(s, start+1)
while Property.fits(s, i):
(i, x) = Property.create(s, i)
if x.name in res.properties:
log.warning(ParserWarning('duplicate "{0}" property in a node. second value ignored'.format(x.name), s, i))
else:
res.properties[x.name] = x
i = skipWhitespace(s, i)
return (i, res)
def listGINodes(self):
if self.isGINode():
yield self
empty = not self.isGINode()
node = self
while node.parent:
node = node.parent
if node.isGINode():
empty = False
yield node
queue = deque(self.children)
while len(queue) > 0:
node = queue.popleft()
if node.isGINode():
empty = False
yield node
queue.extend(node.children)
if empty:
yield self # always yield at least self, can work as GINode as well as any other
def isGINode(self):
return any(prop.type == GAME_INFO for prop in self.properties.values())
def setProp(self, name, value):
self.properties[name] = value
# check value type
def setChildren(self, children):
self.children = children
for child in children:
child.parent = self
def addChild(self, node):
if node in self.children:
return node
node.parent = self
self.children.append(node)
return node
def removeChild(self, node):
if node not in self.children:
return None
del self.children[self.children.index(node)]
node.parent = None
return node
def removeChildAt(self, i):
if -len(self.children) < i < len(self.children):
res = self.children[i]
del self.children[i]
res.parent = None
return res
return None
## Create a copy of the Node, with the same parent and deep copied properties, no copied children.
def copy(self):
res = Node()
res.properties = {k: v.copy() for (k, v) in self.properties.items()}
res.parent = self.parent
return res
def getProp(self, name, default=None):
if name in self.properties:
return self.properties[name].value
else:
return default
## Returns textual representation of the Node itself, but disregards its children.
def __str__(self):
return ";" + "".join(str(p) for p in self.properties.values())
def export(self):
# there is a beautiful recursive solution, which this stack is too narrow to contain
stack = [(self, 1, 1)]
output = []
while len(stack) > 0:
(node, left, right) = stack.pop()
if left > 0:
output.append("("*left)
output.append(str(node)+"\n")
childCount = len(node.children)
if childCount == 0: # a leaf
output.append(")"*right+"\n")
elif childCount == 1: # a line
stack.append((node.children[0], 0, right))
else: # a branching node
# first child pops first, last child closes parent's parentheses
children = zip(node.children, [1]*childCount, [1]*(childCount-1)+[1+right])
stack.extend(reversed(list(children)))
return "".join(output)
|