Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sgfparser.py
blob: 6b52522d739de34a2b82fef6dfa261eb423e86e9 (plain)
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