#! /usr/bin/python next_token_buffer = [] def token(fd): global next_token_buffer if next_token_buffer: x = next_token_buffer.pop(0) return x c = fd.read(1) while c.isspace(): c = fd.read(1) if c in "+-*/^(),;{}": return c elif c.isdigit(): buf = [] while c.isdigit(): buf.append(c) c = fd.read(1) if not c.isspace(): next_token_buffer.append(c) return int("".join(buf)) elif c.isalpha(): if c == "D": return c buf = [] while c.isalpha(): buf.append(c) c = fd.read(1) if not c.isspace(): next_token_buffer.append(c) return ["function", "".join(buf)] else: return None def value(t): if isinstance(t, int): return float(t) else: if t[0] == "+": return value(t[1]) + value(t[2]) elif t[0] == "-": return value(t[1]) - value(t[2]) elif t[0] == "*": return value(t[1]) * value(t[2]) elif t[0] == "/": return value(t[1]) / value(t[2]) elif t[0] == "^": return value(t[1]) ** value(t[2]) else: raise "Operation not known" prec = {"+":1, "-":1, "*":2, "/":2, "^":3} left_assoc = "+-*/" right_assoc = "^" def parse(fd): out = [] x = parse2(fd) while x != None: if x: out.append( x + " [p]Sf z0f" ) x = parse2(fd) return " ".join(out) def parse2(fd, in_block=False): opers = [] out = [] quit_eof = True t = token(fd) while t: if isinstance(t, int): out.append(t) elif t[0] == "function": next = token(fd) if next == "(": opers.append(t) else: out.append("l%s" % t[1]) next_token_buffer.append(next) elif t == "D": out.append(parse_function(fd)) elif t == ";": if not in_block: quit_eof = False break elif t == "{": out.append(parse2(fd, True)) elif t == "}": if not in_block: raise "Syntax error", "not in {" quit_eof = False break elif t in "+-*/^": while opers and opers[-1] != "(" and ((t in left_assoc and prec[t] <= prec[opers[-1]]) or (t in right_assoc and prec[t] < prec[opers[-1]])): out.append(opers.pop()) opers.append(t) elif t == ",": while opers[-1] != "(": if not opers: raise "Syntax error: mismatched parens" out.append(opers.pop()) elif t == "(": opers.append(t) elif t == ")": op = opers.pop() while op != "(": out.append(op) if not opers: raise "Syntax error: mismatched parens" op = opers.pop() try: if opers[-1][0] == "function": if opers[-1][1] == "print": out.append("p Zd>r") opers.pop() else: out.append("l%sx" % opers.pop()[1]) except: pass t = token(fd) while opers: if opers[-1] == "(": raise "Syntax error: mismatched parens" try: if opers[-1][0] == "function": if opers[-1][1] == "print": out.append("p Zd>r") opers.pop() else: out.append("l%sx" % opers.pop()[1]) else: raise "get me out" except: out.append(opers.pop()) if quit_eof and not out: return None return " ".join(str(i) for i in out) def parse_function(fd): name = token(fd)[1] if token(fd) != "(": raise "Syntax error: no" args = [] t = token(fd) while t != ")": args.append(t[1]) t = token(fd) if t == ")": break if t != ",": raise "Syntax error: no" t = token(fd) body = parse2(fd) out = ["["] args.reverse() for arg in args: out.append("S%s" % arg) out.append(body) for arg in args: out.append("L%s Zd>r" % arg) out.append("] s%s" % name) return "".join(out) if __name__ == "__main__": from cStringIO import StringIO import sys x = StringIO("".join(sys.argv[1:])) y = parse(x) print y