summaryrefslogtreecommitdiff
path: root/src/runtime/python/pgf/expr.py
diff options
context:
space:
mode:
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()