mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-04-09 13:09:33 -06:00
170 lines
3.7 KiB
Python
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()
|