diff --git a/src/diana/sgfParser.py b/src/diana/sgfParser.py --- a/src/diana/sgfParser.py +++ b/src/diana/sgfParser.py @@ -6,8 +6,6 @@ def skipWhitespace(str,start): return i class Collection: - gameTrees=[] - def __init__(self,str): self.gameTrees=[] i,x=GameTree.create(str,0) @@ -19,8 +17,9 @@ class Collection: i,x=GameTree.create(str,i) class GameTree: - nodes=[] - branches=[] + def __init__(self): + self.nodes=[] + self.branches=[] # def __init__(self,str,start): # self.nodes=[] @@ -39,7 +38,8 @@ class GameTree: # print("error when parsing GameTree") # return (-1,None) # return (i+1,self) - + + @staticmethod def create(str,start): res=GameTree() i=skipWhitespace(str,start) @@ -66,8 +66,10 @@ class GameTree: return (i+1,res) class Node: - properties=dict() - + def __init__(self): + self.properties=dict() + + @staticmethod def create(str,start): res=Node() if str[start]!=";": @@ -77,7 +79,8 @@ class Node: i,x=Property.create(str,start+1) 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)) + print(res.properties) + raise ParserError(0,0,'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) @@ -93,9 +96,11 @@ class Node: else: return None class Property: - name="" - value="" - + def __init__(self): + self.name="" + self.value="" + + @staticmethod def create(str,start): res=Property() i,x=Property.ident(str,start) @@ -111,7 +116,8 @@ class Property: # i=skipWhitespace(str,i) # i,x=PropValue.create(str,i,res.name) return (i,res) - + + @staticmethod def ident(str,start): r=re.compile(r"[A-Z]+") m=r.match(str,start) @@ -119,10 +125,13 @@ class Property: return (m.end(),m.group()) class PropValue: - type="" - value=None + def __init__(self): + self.type="" + self.value=None + patterns=dict() - + + @staticmethod def create(str,start,name): if name in PropValue.patterns: return PropValue.patterns[name](str,start) @@ -138,7 +147,7 @@ class PropValue: # if str[i]!="]": # return (start,None) # return (i+1,x) - + def choose(*vTypes): def f(str,start): for vType in vTypes: @@ -146,7 +155,7 @@ class PropValue: if x is not None: return (i,x) return (start,None) return f - + def singleton(vType): def f(str,start): if str[start]!="[": @@ -167,11 +176,11 @@ class PropValue: # 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) + single=PropValue.singleton(vType) i,x=single(str,start) while x!=None: res.append(x) @@ -186,7 +195,7 @@ class PropValue: # 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) @@ -197,28 +206,28 @@ class PropValue: 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) @@ -240,7 +249,7 @@ class PropValue: # else: # res+=c # return res - + def text(simple=True,composed=False): def f(str,start): res="" @@ -264,9 +273,9 @@ class PropValue: lastC=c return (i,res) return f - + def empty(str,start): return (start,"") - + def anything(str,start): esc=False for i,c in enumerate(str[start:],start): @@ -363,6 +372,14 @@ class PropValue: "TW":listOf(point,allowEmpty=True) } +class ParserError(Exception): + def __init__(self,line,col,message): + self.line=line + self.col=col + self.message=message + + + """def property(str): # i=propIdent(str) # if i<0: return -1