Ejemplo n.º 1
0
def factor():
    """
    Parses
        factor = ident selector | integer | "(" expression ")" | "not" factor.
    Generates code for the factor if no error is reported
    """
    if SC.sym not in FIRSTFACTOR:
        mark("factor expected"); getSym()
        while SC.sym not in FIRSTFACTOR | STRONGSYMS | FOLLOWFACTOR:
            getSym()
    if SC.sym == IDENT:
        x = find(SC.val)
        if type(x) in {Var, Ref}: x = genVar(x)
        elif type(x) == Const: x = Const(x.tp, x.val); x = genConst(x)
        else: mark('variable or constant expected')
        getSym(); x = selector(x)
    elif SC.sym == NUMBER:
        x = Const(Int, SC.val); x = genConst(x); getSym()
    elif SC.sym == LPAREN:
        getSym(); x = expression()
        if SC.sym == RPAREN: getSym()
        else: mark(") expected")
    elif SC.sym == NOT:
        getSym(); x = factor()
        if x.tp != Bool: mark('not boolean')
        elif type(x) == Const: x.val = 1 - x.val # constant folding
        else: x = genUnaryOp(NOT, x)
    else:
        mark("factor expected"); x = None
    return x
Ejemplo n.º 2
0
def statement():
    """
    Parses
        statement = ident selector ":=" expression |
                    ident "(" [expression {"," expression}] ")" |
                    compoundStatement |
                    "if" expression "then" Statement ["else" Statement] |
                    "while" expression "do" Statement.
    Generates code for the statement if no error is reported
    """
    if SC.sym not in FIRSTSTATEMENT:
        mark("statement expected")
        getSym()
        while SC.sym not in FIRSTSTATEMENT | STRONGSYMS | FOLLOWSTATEMENT:
            getSym()
    if SC.sym == IDENT:
        x = find(SC.val)
        getSym()
        x = genVar(x)
        if type(x) in {Var, Ref}:
            x = selector(x)
            if SC.sym == BECOMES:
                getSym()
                y = expression()
                if x.tp == y.tp in {Bool, Int}:
                    # if type(x) == Var: x = genAssign(x, y)
                    if type(x) == Var:
                        print("x: ", x, "y: ", y)
                        x = genAssign2(x, y)
                    else:
                        mark("illegal assignment")
                else:
                    mark("incompatible assignment")
            elif SC.sym == EQ:
                mark(":= expected")
                getSym()
                y = expression()
            else:
                mark(":= expected")
        elif type(x) in {Proc, StdProc} and SC.sym == LPAREN:
            getSym()
            fp, i = x.par, 0  #  list of formal parameters
            if SC.sym in FIRSTEXPRESSION:
                y = expression()
                if i < len(fp):
                    if type(fp[i]) == Var or type(y) == Var:  # fp[i] == Ref and ty
                        if type(x) == Proc:
                            genActualPara(y, fp[i], i)
                        i = i + 1
                    else:
                        mark("illegal parameter mode")
                else:
                    mark("extra parameter")
                while SC.sym == COMMA:
                    getSym()
                    y = expression()
                    if i < len(fp):
                        if type(fp[i]) == Var or type(y) == Var:
                            if type(x) == Proc:
                                genActualPara(y, fp[i], i)
                            i = i + 1
                        else:
                            mark("illegal parameter mode")
                    else:
                        mark("extra parameter")
            if i < len(fp):
                mark("too few parameters")
            if SC.sym == RPAREN:
                getSym()
            else:
                mark("')' expected")
            if type(x) == StdProc:
                if x.name == "read":
                    x = genRead(y)
                elif x.name == "write":
                    x = genWrite(y)
                elif x.name == "writeln":
                    x = genWriteln()
            else:
                x = genCall(x)
        else:
            mark("variable or procedure expected")
    elif SC.sym == BEGIN:
        x = compoundStatement()
    elif SC.sym == IF:
        getSym()
        x = expression()
        if x.tp == Bool:
            x = genCond(x)
        else:
            mark("boolean expected")
        if SC.sym == THEN:
            getSym()
        else:
            mark("'then' expected")
        y = statement()
        if SC.sym == ELSE:
            y = genThen(x, y)
            getSym()
            z = statement()
            x = genIfElse(x, y, z)
        else:
            x = genIfThen(x, y)
    elif SC.sym == WHILE:
        getSym()
        t = genTarget()
        x = expression()
        if x.tp == Bool:
            x = genCond(x)
        else:
            mark("boolean expected")
        if SC.sym == DO:
            getSym()
        else:
            mark("'do' expected")
        y = statement()
        x = genWhile(t, x, y)
    else:
        mark("invalid statement")
        x = None
    return x
Ejemplo n.º 3
0
def statement():
    """
    Parses
        statement = ident selector ":=" expression |
                    ident "(" [expression {"," expression}] ")" |
                    compoundStatement |
                    "if" expression "then" Statement ["else" Statement] |
                    "while" expression "do" Statement.
    Generates code for the statement if no error is reported
    """
    if SC.sym not in FIRSTSTATEMENT:
        mark("statement expected"); getSym()
        while SC.sym not in FIRSTSTATEMENT | STRONGSYMS | FOLLOWSTATEMENT:
            getSym()
    if SC.sym == IDENT:
        x = find(SC.val); getSym(); x = genVar(x)
        if type(x) in {Var, Ref}:
            x = selector(x)
            if SC.sym == BECOMES:
                getSym(); y = expression()
                if x.tp == y.tp in {Bool, Int}:
                    if type(x) == Var: x = genAssign(x, y)
                    else: mark('illegal assignment')
                else: mark('incompatible assignment')
            elif SC.sym == EQ:
                mark(':= expected'); getSym(); y = expression()
            else: mark(':= expected')
        elif type(x) in {Proc, StdProc} and SC.sym == LPAREN:
            getSym()
            fp, i = x.par, 0  	#  list of formal parameters
            if SC.sym in FIRSTEXPRESSION:
                y = expression()
                if i < len(fp):
                    if type(fp[i]) == Var or type(y) == Var: # fp[i] == Ref and ty
                        if type(x) == Proc: genActualPara(y, fp[i], i)
                        i = i + 1
                    else: mark('illegal parameter mode')
                else: mark('extra parameter')
                while SC.sym == COMMA:
                    getSym()
                    y = expression()
                    if i < len(fp):
                        if type(fp[i]) == Var or type(y) == Var:
                            if type(x) == Proc: genActualPara(y, fp[i], i)
                            i = i + 1
                        else: mark('illegal parameter mode')
                    else: mark('extra parameter')
            if i < len(fp): mark('too few parameters')
            if SC.sym == RPAREN: getSym()
            else: mark("')' expected")
            if type(x) == StdProc:
                if x.name == 'read': x = genRead(y)
                elif x.name == 'write': x = genWrite(y)
                elif x.name == 'writeln': x = genWriteln()
            else: x = genCall(x)
        else: mark("variable or procedure expected")
    elif SC.sym == BEGIN: x = compoundStatement()
    elif SC.sym == IF:
        getSym(); x = expression(); q=1;
        if x.tp == Bool: x = genCond(x)
		elif x.tp == Int: q = 0 				# if we skipped genrelation, prepare to skip following statement