1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# Begin -- grammar generated by Yapps
import sys, re
from yapps import runtime
class SGFScanner(runtime.Scanner):
patterns = [
("''", re.compile('')),
('"\\\\]"', re.compile('\\]')),
('"\\\\["', re.compile('\\[')),
('";"', re.compile(';')),
('"\\\\)"', re.compile('\\)')),
('"\\\\("', re.compile('\\(')),
('\\s+', re.compile('\\s+')),
('Point', re.compile('[a-zA-Z]{2}')),
('Move', re.compile('[a-zA-Z]{2}')),
('Stone', re.compile('[a-zA-Z]{2}')),
('PropID', re.compile('([a-z]*[A-Z]){1,2}[a-z]*')),
('Number', re.compile('[+-]?[0-9]+')),
('Real', re.compile('[+-]?[0-9]+(\\.[0-9]+)?')),
('Color', re.compile('(B|W)')),
('Text', re.compile('[^\\]]*')),
]
def __init__(self, str,*args,**kw):
runtime.Scanner.__init__(self,None,{'\\s+':None,},str,*args,**kw)
class SGF(runtime.Parser):
Context = runtime.Context
def GameTree(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'GameTree', [])
self._scan('"\\\\("', context=_context)
res = []
while 1:
Node = self.Node(_context)
res.append(Node)
if self._peek('";"', '"\\\\)"', '"\\\\("', context=_context) != '";"': break
while self._peek('"\\\\)"', '"\\\\("', context=_context) == '"\\\\("':
GameTree = self.GameTree(_context)
res.append(GameTree)
self._scan('"\\\\)"', context=_context)
return res
def Node(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'Node', [])
self._scan('";"', context=_context)
res = []
while 1:
Property = self.Property(_context)
res.append(Property)
if self._peek('PropID', '";"', '"\\\\)"', '"\\\\("', context=_context) != 'PropID': break
return dict(res)
def Property(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'Property', [])
PropID = self._scan('PropID', context=_context)
res = (PropID, [])
while 1:
self._scan('"\\\\["', context=_context)
ValueType = self.ValueType(_context)
self._scan('"\\\\]"', context=_context)
res[1].append(ValueType)
if self._peek('"\\\\["', 'PropID', '";"', '"\\\\)"', '"\\\\("', context=_context) != '"\\\\["': break
return res
def ValueType(self, _parent=None):
_context = self.Context(_parent, self._scanner, 'ValueType', [])
_token = self._peek('Number', 'Real', 'Color', 'Move', 'Text', "''", context=_context)
if _token == 'Number':
Number = self._scan('Number', context=_context)
return int(Number)
elif _token == 'Real':
Real = self._scan('Real', context=_context)
return float(Real)
elif _token == 'Color':
Color = self._scan('Color', context=_context)
return Color
elif _token == 'Move':
Move = self._scan('Move', context=_context)
return (Move[0].islower() and ord(Move[0])-96 or ord(Move[0])-64, Move[1].islower() and ord(Move[1])-96 or ord(Move[1])-64)
elif _token == 'Text':
Text = self._scan('Text', context=_context)
return Text
else: # == "''"
self._scan("''", context=_context)
return None
def parse(rule, text):
P = SGF(SGFScanner(text))
return runtime.wrap_error_reporter(P, rule)
if __name__ == '__main__':
from sys import argv, stdin
if len(argv) >= 2:
if len(argv) >= 3:
f = open(argv[2],'r')
else:
f = stdin
print parse(argv[1], f.read())
else: print >>sys.stderr, 'Args: <rule> [<filename>]'
# End -- grammar generated by Yapps
|