Beispiel #1
0
def p_Assignment(p):
    '''
    Assignment : LeftHandSide AssignmentOperator AssignmentExpression
    '''
    if 'access_type' not in p[1].keys():
        attributes = ST.lookup(p[1]['place'])
        if attributes == None:
            raise Exception("Undeclared variable used: %s" %(p[1]['place']))
        if 'is_array' in attributes and attributes['is_array']:
            raise Exception("Array '%s' not indexed properly" %(p[1]['place']))
        if attributes['type'] == p[3]['type']:
            TAC.emit(p[1]['place'], p[3]['place'], '', p[2])
        else:
            raise Exception("Type Mismatch for symbol: %s" %(p[3]['place']))
    else:
        dest = p[1]['name'] + '[' + p[1]['index'] + ']'
        TAC.emit(dest, p[3]['place'], '', '=')


    rules_store.append(p.slice)
Beispiel #2
0
def p_ReturnStatement(p):
    '''
    ReturnStatement : RETURN Expression STMT_TERMINATOR
    | RETURN STMT_TERMINATOR
    '''
    if(len(p)==3 and p[1]=='return'):
        TAC.emit('ret', '', '', '')
    else:
        # to_return = ST.lookup(ST.curr_scope, is_func=True)['ret_type']
        to_return = global_return_type
        curr_returned = ST.lookup(p[2]['place'])
        if curr_returned != None:
            if to_return[0] != curr_returned['type']:
                raise Exception("Wrong return type in %s" %(ST.curr_scope))
            if 'is_array' in curr_returned.keys() and len(curr_returned['arr_size']) != to_return[1]:
                raise Exception("Dimension mismatch in return statement in %s" %(ST.curr_scope))
        elif curr_returned == None:
            if p[2]['type'] != to_return[0] or to_return[1] != 0:
                raise Exception("Wrong return type in %s" %(ST.curr_scope))
        TAC.emit('ret', p[2]['place'], '', '')
    rules_store.append(p.slice)
Beispiel #3
0
def p_InclusiveOrExpression(p):
    '''
    InclusiveOrExpression : ExclusiveOrExpression
    | InclusiveOrExpression BITWISE_OR ExclusiveOrExpression
    '''
    if(len(p)==2):
        p[0] = p[1]
        return
    newPlace = ST.get_temp_var()
    p[0] = {
        'place' : newPlace,
        'type' : 'TYPE_ERROR'
    }
    if p[1]['type']=='TYPE_ERROR' or p[3]['type']=='TYPE_ERROR':
        return
    if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
        TAC.emit(newPlace, p[1]['place'], p[3]['place'], '|')
        p[0]['type'] = 'INT'
    else:
        raise Exception('Error: Type is not compatible' + p[1]['place'] + ',' + p[3]['place'] + '.')
    rules_store.append(p.slice)
Beispiel #4
0
def p_AdditiveExpression(p):
    '''
    AdditiveExpression : MultiplicativeExpression
    | AdditiveExpression PLUS MultiplicativeExpression
    | AdditiveExpression MINUS MultiplicativeExpression
    '''
    if len(p) == 2:
        p[0] = p[1]
        return
    newPlace = ST.get_temp_var()
    p[0] = {
        'place' : newPlace,
        'type' : 'TYPE_ERROR'
    }
    if p[1]['type'] == 'TYPE_ERROR' or p[3]['type'] == 'TYPE_ERROR':
        return

    if p[1]['type'] == 'INT' and p[3]['type'] == 'INT':
        TAC.emit(newPlace, p[1]['place'], p[3]['place'], p[2])
        p[0]['type'] = 'INT'
    else:
        raise Exception("Error: integer value is needed")
    rules_store.append(p.slice)
Beispiel #5
0
def p_IfMark1(p):
    ''' IfMark1 : '''
    l1 = ST.make_label()
    l2 = ST.make_label()
    TAC.emit('ifgoto', p[-2]['place'], 'eq 0', l2)
    TAC.emit('goto', l1, '', '')
    TAC.emit('label', l1, '', '')
    ST.create_new_table(l1)
    p[0] = [l1, l2]
Beispiel #6
0
def p_VariableDeclarator(p):
    '''
    VariableDeclarator : VariableDeclaratorId
    | VariableDeclaratorId ASSIGN VariableInitializer
    '''
    p[0] = {}
    if len(p) == 2:
        p[0]['place'] = p[1]
        return
    elif type(p[3]) != type({}):
        return

    if 'is_array' in p[3].keys() and p[3]['is_array']:
        t = ST.get_temp_var()
        TAC.emit(t, '1', '', '=')
        for i in p[3]['place']:
            TAC.emit(t, t, i, '*')
        TAC.emit('declare', p[1], t, p[3]['type'])
        p[0]['place'] = (p[1], p[3]['place'])
        p[0]['type'] = p[3]['type']
    elif 'ret_type' in p[3].keys():
        p[0]['place'] = p[1]
        p[0]['type'] = p[3]['ret_type']
    else:
        TAC.emit(p[1][0], p[3]['place'], '', p[2])
        p[0]['place'] = p[1]
        if 'is_var' not in p[3]:
            attributes = ST.lookup(p[3]['place'])
            if 'is_array' in attributes and attributes['is_array']:
                p[0]['is_array'] = True
                p[0]['arr_size'] = attributes['arr_size']
            else:
                p[0]['is_array'] = False

        p[0]['type'] = p[3]['type']
    rules_store.append(p.slice)
Beispiel #7
0
def p_MethodInvocation(p):
    '''
    MethodInvocation : Name L_PAREN ArgumentList R_PAREN
    | Name L_PAREN R_PAREN
    | Primary DOT Identifier L_PAREN ArgumentList R_PAREN
    | Primary DOT Identifier L_PAREN R_PAREN
    | SUPER DOT Identifier L_PAREN ArgumentList R_PAREN
    | SUPER DOT Identifier L_PAREN R_PAREN
    '''
    # Check return type of function in symbol table
    if p[2] == '(':
        attributes = ST.lookup(p[1]['place'], is_func=True)
        if attributes == None and p[1]['place'] != "System.out.println":
            raise Exception("Undeclared function used: %s" %(p[1]['place']))

        if p[1]['place'] == 'System.out.println':
            if len(p) == 5:
                for parameter in p[3]:
                    TAC.emit('print',parameter['place'],'','')
        else:
            temp_var = ST.get_temp_var()
            if len(p) == 5:
                prototype = attributes['params']
                if len(prototype) != len(p[3]):
                    raise Exception("Wrong number of arguments to function call: %s" %(p[1]['place']))
                for i in range(len(p[3])):
                    parameter = p[3][i]
                    proto = prototype[i]
                    if parameter['type'] != proto['type']:
                        raise Exception("Wrong type of arg passed to function %s; got %s but expected %s" %(p[1]['place'], parameter['type'], proto['type']))
                    TAC.emit('param',parameter['place'],'','')
            TAC.emit('call',p[1]['place'],temp_var,'')
            p[0] = {
                'place' : temp_var,
                'ret_type' : attributes['ret_type']
            }
    rules_store.append(p.slice)
Beispiel #8
0
def p_MultiplicativeExpression(p):
    '''
    MultiplicativeExpression : UnaryExpression
    | MultiplicativeExpression MULT UnaryExpression
    | MultiplicativeExpression DIVIDE UnaryExpression
    | MultiplicativeExpression MODULO UnaryExpression
    '''
    if(len(p)==2):
        p[0] = p[1]
        return
    newPlace = ST.get_temp_var()
    p[0] = {
        'place' : newPlace,
        'type' : 'TYPE_ERROR'
    }
    if p[1]['type'] == 'TYPE_ERROR' or p[3]['type'] == 'TYPE_ERROR':
        return
    if p[2] == '*':
        if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
            TAC.emit(newPlace,p[1]['place'], p[3]['place'], p[2])
            p[0]['type'] = 'INT'
        else:
            raise Exception('Error: Type is not compatible'+p[1]['place']+','+p[3]['place']+'.')
    elif p[2] == '/' :
        if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
            TAC.emit(newPlace, p[1]['place'], p[3]['place'], p[2])
            p[0]['type'] = 'INT'
        else:
            raise Exception('Error: Type is not compatible' + p[1]['place'] + ',' + p[3]['place'] + '.')
    elif p[2] == '%':
        if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
            TAC.emit(newPlace,p[1]['place'],p[3]['place'],p[2])
            p[0]['type'] = 'INT'
        else:
            raise Exception('Error: Type is not compatible' + p[1]['place'] + ',' + p[3]['place'] + '.')
    rules_store.append(p.slice)
Beispiel #9
0
def p_WhMark2(p):
    '''WhMark2 : '''
    TAC.emit('ifgoto',p[-2]['place'],'eq 0', p[-4][2])
    TAC.emit('goto',p[-4][1],'','')
    TAC.emit('label',p[-4][1],'','')
Beispiel #10
0
def p_SwMark1(p):
    ''' SwMark1 : '''
    l = ST.make_label()
    TAC.emit('label', l, '', '')
    p[0] = l
Beispiel #11
0
def p_IfMark4(p):
    ''' IfMark4 : '''
    ST.end_scope()
    TAC.emit('label', p[-2][0], '', '')
Beispiel #12
0
def p_IfMark2(p):
    ''' IfMark2 : '''
    ST.end_scope()
    TAC.emit('label', p[-2][1], '', '')
Beispiel #13
0
def p_EqualityExpression(p):
    '''
    EqualityExpression : RelationalExpression
    | EqualityExpression EQUALS RelationalExpression
    | EqualityExpression NOT_EQUAL RelationalExpression
    '''
    if(len(p)==2):
        p[0] = p[1]
        return
    l1 = ST.make_label()
    l2 = ST.make_label()
    l3 = ST.make_label()
    newPlace = ST.get_temp_var()
    p[0]={
        'place' : newPlace,
        'type' : 'TYPE_ERROR'
    }
    if p[1]['type']=='TYPE_ERROR' or p[3]['type']=='TYPE_ERROR':
        return
    if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
        if(p[2][0]=='='):
            TAC.emit('ifgoto', p[1]['place'], 'eq ' + p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
        else:
            TAC.emit('ifgoto', p[1]['place'], 'neq '+ p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
    else:
        raise Exception('Only INT type comparisions supported: ' + p[1]['place'] + ' and' + p[3]['place'])
    rules_store.append(p.slice)
Beispiel #14
0
def p_RelationalExpression(p):
    '''
    RelationalExpression : ShiftExpression
    | RelationalExpression LST ShiftExpression
    | RelationalExpression GRT ShiftExpression
    | RelationalExpression LEQ ShiftExpression
    | RelationalExpression GEQ ShiftExpression
    | RelationalExpression INSTANCEOF ReferenceType
    '''
    if len(p) == 2:
        p[0] = p[1]
        return
    l1 = ST.make_label()
    l2 = ST.make_label()
    l3 = ST.make_label()
    newPlace = ST.get_temp_var()
    p[0] = {
        'place' : newPlace,
        'type' : 'TYPE_ERROR'
    }
    if p[1]['type']=='TYPE_ERROR' or p[3]['type']=='TYPE_ERROR':
        return

    if p[1]['type'] == 'INT' and p[3]['type'] == 'INT' :
        if p[2]=='>':
            TAC.emit('ifgoto', p[1]['place'], 'gt ' + p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
        elif p[2]=='>=':
            TAC.emit('ifgoto', p[1]['place'], 'geq ' + p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
        elif p[2]=='<':
            TAC.emit('ifgoto', p[1]['place'], 'lt ' + p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
        elif p[2]=='<=':
            TAC.emit('ifgoto', p[1]['place'], 'leq ' + p[3]['place'], l2)
            TAC.emit('label', l1, '', '')
            TAC.emit(newPlace, '0', '', '=')
            TAC.emit('goto', l3, '', '')
            TAC.emit('label', l2, '', '')
            TAC.emit(newPlace, '1', '', '=')
            TAC.emit('label', l3, '', '')
            p[0]['type'] = 'INT'
    else:
        raise Exception('Error: Type is not compatible' + p[1]['place'] + ',' + p[3]['place'] + '.')
    rules_store.append(p.slice)
Beispiel #15
0
def p_doWhMark3(p):
    '''doWhMark3 : '''
    TAC.emit('ifgoto',p[-2]['place'],'eq 0', p[-7][2])
    TAC.emit('goto',p[-7][1],'','')
    TAC.emit('label',p[-7][2],'','')
Beispiel #16
0
def p_FoMark4(p):
    '''FoMark4 : '''
    TAC.emit('ifgoto',p[-3]['place'],'eq 0', p[-4][2])
    TAC.emit('goto',p[-4][1],'','')
    TAC.emit('label',p[-4][1],'','')
Beispiel #17
0
#!/usr/bin/env python
import sys
import ply.lex as lex
import ply.yacc as yacc
import lexer
from three_address_code import TAC
from new_sym_table import ScopeTable

TAC = TAC()
ST = ScopeTable()

stackbegin = []
stackend = []

rules_store = []

global_return_type = None

# Section 19.2
def p_Goal(p):
    '''Goal : CompilationUnit'''
    rules_store.append(p.slice)

# Section 19.3
def p_Identfier(p):
    '''Identifier : IDENTIFIER'''
    p[0] = p[1]

def p_Literal(p):
    ''' Literal : IntegerConst
    | FloatConst