Files
@ 31266616bb87
Branch filter:
Location: Diana/src/sgfParser/collection.py - annotation
31266616bb87
2.1 KiB
text/x-python
split diagram notes into separate text files, refactored diana.py
2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 2a5d1585e748 | from .node import Node
from . import skipWhitespace, ParserError
class Collection:
def __init__(self,s):
self.gameTrees=[]
i=skipWhitespace(s,0)
if i>=len(s): return
elif not GameTree.fits(s,i):
raise ParserError("expected a GameTree starting with '('",s,i)
while GameTree.fits(s,i):
i,x=GameTree.create(s,i)
self.gameTrees.append(x)
if i<len(s):
raise ParserError("expected EOF",s,i)
def listGames(self):
for tree in self.gameTrees:
for game in tree.listGames(): yield game
class GameTree:
def __init__(self):
self.nodes=[]
self.branches=[]
@staticmethod
def fits(s,i):
return i<len(s) and s[i]=="("
@staticmethod
def create(s,start):
assert GameTree.fits(s,start)
res=GameTree()
i=skipWhitespace(s,start+1)
if not Node.fits(s,i):
raise ParserError("expected a Node starting with ';'",s,i)
y=None
while Node.fits(s,i):
i,x=Node.create(s,i)
res.nodes.append(x)
if y: y.addChild(x)
x.setParent(y)
y=x
i=skipWhitespace(s,i)
while GameTree.fits(s,i):
i,x=GameTree.create(s,i)
res.branches.append(x)
subroot=x.getNode(0)
subroot.setParent(y)
if y: y.addChild(subroot)
i=skipWhitespace(s,i)
if i>=len(s) or s[i]!=")":
raise ParserError("expected end of a GameTree marked by ')'",s,i)
i=skipWhitespace(s,i+1)
return (i,res)
## Expand multiple games into distinct GameTrees and yield each.
def listGames(self):
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 game tree containing the provided Node.
#
# Ancestor nodes are copied, descendants are shared.
def _buildSubtree(self,seedNode):
node=seedNode.copy()
while node.parent:
newNode=node.parent.copy()
node.parent=newNode
newNode.setChildren([node])
node=newNode
return node
## Find and yield Game Info nodes.
def _listGINodes(self):
for node in self.nodes:
if node.isGINode():
yield node
for tree in self.branches:
for node in tree._listGINodes():
yield node
|