Files @ 7a9194696648
Branch filter:

Location: Diana/src/sgfParser/propValues.py - annotation

Laman
split propValues parsing into a separate module
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
7a9194696648
import re

from . import ParserError, skipWhitespace


class Composed:
	def __init__(self,a=None,b=None):
		self.a=a
		self.b=b

	def __str__(self):
		return "{0}:{1}".format(self.a,self.b)


class Point:
	def __init__(self,c,r):
		self.r=r
		self.c=c

	def __iter__(self):
		yield self.c
		yield self.r

	def __str__(self):
		a=ord("a")
		return chr(a+self.c)+chr(a+self.r)


## Metatype matching one of the provided types.
#
# Returns the first match, so the order is important.
def choose(*vTypes):
	def f(s,start):
		for vType in vTypes:
			try:
				i,x=vType(s,start)
				return (i,x)
			except ParserError: pass
		raise ParserError("no variant of a 'choose' property value matched",s,start)
	return f


def singletonFits(s,i):
	return i<len(s) and s[i]=="["


def singletonEnds(s,i):
	return i<len(s) and s[i]=="]"


def singleton(vType):
	def f(s,start):
		if not singletonFits(s,start):
			raise ParserError("expected a property value starting with '['",s,start)
		i,x=vType(s,start+1)
		if not singletonEnds(s,i):
			raise ParserError("expected a property value ending with ']'",s,i)
		i=skipWhitespace(s,i+1)
		return (i,x)
	return f


def listOf(vType,allowEmpty=False):
	def f(s,start):
		i=start
		if not singletonFits(s,i):
			raise ParserError("expected a property value starting with '['",s,i)
		if singletonEnds(s,i+1) and allowEmpty:
			i=skipWhitespace(s,i+2)
			return (i,[])
		single=singleton(vType)
		i,x=single(s,i)
		res=[x]
		while singletonFits(s,i):
			i,x=single(s,i)
			res.append(x)
		return (i,res)
	return f


def compose(vTypeA,vTypeB):
	def f(s,start):
		i,a=vTypeA(s,start)
		if i>=len(s) or s[i]!=":":
			raise ParserError("expected a composed property value separated by ':'",s,i)
		i,b=vTypeB(s,i+1)
		return (i,Composed(a,b))
	return f


def number(s,start):
	r=re.compile(r"(\+|-|)\d+")
	m=r.match(s,start)
	if m is None: raise ParserError("expected a number matching '(\+|-|)\d+'",s,start)
	res=int(m.group(0))
	return (m.end(),res)


def real(s,start):
	r=re.compile(r"(\+|-|)\d+(\.\d+)?")
	m=r.match(s,start)
	if m is None: raise ParserError("expected a real number matching '(\+|-|)\d+(\.\d+)?'",s,start)
	res=float(m.group(0))
	return (m.end(),res)


def double(s,start):
	r=re.compile(r"1|2")
	m=r.match(s,start)
	if m is None: raise ParserError("expected a double value, either '1' or '2'",s,start)
	res=int(m.group(0))
	return (m.end(),res)


def color(s,start):
	r=re.compile(r"B|W")
	m=r.match(s,start)
	if m is None: raise ParserError("expected a color value, either 'B' or 'W'",s,start)
	return (m.end(),m.group(0))


def text(simple=True,composed=False):
	def f(s,start):
		res=""
		esc=False
		lastC=""
		i=start
		for i,c in enumerate(s[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(s,start): return (start,"")


def anything(s,start):
	esc=False
	for i,c in enumerate(s[start:],start):
		if esc: esc=False
		elif c=="\\": esc=True
		elif c=="]": break
	return (i,s[start:i])


# go specific
def point(s,start):
	r=re.compile(r"[a-zA-Z]{2}|") # !! limit to board size
	m=r.match(s,start)
	if m is None: raise ParserError("expected a point value matching '[a-zA-Z]{2}|'",s,start)
	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(),Point(col,row))


move=point
stone=point