Files
@ 0ee71f3564f4
Branch filter:
Location: Diana/src/sgfParser/collection.py - annotation
0ee71f3564f4
2.2 KiB
text/x-python
the parser is more predictive and reports errors
b66f5379b832 0ee71f3564f4 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 b66f5379b832 0ee71f3564f4 0ee71f3564f4 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 b66f5379b832 0ee71f3564f4 b66f5379b832 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 b66f5379b832 0ee71f3564f4 0ee71f3564f4 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 b66f5379b832 b66f5379b832 0ee71f3564f4 b66f5379b832 b66f5379b832 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 0ee71f3564f4 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 2ed7f0dab5ef b66f5379b832 a362783e3bec 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef 2ed7f0dab5ef b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 b66f5379b832 | from sgfParser.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 the 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
|