Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/sgfparser.py
diff options
context:
space:
mode:
Diffstat (limited to 'sgfparser.py')
-rw-r--r--sgfparser.py100
1 files changed, 100 insertions, 0 deletions
diff --git a/sgfparser.py b/sgfparser.py
new file mode 100644
index 0000000..6b52522
--- /dev/null
+++ b/sgfparser.py
@@ -0,0 +1,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