# HG changeset patch # User Laman # Date 2017-01-21 21:28:04 # Node ID 5781a5a0b2fb315b7b0050a12edd024734581ba2 # Parent f0b8120281b98f6fa5d084ea91a6349fb78cb1fd SGF nodes aware of their neighbours in the tree diff --git a/src/sgfParser.py b/src/sgfParser.py --- a/src/sgfParser.py +++ b/src/sgfParser.py @@ -1,10 +1,12 @@ import re + def skipWhitespace(s,start): i=start while i<len(s) and s[i].isspace(): i+=1 return i + class Collection: def __init__(self,s): self.gameTrees=[] @@ -19,7 +21,8 @@ class Collection: def listGames(self): for tree in self.gameTrees: for game in tree.listGames(): yield game - + + class GameTree: def __init__(self): self.nodes=[] @@ -36,14 +39,22 @@ class GameTree: if x is None: # print("error when parsing GameTree") return (i,None) + y=None while x is not None: res.nodes.append(x) + if y: y.addChild(x) + x.setParent(y) + y=x i=skipWhitespace(s,i) i,x=Node.create(s,i) i=skipWhitespace(s,i) i,x=GameTree.create(s,i) while x is not None: res.branches.append(x) + subroot=x.getNode(0) + if subroot: + subroot.setParent(y) + if y: y.addChild(subroot) i=skipWhitespace(s,i) i,x=GameTree.create(s,i) if s[i]!=")": @@ -56,6 +67,11 @@ class GameTree: for node in self._listGINodes(): yield self._buildSubtree(node) + def getNode(self,i): + if 0<=i<len(self.nodes): + return self.nodes[i] + return None + ## Create and return a new GameTree containing the provided Node. # # The Node objects are shared between the trees, not copied. @@ -73,10 +89,13 @@ class GameTree: for tree in self.branches: for node in tree._listGINodes(): yield node - + + class Node: def __init__(self): self.properties=dict() + self._parent=None + self._children=[] @staticmethod def create(s,start): @@ -102,6 +121,27 @@ class Node: def setProperty(self,name,value): self.properties[name]=value # zkontrolovat typ value + + def setParent(self,node): + self._parent=node + + def addChild(self,node): + if node in self._children: return node + 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)] + return node + + def removeChildAt(self,i): + if -len(self._children)<i<len(self._children): + res=self._children[i] + del self._children[i] + return res + return None def getProperty(self,name): if name in self.properties: return self.properties[name] @@ -126,6 +166,7 @@ class Property: if x is None: print('error when parsing property "{0}" at position {1}'.format(res.name,i)) return (start,None) + res.value=x return (i,res) @staticmethod @@ -137,7 +178,7 @@ class Property: @property def type(self): - gameInfo=["AN","BR","BT","CP","DT","EV","GN","GC","ON","OT","PB","PC","PW","RE","RO","RU","SO","TM","US","WR","WT"] + gameInfo={"AN","BR","BT","CP","DT","EV","GN","GC","ON","OT","PB","PC","PW","RE","RO","RU","SO","TM","US","WR","WT"} if self.name in gameInfo: return Property.GAME_INFO else: return Property.UNKNOWN