# 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: []' # End -- grammar generated by Yapps