From 9b78da535700f561952d0b6498d84b187e9a1791 Mon Sep 17 00:00:00 2001 From: "kr.angelov" Date: Mon, 7 Jan 2013 15:11:12 +0000 Subject: [PATCH] now the Python binding has an alternative representation for abstract trees which is composed of Python objects. The new representation is not integrated with the core runtime yet --- src/runtime/python/pgf/__init__.py | 3 + src/runtime/python/{pypgf.c => pgf/binding.c} | 4 +- src/runtime/python/pgf/expr.py | 169 ++++++++++++++++++ src/runtime/python/setup.py | 10 +- 4 files changed, 181 insertions(+), 5 deletions(-) create mode 100644 src/runtime/python/pgf/__init__.py rename src/runtime/python/{pypgf.c => pgf/binding.c} (99%) create mode 100644 src/runtime/python/pgf/expr.py diff --git a/src/runtime/python/pgf/__init__.py b/src/runtime/python/pgf/__init__.py new file mode 100644 index 000000000..07e164093 --- /dev/null +++ b/src/runtime/python/pgf/__init__.py @@ -0,0 +1,3 @@ +import pgf.expr +from pgf.binding import * +from pgf.expr import (readExpr_py) diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pgf/binding.c similarity index 99% rename from src/runtime/python/pypgf.c rename to src/runtime/python/pgf/binding.c index fec5e1578..5efb7a0be 100644 --- a/src/runtime/python/pypgf.c +++ b/src/runtime/python/pgf/binding.c @@ -863,7 +863,7 @@ static PyMethodDef module_methods[] = { }; PyMODINIT_FUNC -initpgf(void) +initbinding(void) { PyObject *m; @@ -879,7 +879,7 @@ initpgf(void) if (PyType_Ready(&pgf_ExprIterType) < 0) return; - m = Py_InitModule("pgf", module_methods); + m = Py_InitModule("binding", module_methods); if (m == NULL) return; diff --git a/src/runtime/python/pgf/expr.py b/src/runtime/python/pgf/expr.py new file mode 100644 index 000000000..83cccd39f --- /dev/null +++ b/src/runtime/python/pgf/expr.py @@ -0,0 +1,169 @@ +import pgf.binding +import StringIO + +class App: + """An application of a function to an argument""" + + def __init__(self, fun, arg): + self.fun = fun + self.arg = arg + + def showExpr(self, prec): + s = self.fun.showExpr(3) + " " + self.arg.showExpr(4) + if prec > 3: + s = "(" + s + ")" + return s + + def __str__(self): + return self.showExpr(0) + +class Lit: + """A literal value""" + + def __init__(self, value): + self.value = value + + def showExpr(self, prec): + if isinstance(self.value, str): + return '"' + self.value + '"' + else: + return str(self.value) + + def __str__(self): + return self.showExpr(0) + +class Meta: + """A meta variable""" + + def __init__(self, metaid): + self.metaid = metaid + + def showExpr(self, prec): + return "?" + + def __str__(self): + return self.showExpr(0) + +class Fun: + """A function name""" + + def __init__(self, name): + self.name = name + + def showExpr(self, prec): + return self.name + + def __str__(self): + return self.showExpr(0) + +class __ExprParser: + # token types + TOKEN_UNKNOWN = 0 + TOKEN_LPARENT = 1 + TOKEN_RPARENT = 2 + TOKEN_QUESTION = 3 + TOKEN_IDENT = 4 + TOKEN_STRING = 5 + TOKEN_INT = 6 + TOKEN_FLOAT = 7 + TOKEN_EOF = 8 + + def __init__(self, fh): + self.ch = ' ' + self.fh = fh + self.token = self.TOKEN_UNKNOWN + self.token_value = "" + self.readToken() + + def readToken(self): + while self.ch.isspace(): + self.ch = self.fh.read(1); + + self.token_value = "" + + if self.ch == '(': + self.ch = self.fh.read(1); + self.token = self.TOKEN_LPARENT + elif self.ch == ')': + self.ch = self.fh.read(1); + self.token = self.TOKEN_RPARENT + elif self.ch == '?': + self.ch = self.fh.read(1); + self.token = self.TOKEN_QUESTION + elif (self.ch.isalpha() or self.ch == '_'): + self.token = self.TOKEN_IDENT + while (self.ch.isalnum() or self.ch == '_' or self.ch == "'"): + self.token_value = self.token_value + self.ch + self.ch = self.fh.read(1) + elif self.ch == '"': + self.ch = self.fh.read(1) + self.token = self.TOKEN_STRING + while self.ch != '"': + if self.ch == '': + raise pgf.ParseError("Missing quotation mark") + self.token_value = self.token_value + self.ch + self.ch = self.fh.read(1) + self.ch = self.fh.read(1) + elif self.ch.isdigit(): + self.token = self.TOKEN_INT + while self.ch.isdigit(): + self.token_value = self.token_value + self.ch + self.ch = self.fh.read(1) + + if self.ch == '.': + self.token = self.TOKEN_FLOAT + + self.token_value = self.token_value + self.ch + self.ch = self.fh.read(1) + + while self.ch.isdigit(): + self.token_value = self.token_value + self.ch + self.ch = self.fh.read(1) + + elif self.ch == '': + self.token = self.TOKEN_EOF + else: + self.token = self.TOKEN_UNKNOWN + + def parseTerm(self): + if self.token == self.TOKEN_IDENT: + e = Fun(self.token_value) + self.readToken() + return e + elif self.token == self.TOKEN_LPARENT: + self.readToken() + e = self.parseExpr() + if self.token == self.TOKEN_RPARENT: + self.readToken() + return e; + else: + raise pgf.ParseError("Missing right parenthesis") + elif self.token == self.TOKEN_QUESTION: + e = Meta(0) + self.readToken() + return e + elif self.token == self.TOKEN_STRING: + e = Lit(self.token_value) + self.readToken() + return e + elif self.token == self.TOKEN_INT: + e = Lit(int(self.token_value)) + self.readToken() + return e + elif self.token == self.TOKEN_FLOAT: + e = Lit(float(self.token_value)) + self.readToken() + return e + else: + raise pgf.ParseError("Unknown token") + + def parseExpr(self): + e = self.parseTerm() + while (self.token != self.TOKEN_EOF and + self.token != self.TOKEN_RPARENT): + e = App(e, self.parseTerm()) + return e + +def readExpr_py(str): + parser = __ExprParser(StringIO.StringIO(str)) + return parser.parseExpr() diff --git a/src/runtime/python/setup.py b/src/runtime/python/setup.py index 7356cb6c1..6f908cfe1 100644 --- a/src/runtime/python/setup.py +++ b/src/runtime/python/setup.py @@ -1,11 +1,15 @@ from distutils.core import setup, Extension -pgf_module = Extension('pgf', - sources = ['pypgf.c'], +pgf_module = Extension('pgf.binding', + sources = ['pgf/binding.c'], extra_compile_args = ['-std=c99'], libraries = ['gu', 'pgf']) setup (name = 'pgf', version = '1.0', - description = 'This is binding to the PGF engine', + description = 'A binding to the PGF engine', + author='Krasimir Angelov', + author_email='kr.angelov@gmail.com', + license='BSD', + packages=['pgf'], ext_modules = [pgf_module])