Files
@ c6e20613189d
Branch filter:
Location: Diana/src/sgfParser/collection.py - annotation
c6e20613189d
2.2 KiB
text/x-python
added location of the ParserError in the parsed file
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 c6e20613189d 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 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
|