Exemplo n.º 1
0
def declarations(allocVar):
    while SC.sym == CONST:
        getSym()
        if SC.sym == IDENT: ident = SC.val; getSym()
        else: mark("constant name expected")
        if SC.sym == EQ: getSym()
        else: mark("= expected")
        x = expression()
        if type(x) == Const: newDecl(ident, x)
        else: mark('expression not constant')
    while SC.sym == TYPE:
        getSym()
        if SC.sym == IDENT: ident = SC.val; getSym()
        else: mark("type name expected")
        if SC.sym == EQ: getSym()
        else: mark("= expected")
        x = typ(); newDecl(ident, x)  #  x is of type ST.Type
    start = len(topScope())
    while SC.sym == VAR:
        getSym(); typedIds()
    var = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        getSym()
        if SC.sym == LPAREN:
            getSym()
            if SC.sym == IDENT: r = SC.val; getSym()
            else: mark("identifier expected")
            if SC.sym == COLON: getSym()
            else: mark("':' expected")
            tp = typ().val
            if SC.sym == RPAREN: getSym()
            else: mark(") expected")
        else: r = None
        if SC.sym == IDENT: ident = SC.val; getSym()
        else: mark("procedure name expected")
        newDecl(ident, Proc([], [])) #  entered without parameters
        sc = topScope(); openScope() # new scope for parameters and body
        if r: newDecl(r, Var(tp))
        if SC.sym == LPAREN: getSym()
        else: mark("( expected")
        if SC.sym == IDENT: typedIds()
        fp = topScope()
        if SC.sym == RPAREN: getSym()
        else: mark(") expected")
        d = len(fp)
        if SC.sym == RARROW:
            getSym()
            if SC.sym == LPAREN: getSym()
            else: mark('( expected')
            typedIds()
            if SC.sym == RPAREN: getSym()
            else: mark(') expected')
        sc[-1].par, sc[-1].res = fp[:d], fp[d:] #  procedure parameters updated
        para = CG.genProcStart(ident, fp[:d], fp[d:])
        body(ident, para); closeScope() #  scope for parameters and body closed
    return var
Exemplo n.º 2
0
def typ():
    """
    Parses
        type = ident |
               "array" "[" expression ".." expression "]" "of" type |
               "record" typedIds {";" typedIds} "end".
    Returns a type descriptor 
    """
    if SC.sym not in FIRSTTYPE:
        getSym()
        mark("type expected", 37)
        while SC.sym not in FIRSTTYPE | FOLLOWTYPE | STRONGSYMS:
            getSym()
    if SC.sym == IDENT:
        ident = SC.val
        x = find(ident)
        getSym()
        if type(x) == Type: x = Type(x.tp)
        else: mark('not a type', 38)
    elif SC.sym == ARRAY:
        getSym()
        if SC.sym == LBRAK: getSym()
        else: mark("'[' expected", 39)
        x = expression()
        if type(x) != Const or x.val < 0: mark('bad lower bound', 40)
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected", 41)
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected", 42)
        y = expression()
        if type(y) != Const or y.val < x.val: mark('bad upper bound', 43)
        if SC.sym == RBRAK: getSym()
        else: mark("']' expected", 44)
        if SC.sym == OF: getSym()
        else: mark("'of' expected", 45)
        z = typ().tp
        l = y.val - x.val + 1
        x = Type(genArray(Array(z, x.val, l)))
    elif SC.sym == RECORD:
        getSym()
        openScope()
        typedIds(Var)
        while SC.sym == SEMICOLON:
            getSym()
            typedIds(Var)
        if SC.sym == END: getSym()
        else: mark("'end' expected", 46)
        r = topScope()
        closeScope()
        x = Type(genRec(Record(r)))
    else:
        mark("type expected", 47)
        x = Type(None)
    return x
Exemplo n.º 3
0
def typ():
    if SC.sym not in FIRSTTYPE:
        getSym()
        mark("type expected")
        while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE:
            getSym()
    if SC.sym == IDENT:
        ident = SC.val
        x = find(ident)
        getSym()
        if type(x) == Type: x = Type(x.val)
        else:
            mark('not a type')
            x = Type(None)
    elif SC.sym == ARRAY:
        getSym()
        if SC.sym == LBRAK: getSym()
        else: mark("'[' expected")
        x = expression()
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected")
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected")
        y = expression()
        if SC.sym == RBRAK: getSym()
        else: mark("']' expected")
        if SC.sym == OF: getSym()
        else: mark("'of' expected")
        z = typ().val
        if type(x) != Const or x.val < 0:
            mark('bad lower bound')
            x = Type(None)
        elif type(y) != Const or y.val < x.val:
            mark('bad upper bound')
            x = Type(None)
        else:
            x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1)))
    elif SC.sym == RECORD:
        getSym()
        openScope()
        typedIds(Var)
        while SC.sym == SEMICOLON:
            getSym()
            typedIds(Var)
        if SC.sym == END: getSym()
        else: mark("'end' expected")
        r = topScope()
        closeScope()
        x = Type(CG.genRec(Record(r)))
    else:
        x = Type(None)
    return x
Exemplo n.º 4
0
def program():
    newDecl('boolean', Type(CG.genBool(Bool)))
    newDecl('integer', Type(CG.genInt(Int)))
    newDecl('true', Const(Bool, 1))
    newDecl('false', Const(Bool, 0))
    newDecl('read', StdProc([], [Var(Int)]))
    newDecl('write', StdProc([Var(Int)], []))
    newDecl('writeln', StdProc([], []))
    CG.genProgStart()
    declarations(CG.genGlobalVars)
    if SC.sym == PROGRAM: getSym()
    else: mark("'program' expected")
    ident = SC.val
    if SC.sym == IDENT: getSym()
    else: mark('program name expected')
    openScope(); CG.genProgEntry(ident); x = body(ident, 0)
    closeScope(); x = CG.genProgExit(x)
    return x
Exemplo n.º 5
0
def typ():
    """
    Parses
        type = ident |
               "array" "[" expression ".." expression "]" "of" type |
               "record" typedIds {";" typedIds} "end".
    Returns a type descriptor 
    """
    if SC.sym not in FIRSTTYPE:
        getSym(); mark("type expected")
        while SC.sym not in FIRSTTYPE | FOLLOWTYPE |STRONGSYMS:
            getSym()
    if SC.sym == IDENT:
        ident = SC.val; x = find(ident); getSym()
        if type(x) == Type: x = Type(x.tp)
        else: mark('not a type')
    elif SC.sym == ARRAY:
        getSym()
        if SC.sym == LBRAK: getSym()
        else: mark("'[' expected")
        x = expression()
        if type(x) != Const or x.val < 0: mark('bad lower bound')
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected")
        if SC.sym == PERIOD: getSym()
        else: mark("'.' expected")
        y = expression()
        if type(y) != Const or y.val < x.val: mark('bad upper bound')
        if SC.sym == RBRAK: getSym()
        else: mark("']' expected")
        if SC.sym == OF: getSym()
        else: mark("'of' expected")
        z = typ().tp; l = y.val - x.val + 1
        x = Type(genArray(Array(z, x.val, l)))
    elif SC.sym == RECORD:
        getSym(); openScope(); typedIds(Var)
        while SC.sym == SEMICOLON:
            getSym(); typedIds(Var)
        if SC.sym == END: getSym()
        else: mark("'end' expected")
        r = topScope(); closeScope()
        x = Type(genRec(Record(r)))
    else: mark("type expected"); x = Type(None)
    return x
Exemplo n.º 6
0
def typ():
    if SC.sym == IDENT:
        ident = SC.val; x = find(ident)
        if type(x) == Type: x = Type(x.val); getSym()
        else: mark('type identifier expected')
    elif SC.sym == LBRAK:
        getSym(); x = expression()
        if SC.sym == DOTDOT: getSym()
        else: mark("'..' expected")
        y = expression()
        if SC.sym == RBRAK: getSym()
        else: mark("']' expected")
        if SC.sym == RARROW: getSym()
        else: mark("'→' expected")
        z = typ().val;
        if type(x) != Const or x.val < 0: mark('bad lower bound')
        elif type(y) != Const or y.val < x.val: mark('bad upper bound')
        else: x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1)))
    elif SC.sym == LPAREN:
        getSym(); openScope(); typedIds()
        if SC.sym == RPAREN: getSym()
        else: mark("')' expected")
        r = topScope(); closeScope()
        x = Type(CG.genRec(Record(r)))
    elif SC.sym == FULLPAREN:
        pass
    elif SC.sym == SET:
        getSym();
        if SC.sym == LBRAK: getSym()
        else: mark ("'[' expected")
        x = expression()
        if SC.sym == DOTDOT: getSym()
        else: mark("'..' expected")
        y = expression()
        if SC.sym == RBRAK: getSym()
        else: mark("']' expected")
        if type(x) != Const: mark('bad lower bound')
        elif type(y) != Const or y.val < x.val: mark('bad upper bound')
        else: x = Type(CG.genSet(Set(x.val, y.val - x.val + 1)))
    else: mark('type expected')
    return x
Exemplo n.º 7
0
def declarations(allocVar):
    if SC.sym not in FIRSTDECL | FOLLOWDECL:
        getSym()
        mark("'begin' or declaration expected")
        while SC.sym not in FIRSTDECL | STRONGSYMS | FOLLOWDECL:
            getSym()
    while SC.sym == CONST:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                getSym()
            else:
                mark("= expected")
            x = expression()
            if type(x) == Const:
                newDecl(ident, x)
            else:
                mark('expression not constant')
        else:
            mark("constant name expected")
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    while SC.sym == TYPE:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                getSym()
            else:
                mark("= expected")
            x = typ()
            newDecl(ident, x)  # x is of type ST.Type
            if SC.sym == SEMICOLON:
                getSym()
            else:
                mark("; expected")
        else:
            mark("type name expected")
    start = len(topScope())
    while SC.sym == VAR:
        getSym()
        typedIds(Var)
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    varsize = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        getSym()
        if SC.sym == IDENT:
            getSym()
        else:
            mark("procedure name expected")
        ident = SC.val
        newDecl(ident, Proc([]))  # entered without parameters
        sc = topScope()
        CG.genProcStart()
        openScope()  # new scope for parameters and body
        if SC.sym == LPAREN:
            getSym()
            if SC.sym in {VAR, IDENT}:
                if SC.sym == VAR:
                    getSym()
                    typedIds(Ref)
                else:
                    typedIds(Var)
                while SC.sym == SEMICOLON:
                    getSym()
                    if SC.sym == VAR:
                        getSym()
                        typedIds(Ref)
                    else:
                        typedIds(Var)
            else:
                mark("formal parameters expected")
            fp = topScope()
            sc[-1].par = fp[:]  # procedure parameters updated
            if SC.sym == RPAREN:
                getSym()
            else:
                mark(") expected")
        else:
            fp = []
        parsize = CG.genFormalParams(fp)
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
        localsize = declarations(CG.genLocalVars)
        CG.genProcEntry(ident, parsize, localsize)
        x = compoundStatement()
        CG.genProcExit(x, parsize, localsize)
        closeScope()  # scope for parameters and body closed
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    return varsize
Exemplo n.º 8
0
def declarations(allocVar):
    """
    Parses
        declarations =
            {"const" ident "=" expression ";"}
            {"type" ident "=" type ";"}
            {"var" typedIds ";"}
            {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";"
                declarations compoundStatement ";"}.
    Updates current scope of symbol table.
    Reports an error if an identifier is already defined in the current scope.
    For each procedure, code is generated
    """
    global depth
    if SC.sym not in FIRSTDECL | FOLLOWDECL:
        getSym()
        mark("'begin' or declaration expected")
        while SC.sym not in FIRSTDECL | STRONGSYMS | FOLLOWDECL:
            getSym()
    while SC.sym == CONST:
        # attributes
        depth += 1
        write(indent * depth)
        write('const')
        writeln()
        writeHtml(htmlIndent * depth)
        writeHtml('const')
        writeHtmlLn()
        #
        getSym()
        if SC.sym == IDENT:
            # attributes
            depth += 1
            ident = SC.val
            write(indent * depth)
            write(ident)
            writeHtml(htmlIndent * depth)
            # integer constant is upright
            writeHtml(ident)
            #
            getSym()
            if SC.sym == EQ:
                # attribute
                write(' = ')
                writeHtml(' = ')
                #
                getSym()
            else:
                mark("= expected")
            x = expression()
            if type(x) == Const: newObj(ident, x)
            else: mark('expression not constant')
            depth -= 1
        else:
            mark("constant name expected")
        if SC.sym == SEMICOLON:
            # attributes
            write(';')
            writeln()
            writeHtml(';')
            writeHtmlLn()
            #
            getSym()
        else:
            mark("; expected")
        depth -= 1
    while SC.sym == TYPE:
        # attributes
        depth += 1
        write(indent * depth)
        write('type')
        writeln()
        writeHtml(htmlIndent * depth)
        writeHtml('type')
        writeHtmlLn()
        #
        getSym()
        if SC.sym == IDENT:
            # attributes
            depth += 1
            ident = SC.val
            write(indent * depth)
            write(ident)
            writeHtml(htmlIndent * depth)
            writeHtml(ident, _class='ident')
            #
            getSym()
            if SC.sym == EQ:
                # attributes
                write(' = ')
                writeHtml(' = ')
                #
                getSym()
            else:
                mark("= expected")
            # attributes (emulate stack)
            old_depth = depth
            depth += 1
            x = typ()
            depth = old_depth
            #
            newObj(ident, x)  #  x is of type ST.Type
            if SC.sym == SEMICOLON:
                # attribute
                write(';')
                writeln()
                writeHtml(';')
                writeHtmlLn()
                getSym()
                #
            else:
                mark("; expected")
            depth -= 1
        else:
            mark("type name expected")
        depth -= 1
    start = len(topScope())
    while SC.sym == VAR:
        # attributes
        depth += 1
        write(indent * depth)
        write('var')
        writeln()
        writeHtml(htmlIndent * depth)
        writeHtml('var')
        writeHtmlLn()
        depth += 1
        getSym()
        write(indent * depth)
        write(SC.val)
        writeHtml(htmlIndent * depth)
        writeHtml(SC.val)
        #
        typedIds(Var)
        if SC.sym == SEMICOLON:
            #
            write(';')
            writeln()
            writeHtml(';')
            writeHtmlLn()
            getSym()
            #
        else:
            mark("; expected")
        depth -= 2
    varsize = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        #
        depth += 1
        write(indent * depth)
        write('procedure ')
        writeHtml(htmlIndent * depth)
        writeHtml('procedure ')
        #
        getSym()
        if SC.sym == IDENT:
            #
            write(SC.val)
            writeHtml(SC.val)
            #
            getSym()
        else:
            mark("procedure name expected")
        ident = SC.val
        newObj(ident, Proc([]))  #  entered without parameters
        sc = topScope()
        CG.procStart()
        openScope()  # new scope for parameters and body
        if SC.sym == LPAREN:
            #
            write('(')
            writeHtml('(')
            #
            getSym()
            if SC.sym in {VAR, IDENT}:
                if SC.sym == VAR:
                    #
                    write('var ')
                    writeHtml('var ')
                    getSym()
                    write(SC.val)
                    writeHtml(SC.val)
                    #
                    typedIds(Ref)
                else:
                    typedIds(Var)
                while SC.sym == SEMICOLON:
                    #
                    write('; ')
                    writeHtml('; ')
                    #
                    getSym()
                    if SC.sym == VAR:
                        #
                        write('var ')
                        writeHtml('var ')
                        getSym()
                        write(SC.val)
                        writeHtml(SC.val)
                        #
                        typedIds(Ref)
                    else:
                        #
                        write(SC.val)
                        writeHtml(SC.val)
                        #
                        typedIds(Var)
            else:
                mark("formal parameters expected")
            fp = topScope()
            sc[-1].par = fp[:]  #  procedure parameters updated
            if SC.sym == RPAREN:
                #
                write(')')
                writeHtml(')')
                #
                getSym()
            else:
                mark(") expected")
        else:
            fp = []
        parsize = CG.genFormalParams(fp)
        if SC.sym == SEMICOLON:
            #
            write(';')
            writeln()
            writeHtml(';')
            writeHtmlLn()
            #
            getSym()
        else:
            mark("; expected")
        depth += 1
        localsize = declarations(CG.genLocalVars)
        CG.genProcEntry(ident, parsize, localsize)
        x = compoundStatement(depth + 1)
        CG.genProcExit(x, parsize, localsize)
        closeScope()  #  scope for parameters and body closed
        if SC.sym == SEMICOLON: getSym()
        else: mark("; expected")
        depth -= 1
    return varsize
Exemplo n.º 9
0
def typ():
    """
    Parses
        type = ident |
               "array" "[" expression ".." expression "]" "of" type |
               "record" typedIds {";" typedIds} "end".
    Returns a type descriptor
    """
    global depth
    if SC.sym not in FIRSTTYPE:
        getSym()
        mark("type expected")
        while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE:
            getSym()
    if SC.sym == IDENT:
        # attribute
        ident = SC.val
        write(ident)
        writeHtml(ident, _class='ident')
        #
        x = find(ident)
        getSym()
        if type(x) == Type: x = Type(x.tp)
        else:
            mark('not a type')
            x = Type(None)
    elif SC.sym == ARRAY:
        depth += 1
        # attribute
        writeln()
        write(indent * depth)
        write('array ')
        writeHtmlLn()
        writeHtml(htmlIndent * depth)
        writeHtml('array ')
        #
        getSym()
        if SC.sym == LBRAK:
            # attribute
            write('[')
            writeHtml('[')
            #
            getSym()
        else:
            mark("'[' expected")
        x = expression()
        if SC.sym == PERIOD:
            # attribute
            write(' .')
            writeHtml(' .')
            #
            getSym()
        else:
            mark("'.' expected")
        if SC.sym == PERIOD:
            # attribute
            write('. ')
            writeHtml('. ')
            #
            getSym()
        else:
            mark("'.' expected")
        y = expression()
        if SC.sym == RBRAK:
            # attribute
            write('] ')
            writeHtml('] ')
            #
            getSym()
        else:
            mark("']' expected")
        if SC.sym == OF:
            # attribute
            write('of')
            writeHtml('of')
            #
            getSym()
        else:
            mark("'of' expected")
        z = typ().tp
        if type(x) != Const or x.val < 0:
            mark('bad lower bound')
            x = Type(None)
        elif type(y) != Const or y.val < x.val:
            mark('bad upper bound')
            y = Type(None)
        else:
            x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1)))
        depth -= 1
    elif SC.sym == RECORD:
        # attributes
        depth += 1
        writeln()
        write(indent * depth)
        write('record')
        writeln()
        writeHtmlLn()
        writeHtml(htmlIndent * depth)
        writeHtml('record')
        writeHtmlLn()
        depth += 1
        #
        getSym()

        # attributes
        write(indent * depth)
        write(SC.val)
        writeHtml(htmlIndent * depth)
        writeHtml(SC.val)
        #
        openScope()
        typedIds(Var)
        while SC.sym == SEMICOLON:
            # attributes
            write(';')
            writeln()
            writeHtml(';')
            writeHtmlLn()
            #
            getSym()

            # attributes
            write(indent * depth)
            write(SC.val)
            writeHtml(htmlIndent * depth)
            writeHtml(SC.val)
            #
            typedIds(Var)
        # attributes
        writeln()
        writeHtmlLn()
        depth -= 1
        write(indent * depth)
        writeHtml(htmlIndent * depth)
        #
        if SC.sym == END:
            # attributes
            write('end')
            writeHtml('end')
            #
            getSym()
        else:
            mark("'end' expected")
        r = topScope()
        closeScope()
        x = Type(CG.genRec(Record(r)))
        depth -= 1
    else:
        x = Type(None)
    return x
Exemplo n.º 10
0
def declarations(allocVar):
    """
    Parses
        declarations =
            {"const" ident "=" expression ";"}
            {"type" ident "=" type ";"}
            {"var" typedIds ";"}
            {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";"
                declarations compoundStatement ";"}.
    Updates current scope of symbol table.
    Reports an error if an identifier is already defined in the current scope.
    For each procedure, code is generated
    """
    if SC.sym not in FIRSTDECL | FOLLOWDECL:
        getSym()
        mark("declaration expected")
        while SC.sym not in FIRSTDECL | FOLLOWDECL:
            getSym()
    while SC.sym == CONST:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                getSym()
            else:
                mark("= expected")
            x = expression()
            if type(x) == Const:
                newObj(ident, x)
            else:
                mark("expression not constant")
        else:
            mark("constant name expected")
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    while SC.sym == TYPE:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                getSym()
            else:
                mark("= expected")
            x = typ()
            newObj(ident, x)  #  x is of type ST.Type
            if SC.sym == SEMICOLON:
                getSym()
            else:
                mark("; expected")
        else:
            print(SC.sym)
            mark("type name expected")
    start = len(topScope())
    while SC.sym == VAR:
        getSym()
        typedIds(Var)
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    varsize = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        getSym()
        if SC.sym == IDENT:
            getSym()
        else:
            mark("procedure name expected")
        ident = SC.val
        newObj(ident, Proc([]))  #  entered without parameters
        sc = topScope()
        procStart()
        openScope()  # new scope for parameters and body
        if SC.sym == LPAREN:
            getSym()
            if SC.sym in {VAR, IDENT}:
                if SC.sym == VAR:
                    getSym()
                    typedIds(Ref)  # , procParams)
                else:
                    typedIds(Var)  # , procParams)
                while SC.sym == SEMICOLON:
                    getSym()
                    if SC.sym == VAR:
                        getSym()
                        typedIds(Ref)  # , procParams)
                    else:
                        typedIds(Var)  # , procParams)
            else:
                mark("formal parameters expected")
            fp = topScope()
            sc[-1].par = fp[:]  #  procedure parameters updated
            if SC.sym == RPAREN:
                getSym()
            else:
                mark(") expected")
        else:
            fp = []
        parsize = genFormalParams(fp)
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
        localsize = declarations(genLocalVars)
        genProcEntry(ident, parsize, localsize)
        x = compoundStatement()
        genProcExit(x, parsize, localsize)
        closeScope()  #  scope for parameters and body closed
        if SC.sym == SEMICOLON:
            getSym()
        else:
            mark("; expected")
    return varsize
Exemplo n.º 11
0
def declarations(allocVar, l):
    """
    Parses
        declarations(l) =
            {"const" «writeln; write(l * indent + 'const')» ident «writeln; write((l + 1) * indent + ident)» "=" «write(' = ')» expression ";" «write(';')»}
            {"type" «writeln; write(l * indent + 'type')» ident «writeln; write((l + 1) * indent + ident)» "=" «write(' = ')» type(l + 1) ";" «write(';')»}
            {"var" «writeln; write(l * indent + 'var')» «writeln; write((l + 1) * indent)» typedIds(l + 1) ";" «write(';')»}
            {"procedure" «writeln; write(l * indent + 'procedure ')» ident «write(ident)» ["(" «write('(')» [["var" «write('var ')»] typedIds(l) {";" «write('; ')» ["var" «write('var ')»] typedIds(l)}] ")" «write(')')»] ";" «write(";")»
                declarations(l + 1) compoundStatement(l + 1) ";"}.
    Updates current scope of symbol table.
    Reports an error if an identifier is already defined in the current scope.
    For each procedure, code is generated
    """
    if SC.sym not in FIRSTDECL | FOLLOWDECL:
        getSym()
        mark("'begin' or declaration expected")
        while SC.sym not in FIRSTDECL | STRONGSYMS | FOLLOWDECL:
            getSym()
    while SC.sym == CONST:
        writeln()
        write(l * indent + 'const')
        getSym()
        if SC.sym == IDENT:
            writeln()
            write((l + 1) * indent + SC.val)
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                write(' = ')
                getSym()
            else:
                mark("= expected")
            x = expression()
            if type(x) == Const: newObj(ident, x)
            else: mark('expression not constant')
        else: mark("constant name expected")
        if SC.sym == SEMICOLON:
            write(';')
            getSym()
        else:
            mark("; expected")
    while SC.sym == TYPE:
        writeln()
        write(l * indent + 'type')
        getSym()
        if SC.sym == IDENT:
            writeln()
            write((l + 1) * indent + ident)
            ident = SC.val
            getSym()
            if SC.sym == EQ:
                write(' = ')
                getSym()
            else:
                mark("= expected")
            x = typ(l + 1)
            newObj(ident, x)  #  x is of type ST.Type
            if SC.sym == SEMICOLON:
                write(';')
                getSym()
            else:
                mark("; expected")
        else:
            mark("type name expected")
    start = len(topScope())
    while SC.sym == VAR:
        writeln()
        write(l * indent + 'var')
        getSym()
        writeln()
        write((l + 1) * indent)
        typedIds(Var, l + 1)
        if SC.sym == SEMICOLON:
            write(';')
            getSym()
        else:
            mark("; expected")
    varsize = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        writeln()
        write(l * indent + 'procedure ')
        getSym()
        if SC.sym == IDENT:
            write(SC.val)
            getSym()
        else:
            mark("procedure name expected")
        ident = SC.val
        newObj(ident, Proc([]))  #  entered without parameters
        sc = topScope()
        CG.procStart()
        openScope()  # new scope for parameters and body
        if SC.sym == LPAREN:
            write('(')
            getSym()
            if SC.sym in {VAR, IDENT}:
                if SC.sym == VAR:
                    write('var ')
                    getSym()
                    typedIds(Ref, l)
                else:
                    typedIds(Var, l)
                while SC.sym == SEMICOLON:
                    write('; ')
                    getSym()
                    if SC.sym == VAR:
                        write('var ')
                        getSym()
                        typedIds(Ref, l)
                    else:
                        typedIds(Var, l)
            else:
                mark("formal parameters expected")
            fp = topScope()
            sc[-1].par = fp[:]  #  procedure parameters updated
            if SC.sym == RPAREN:
                write(')')
                getSym()
            else:
                mark(") expected")
        else:
            fp = []
        parsize = CG.genFormalParams(fp)
        if SC.sym == SEMICOLON:
            write(';')
            getSym()
        else:
            mark("; expected")
        localsize = declarations(CG.genLocalVars, l + 1)
        CG.genProcEntry(ident, parsize, localsize)
        x = compoundStatement(l + 1)
        CG.genProcExit(x, parsize, localsize)
        closeScope()  #  scope for parameters and body closed
        if SC.sym == SEMICOLON:
            write(';')
            getSym()
        else:
            mark("; expected")
    return varsize
Exemplo n.º 12
0
def typ(l):
    """
    Parses
        type(l) = ident «write(ident)» |
               "array" «writeln; write((l + 1) * indent + 'array ')» "[" «write('[')» expression ".." «write(' .. ')» expression "]" «write(']')» "of" «write(' of ')» type(l)|
               "record" «writeln; write((l + 1) * indent + 'record')» typedIds(l) {";" «write(';')» typedIds(l)} "end" «writeln; write((l + 1) * indent + 'end')».
    Returns a type descriptor 
    """
    if SC.sym not in FIRSTTYPE:
        getSym()
        mark("type expected")
        while SC.sym not in FIRSTTYPE | STRONGSYMS | FOLLOWTYPE:
            getSym()
    if SC.sym == IDENT:
        write(SC.val)
        ident = SC.val
        x = find(ident)
        getSym()
        if type(x) == Type: x = Type(x.tp)
        else:
            mark('not a type')
            x = Type(None)
    elif SC.sym == ARRAY:
        writeln()
        write((l + 1) * indent + 'array ')
        getSym()
        if SC.sym == LBRAK:
            write('[')
            getSym()
        else:
            mark("'[' expected")
        x = expression()
        if SC.sym == PERIOD:
            write(' .')
            getSym()
        else:
            mark("'.' expected")
        if SC.sym == PERIOD:
            write('. ')
            getSym()
        else:
            mark("'.' expected")
        y = expression()
        if SC.sym == RBRAK:
            write(']')
            getSym()
        else:
            mark("']' expected")
        if SC.sym == OF:
            write(' of ')
            getSym()
        else:
            mark("'of' expected")
        z = typ(l + 1).tp
        if type(x) != Const or x.val < 0:
            mark('bad lower bound')
            x = Type(None)
        elif type(y) != Const or y.val < x.val:
            mark('bad upper bound')
            y = Type(None)
        else:
            x = Type(CG.genArray(Array(z, x.val, y.val - x.val + 1)))
    elif SC.sym == RECORD:
        writeln()
        write((l + 1) * indent + 'record ')
        writeln()
        write((l + 2) * indent)
        getSym()
        openScope()
        typedIds(Var, l + 2)
        while SC.sym == SEMICOLON:
            write(';')
            writeln()
            write((l + 2) * indent)
            getSym()
            typedIds(Var, l + 2)
        if SC.sym == END:
            writeln()
            write((l + 1) * indent + 'end')
            getSym()
        else:
            mark("'end' expected")
        r = topScope()
        closeScope()
        x = Type(CG.genRec(Record(r)))
    else:
        x = Type(None)
    return x
Exemplo n.º 13
0
def declarations(allocVar):
    """
    Parses
        declarations =
            {"const" ident "=" expression ";"}
            {"type" ident "=" type ";"}
            {"var" typedIds ";"}
            {"procedure" ident ["(" [["var"] typedIds {";" ["var"] typedIds}] ")"] ";"
                declarations compoundStatement ";"}.
    Updates current scope of symbol table.
    Reports an error if an identifier is already defined in the current scope.
    For each procedure, code is generated
    """
    if SC.sym not in FIRSTDECL | FOLLOWDECL:
        getSym()
        mark("declaration expected", 50)
        while SC.sym not in FIRSTDECL | FOLLOWDECL:
            getSym()
    while SC.sym == CONST:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ: getSym()
            else: mark("= expected", 51)
            x = expression()
            if type(x) == Const: newObj(ident, x)
            else: mark('expression not constant', 52)
        else: mark("constant name expected", 53)
        if SC.sym == SEMICOLON: getSym()
        else: mark("; expected", 54)
    while SC.sym == TYPE:
        getSym()
        if SC.sym == IDENT:
            ident = SC.val
            getSym()
            if SC.sym == EQ: getSym()
            else: mark("= expected", 55)
            x = typ()
            newObj(ident, x)  #  x is of type ST.Type
            if SC.sym == SEMICOLON: getSym()
            else: mark("; expected", 56)
        else:
            mark("type name expected", 57)
    start = len(topScope())
    while SC.sym == VAR:
        getSym()
        typedIds(Var)
        if SC.sym == SEMICOLON: getSym()
        else: mark("; expected", 58)
    varsize = allocVar(topScope(), start)
    while SC.sym == PROCEDURE:
        getSym()
        if SC.sym == IDENT: getSym()
        else: mark("procedure name expected", 59)
        ident = SC.val
        newObj(ident, Proc([]))  #  entered without parameters
        sc = topScope()
        procStart()
        openScope()  # new scope for parameters and body
        if SC.sym == LPAREN:
            getSym()
            if SC.sym in {VAR, IDENT}:
                if SC.sym == VAR:
                    getSym()
                    typedIds(Ref)  #, procParams)
                else:
                    typedIds(Var)  #, procParams)
                while SC.sym == SEMICOLON:
                    getSym()
                    if SC.sym == VAR:
                        getSym()
                        typedIds(Ref)  #, procParams)
                    else:
                        typedIds(Var)  #, procParams)
            else:
                mark("formal parameters expected", 60)
            fp = topScope()
            sc[-1].par = fp[:]  #  procedure parameters updated
            if SC.sym == RPAREN: getSym()
            else: mark(") expected", 61)
        else: fp = []
        parsize = genFormalParams(fp)
        if SC.sym == SEMICOLON: getSym()
        else: mark("; expected", 62)
        # PROCEDURE CALL
        localsize = declarations(genLocalVars)
        genProcEntry(ident, parsize, localsize)
        x = compoundStatement()
        genProcExit(x, parsize, localsize)
        closeScope()  #  scope for parameters and body closed
        if SC.sym == SEMICOLON: getSym()
        else: mark("; expected", 63)
    return varsize