# HG changeset patch # User Laman # Date 2016-09-18 16:07:28 # Node ID 6310ece1b69e5a69884dfb9267a33b53a157deb4 # Parent fd76ef287e30281b99efd89e7f5614c94e08cc1a cleaned old code diff --git a/src/diana/sgf.py b/src/diana/sgf.py --- a/src/diana/sgf.py +++ b/src/diana/sgf.py @@ -1,579 +1,6 @@ -import re - - -class Collection: - gameTrees=[] - - def export(self): - res="" - for root in gameTrees: - res+="({0})\n".format(root.fullExport()) - return res - -class Node: - parent=None - children=[] - properties={} - - def newChild(self): - child=Node() - child.parent=self - self.children.append(child) - return child - - def addChild(self,child): - child.parent=self - self.children.append(child) - - def delChild(self,index): - del self.children[index] - - def setProperty(self): pass - def getProperty(self): pass - - def fullExport(self): - res=self.export() - if len(self.children)==1: res+=children[0].fullExport() - else: - for child in self.children: - res+=child.fullExport() - return res - - def export(self): - res=";" - for name,value in properties.items(): - res+="{0}[{1}]".format(name,value) # !! str(value) - res+="\n" - return res - -class Property: - name="" - value=None - -class ListOf(Property): - values=[] - vType=None - - def __str__(self): - return "["+"][".join(self.values)+"]" - -class Composed(Property): - value=() - - def __str__(self): - return self.value[0]+":"+self.value[1] # !! str(self.value[0]) - -class Point(Property): # !! pass - row=0 - col=0 - - def __str__(self): - f=lambda x: chr(x+ord("a")) if x<26 else chr(x-26+ord("A")) - row=f(self.row) - col=f(self.col) - - return col+row - - - -def skipWhitespace(str,start): - i=start - while i=len(str) or str[i]!="(": - # print("error when parsing GameTree") - return (start,None) - i=skipWhitespace(str,i) - i,x=Node.create(str,start+1) - if x is None: - # print("error when parsing GameTree") - return (i,None) - while x is not None: - res.nodes.append(x) - i=skipWhitespace(str,i) - i,x=Node.create(str,i) - i=skipWhitespace(str,i) - i,x=GameTree.create(str,i) - while x is not None: - res.branches.append(x) - i=skipWhitespace(str,i) - i,x=GameTree.create(str,i) - if str[i]!=")": - # print("error when parsing GameTree") - return (i,None) - return (i+1,res) - -class Node: - properties=dict() - - def create(str,start): - res=Node() - if str[start]!=";": - # print("error when parsing Node") - return (start,None) - i=skipWhitespace(str,start+1) - i,x=Property.create(str,i) - while x is not None: - if x.name in res.properties: - print('error: duplicate "{0}" property in node at position {1}. second value ignored'.format(x.name,start)) - else: - res.properties[x.name]=x - i=skipWhitespace(str,i) - i,x=Property.create(str,i) - return (i,res) - - def setProperty(self,name,value): - self.properties[name]=value - # zkontrolovat typ value - - def getProperty(self,name): - if name in self.properties: return self.properties[name] - else: return None - -class Property: - name="" - value="" - - def create(str,start): - res=Property() - i,x=Property.ident(str,start) - if x is None: - return (start,None) - res.name=x - i,x=PropValue.create(str,i,res.name) - if x is None: - print('error when parsing property "{0}" at position {1}'.format(res.name,i)) - return (start,None) - # while x is not None: # přesunuto do PropValue.listOf - # res.values.append(x) - # i=skipWhitespace(str,i) - # i,x=PropValue.create(str,i,res.name) - res.values.append(x) # !! podezřelé - return (i,res) - - def ident(str,start): - r=re.compile(r"[A-Z]+") - m=r.match(str,start) - if m is None: return (start,None) - return (m.end(),m.group()) +class SgfReader: + def __init__(self,collection): + self.collection=collection -class PropValue: - type="" - value=None - patterns=dict() - - def create(str,start,name): - if name in PropValue.patterns: - return PropValue.patterns[name](str,start) - else: - print('warning, unknown property "{0}" at position {1}'.format(name,start)) - return PropValue.singleton(PropValue.anything)(str,start) - - # def singleton(str,start,vType): - # if str[start]!="[": - # return (start,None) - # i,x=vType(str,start+1) - # if x is None: return (start,None) - # if str[i]!="]": - # return (start,None) - # return (i+1,x) - - def choose(*vTypes): - def f(str,start): - for vType in vTypes: - i,x=vType(str,start) - if x is not None: return (i,x) - return (start,None) - return f - - def singleton(vType): - def f(str,start): - if str[start]!="[": - return (start,None) - i,x=vType(str,start+1) - if x is None: return (start,None) - if str[i]!="]": - return (start,None) - return (i+1,x) - return f - - # def listOf(str,start,vType,allowEmpty=False): - # res=[] - # i,x=singleton(str,start,vType) - # # singleton(vType) if vType not tuple else compose(vType[0],vType[1]) - # while x!=None: - # res.append(x) - # i,x=singleton(str,i,vType) - # if len(res)==0 and not allowEmpty: return (start,None) - # return (i,res) - - def listOf(vType,allowEmpty=False): - def f(str,start): - res=[] - single=singleton(vType) - i,x=single(str,start) - while x!=None: - res.append(x) - i,x=single(str,i) - if len(res)==0 and not allowEmpty: return (start,None) - return (i,res) - return f - - # def compose(str,start,vTypeA,vTypeB): - # i,a=vTypeA(str,start) - # if a==None or str[i]!=":": return (start,None) - # i,b=vTypeB(str,i+1) - # if b==None: return start,None - # return (i,(a,b)) - - def compose(vTypeA,vTypeB): - def f(str,start): - i,a=vTypeA(str,start) - # print(">",i,a) - if a==None or str[i]!=":": return (start,None) - i,b=vTypeB(str,i+1) - # print(">",i,b) - if b==None: return start,None - return (i,(a,b)) - return f - - def number(str,start): - r=re.compile(r"(\+|-|)\d+") - m=r.match(str,start) - if m is None: return (start,None) - res=int(m.group(0)) - return (m.end(),res) - - def real(str,start): - r=re.compile(r"(\+|-|)\d+(\.\d+)?") - m=r.match(str,start) - if m is None: return (start,None) - res=float(m.group(0)) - return (m.end(),res) - - def double(str,start): - r=re.compile(r"1|2") - m=r.match(str,start) - if m is None: return (start,None) - res=int(m.group(0)) - return (m.end(),res) - - def color(str,start): - r=re.compile(r"B|W") - m=r.match(str,start) - if m is None: return (start,None) - return (m.end(),m.group(0)) - - # def simpleText(str,start): - # res="" - # esc=False - # lineBreak=False - # for c in str: - # if esc: - # res+=c - # esc=False - # elif c=="\\": - # esc=True - # elif c=="]": - # break - # else: - # res+=c - # return res - - def text(simple=True,composed=False): - def f(str,start): - res="" - esc=False - lastC="" - for i,c in enumerate(str[start:],start): - if esc: - if c!="\n" and c!="\r": res+=c - esc=False - elif (c=="\n" and lastC=="\r") or (c=="\r" and lastC=="\n"): pass - elif c=="\r" or c=="\n" and not simple: - res+="\n" - elif c.isspace(): - res+=" " - elif c=="\\": - esc=True - elif c=="]" or (c==":" and composed): - break - else: - res+=c - lastC=c - return (i,res) - return f - - def empty(str,start): return (start,"") - - def anything(str,start): # přidat listOf - esc=False - for i,c in enumerate(str[start:],start): - if esc: esc=False - elif c=="\\": esc=True - elif c=="]": break - return (i,str[start:i]) - - # go specific - def point(str,start): - r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size - m=r.match(str,start) - if m is None: return (start,None) - if m.group(0)=="": # pass, !! tt - return (m.end(),tuple()) - col=m.group(0)[0] - row=m.group(0)[1] - col=ord(col) - (ord("a") if "a"<=col<="z" else ord("A")-26) - row=ord(row) - (ord("a") if "a"<=row<="z" else ord("A")-26) - return (m.end(),(col,row)) - - move=point - stone=point - - patterns={ - "B":singleton(move), - "KO":singleton(empty), - "MN":singleton(number), - "W":singleton(move), - "AB":listOf(stone), # - "AE":listOf(point), # - "AW":listOf(stone), # - "PL":singleton(color), - "C":singleton(text(simple=False)), - "DM":singleton(double), - "GB":singleton(double), - "GW":singleton(double), - "HO":singleton(double), - "N":singleton(text()), - "UC":singleton(double), - "V":singleton(real), - "BM":singleton(double), - "DO":singleton(empty), - "IT":singleton(empty), - "TE":singleton(double), - "AR":listOf(compose(point,point)), # - "CR":listOf(point), # - "DD":listOf(point,allowEmpty=True), # - "LB":listOf(compose(point,text())), # - "LN":listOf(compose(point,point)), # - "MA":listOf(point), # - "SL":listOf(point), # - "SQ":listOf(point), # - "TR":listOf(point), # - "AP":singleton(compose(text(composed=True),text())), # - "CA":singleton(text()), - "FF":singleton(number), - "GM":singleton(number), - "ST":singleton(number), - "SZ":choose(singleton(number),singleton(compose(number,number))), # - "AN":singleton(text()), - "BR":singleton(text()), - "BT":singleton(text()), - "CP":singleton(text()), - "DT":singleton(text()), - "EV":singleton(text()), - "GN":singleton(text()), - "GC":singleton(text(simple=False)), - "ON":singleton(text()), - "OT":singleton(text()), - "PB":singleton(text()), - "PC":singleton(text()), - "PW":singleton(text()), - "RE":singleton(text()), - "RO":singleton(text()), - "RU":singleton(text()), - "SO":singleton(text()), - "TM":singleton(real), - "US":singleton(text()), - "WR":singleton(text()), - "WT":singleton(text()), - "BL":singleton(real), - "OB":singleton(number), - "OW":singleton(number), - "WL":singleton(real), - "FG":choose(singleton(empty),singleton(compose(number,text()))), # - "PM":singleton(number), - "VW":listOf(point,allowEmpty=True), # - - # go specific - "HA":singleton(number), - "KM":singleton(real), - "TB":listOf(point,allowEmpty=True), - "TW":listOf(point,allowEmpty=True) - } - -"""def property(str): - # i=propIdent(str) - # if i<0: return -1 - # j=i - # i=propValue(str[i:]) - # while i>=0: - # j+=i - # i=propValue(str[i:]) - # return j - -def propIdent(str): - m=re.match(r"[A-Z]+",str) - if m is None: return -1 - return m.end() - -def propValue(str): - i=cValueType(str[1:]) - if str[0]=="[" and i>=0 and str[i]=="]": return i+1 - else: return -1 - -class propValue: - pass - -def cValueType(str,start): - matches=[real,number,double,color,simpleText] - for f in matches: - i,x=f(str,start) - if x is not None: return i,x - return 1/0 - -def number(str,start): - r=re.compile(r"(\+|-|)\d+") - m=r.match(str,start) - if m is None: return (-1,None) - x=int(m.group(0)) - return (m.end(),x) - -def real(str): - m=re.match(r"(\+|-|)\d+(\.\d+)?",str) - if m is None: return -1 - return m.end() - -def double(str): - m=re.match(r"1|2",str) - if m is None: return -1 - return m.end() - -def color(str): - m=re.match(r"B|W",str) - if m is None: return -1 - return m.end() - -def simpleText(str): - res=r"" - esc=False - for c in str: - if esc: - res+=c - esc=False - elif c=="\\": - esc=True - elif c=="]": - break - else: - res+=c - return res""" - - -# TODO: -# date - - -""" -# move -B move -KO none -MN number -W move - -# setup -AB list of stone -AE list of point -AW list of stone -PL color - -# node annotation -C text -DM double -GB double -GW double -HO double -N simpleText -UC double -V real - -# move annotation -BM double -DO none -IT none -TE double - -# markup -AR list of composed point:point -CR list of point -DD elist of point -LB list of composed point:simpleText -LN list of composed point:point -MA list of point -SL list of point -SQ list of point -TR list of point - -# root -AP composed simpleText:simpleText -CA simpleText -FF number -GM number -ST number -SZ number | composed number:number - -# game info -AN simpleText -BR simpleText -BT simpleText -CP simpleText -DT simpleText -EV simpleText -GN simpleText -GC text -ON simpleText -OT simpleText -PB simpleText -PC simpleText -PW simpleText -RE simpleText -RO simpleText -RU simpleText -SO simpleText -TM real -US simpleText -WR simpleText -WT simpleText - -# timing -BL real -OB number -OW number -WL real - -# misc -FG none | composition of number:simpleText -PM number -VW elist of point -""" \ No newline at end of file + def getGameRecords(self): + pass \ No newline at end of file diff --git a/src/diana/sgfParser.py b/src/diana/sgfParser.py --- a/src/diana/sgfParser.py +++ b/src/diana/sgfParser.py @@ -20,24 +20,6 @@ class GameTree: def __init__(self): self.nodes=[] self.branches=[] - - # def __init__(self,s,start): - # self.nodes=[] - # self.branches=[] - # if s[start]!="(": - # print("error when parsing GameTree") - # return (-1,None) - # i,x=Node(s,start+1) - # if x is None: - # print("error when parsing GameTree") - # return (-1,None) - # while x is not None: - # self.nodes.append(x) - # i,x=Node(s,i) - # if s[i]!=")": - # print("error when parsing GameTree") - # return (-1,None) - # return (i+1,self) @staticmethod def create(s,start): @@ -111,10 +93,6 @@ class Property: if x is None: print('error when parsing property "{0}" at position {1}'.format(res.name,i)) return (start,None) - # while x is not None: # přesunuto do PropValue.listOf - # res.values.append(x) - # i=skipWhitespace(s,i) - # i,x=PropValue.create(s,i,res.name) return (i,res) @staticmethod @@ -138,15 +116,6 @@ class PropValue: else: print('warning, unknown property "{0}" at position {1}'.format(name,start)) return PropValue.singleton(PropValue.anything)(s,start) - - # def singleton(s,start,vType): - # if s[start]!="[": - # return (start,None) - # i,x=vType(s,start+1) - # if x is None: return (start,None) - # if s[i]!="]": - # return (start,None) - # return (i+1,x) def choose(*vTypes): def f(s,start): @@ -166,16 +135,6 @@ class PropValue: return (start,None) return (i+1,x) return f - - # def listOf(s,start,vType,allowEmpty=False): - # res=[] - # i,x=singleton(s,start,vType) - # # singleton(vType) if vType not tuple else compose(vType[0],vType[1]) - # while x!=None: - # res.append(x) - # i,x=singleton(s,i,vType) - # if len(res)==0 and not allowEmpty: return (start,None) - # return (i,res) def listOf(vType,allowEmpty=False): def f(s,start): @@ -188,13 +147,6 @@ class PropValue: if len(res)==0 and not allowEmpty: return (start,None) return (i,res) return f - - # def compose(s,start,vTypeA,vTypeB): - # i,a=vTypeA(s,start) - # if a==None or s[i]!=":": return (start,None) - # i,b=vTypeB(s,i+1) - # if b==None: return start,None - # return (i,(a,b)) def compose(vTypeA,vTypeB): def f(s,start): @@ -233,22 +185,6 @@ class PropValue: m=r.match(s,start) if m is None: return (start,None) return (m.end(),m.group(0)) - - # def simpleText(s,start): - # res="" - # esc=False - # lineBreak=False - # for c in s: - # if esc: - # res+=c - # esc=False - # elif c=="\\": - # esc=True - # elif c=="]": - # break - # else: - # res+=c - # return res def text(simple=True,composed=False): def f(s,start): @@ -378,75 +314,6 @@ class ParserError(Exception): self.col=col self.message=message - - -"""def property(s): - # i=propIdent(s) - # if i<0: return -1 - # j=i - # i=propValue(s[i:]) - # while i>=0: - # j+=i - # i=propValue(s[i:]) - # return j - -def propIdent(s): - m=re.match(r"[A-Z]+",s) - if m is None: return -1 - return m.end() - -def propValue(s): - i=cValueType(s[1:]) - if s[0]=="[" and i>=0 and s[i]=="]": return i+1 - else: return -1 - -class propValue: - pass - -def cValueType(s,start): - matches=[real,number,double,color,simpleText] - for f in matches: - i,x=f(s,start) - if x is not None: return i,x - return 1/0 - -def number(s,start): - r=re.compile(r"(\+|-|)\d+") - m=r.match(s,start) - if m is None: return (-1,None) - x=int(m.group(0)) - return (m.end(),x) - -def real(s): - m=re.match(r"(\+|-|)\d+(\.\d+)?",s) - if m is None: return -1 - return m.end() - -def double(s): - m=re.match(r"1|2",s) - if m is None: return -1 - return m.end() - -def color(s): - m=re.match(r"B|W",s) - if m is None: return -1 - return m.end() - -def simpleText(s): - res=r"" - esc=False - for c in s: - if esc: - res+=c - esc=False - elif c=="\\": - esc=True - elif c=="]": - break - else: - res+=c - return res""" - # TODO: # date