def parseRest(exp1,toks): if toks.null(): return (exp1,toks) else: with toks as (b,bs): if b == neg: exp2,rest = force( parseAtom(bs) ) return parseRest( Diff_exp(exp1,exp2) ,rest) elif b == lf: exp2,rest = force( parseExp(bs) ) return parseRest( Call_exp(exp1,exp2) ,strip(rf,rest) ) else: return (exp1,toks)
def parseRest(exp1, toks): if toks.null(): return (exp1, toks) else: with toks as (b, bs): if b == "+": exp2, rest = force(parseAtom(bs)) return parseRest(["BinOp", exp1, b, exp2], rest) elif b == '-': exp2, rest = force(parseAtom(bs)) return parseRest(["BinOp", exp1, b, exp2], rest) else: return (exp1, toks)
def read(inp): output = force( parseExp(Lex(inp)) ) with unpack(output) as (result,rest): if rest.null(): return result else: raise ParseError("not all: {}".format(output))
def parseTypeRest(typ1,toks): if toks.null(): return (typ1,toks) else: with toks as (b,rest): if b == "->": typ2,rest2 = force( parseTypeAtom(rest) ) return parseTypeRest( Proc_Type(typ1,typ2) ,rest2) else: return (typ1,toks)
def parseTypeAtom(toks): if toks.null(): raise ParseError("parseTypeError: {} is null".format(toks)) else: with toks as (typ,rest): if IsType(typ): return ToType(typ),rest elif typ == lf : typ1 ,rest1 = force( parseType(rest) ) #print typ1 return typ1,strip(rf,rest1) else: raise ParseError("parseTypeError: {} ,{}".format(var,rest))
def parseAtom(toks): with toks as (op, rest): if op == "if": exp1, rest1 = force(parseExp(rest)) exp2, rest2 = force(parseExp(strip("then", rest1))) exp3, rest3 = force(parseExp(strip("else", rest2))) return ["If", exp1, exp2, exp3], rest3 elif op == "let": var1, rest1 = force(parseVar(rest)) exp1, rest2 = force(parseExp(strip("=", rest1))) body, rest3 = force(parseExp(strip("in", rest2))) return ["Let", var1, exp1, body], rest3 elif IsBool(op): return ["Bool", ToBool(op)], rest elif IsNum(op): return ["Num", int(op)], rest elif IsId(op): return ["Id", op], rest elif op == '(': exp1, rest1 = force(parseExp(rest)) return exp1, strip(')', rest1) else: raise ParseError("parseAtom")
def parseExp(toks): exp1, rest1 = force(parseAtom(toks)) return parseRest(exp1, rest1)
def read(inp): return force(parseExp(Lex(inp)))
with toks as (b, bs): if b == "+": exp2, rest = force(parseAtom(bs)) return parseRest(["BinOp", exp1, b, exp2], rest) elif b == '-': exp2, rest = force(parseAtom(bs)) return parseRest(["BinOp", exp1, b, exp2], rest) else: return (exp1, toks) inp = Lex(""" let b = 3 in if 6 + b then true else false """) print(force(parseExp(inp))) # if true then a else b def read(inp): return force(parseExp(Lex(inp))) print( read(""" let a = if true then 233 else 332 in (if (let c = a + a in c + a) then true - 1 else false + 1) """))
def _f(lst): lst = list(reversed(lst)) return force(f(lst, []))
def parseAtom(toks): if toks.null(): raise ParseError("toks is null: {}".format(toks)) with toks as (op,rest): if op == If: exp1,rest1 = force( parseExp(rest) ) exp2,rest2 = force( parseExp( strip("then",rest1)) ) exp3,rest3 = force( parseExp( strip("else",rest2)) ) return If_exp(exp1,exp2,exp3),rest3 elif op == Let: var1,rest1 = force( parseVar(rest) ) exp1,rest2 = force( parseExp(strip(Defn,rest1)) ) body,rest3 = force( parseExp(strip(In,rest2)) ) return Let_exp(var1,exp1,body),rest3 elif op == LetRec: pname,rest1 = force( parseVar(rest) ) pvar,rest2 = force( parseVar(strip(lf,rest1) ) ) var_typ,rest3 = force( parseType( strip(":",rest2) ) ) res_typ,rest4 = force( parseType( strip(":",strip(rf,rest3)) )) pbody,rest5 = force( parseExp( strip("=",rest4) ) ) lbody,rest6 = force( parseExp(strip(In,rest5)) ) return Letrec_exp(pname,pvar,pbody,lbody,var_typ,res_typ),rest6 elif op == Zero: exp1,rest1 = force( parseExp( strip("?",rest) ) ) return Zerop_exp(exp1),rest1 elif op == Fn: var,rest1 = force( parseVar(strip(lf,rest)) ) var_type,rest2 = force( parseType(strip(":",rest1) ) ) body,rest2 = force( parseExp(strip(rf,rest2) ) ) return Proc_exp(var,var_type,body),rest2 elif IsNum(op): return Const_exp(int(op)),rest elif IsId(op): return Var_exp(op),rest elif op == lf: exp1,rest1 = force( parseExp(rest) ) #try: # exp2,rest2 = force(parseExp(rest1) ) # return Call_exp(exp1,exp2),strip(rf,rest2) #except ParseError: # return exp1,strip(rf,rest1) return exp1,strip(rf,rest1) else: raise ParseError("parseAtomError: {},{}".format(op,rest))
def parseType(toks): typ1,rest1 = force( parseTypeAtom(toks) ) return parseTypeRest(typ1,rest1)