summaryrefslogtreecommitdiff
path: root/src/runtime/python/pgf/expr.py
diff options
context:
space:
mode:
authorkr.angelov <kr.angelov@gmail.com>2013-01-07 15:11:12 +0000
committerkr.angelov <kr.angelov@gmail.com>2013-01-07 15:11:12 +0000
commit9b78da535700f561952d0b6498d84b187e9a1791 (patch)
tree64951ee67c511350671702016ab1b69c3e7350b4 /src/runtime/python/pgf/expr.py
parent2c169406fcfa7a38cd89f8a6acbd0bb138d7c330 (diff)
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
Diffstat (limited to 'src/runtime/python/pgf/expr.py')
-rw-r--r--src/runtime/python/pgf/expr.py169
1 files changed, 169 insertions, 0 deletions
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()