Files
gf-core/src/runtime/python/pgf/expr.py

170 lines
3.7 KiB
Python

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()