def p_IfMark3(p): ''' IfMark3 : ''' l3 = ST.make_label() TAC.emit('goto', l3, '', '') TAC.emit('label', p[-3][1], '', '') ST.create_new_table(p[-3][1]) p[0] = [l3]
def p_MethodDeclaration(p): ''' MethodDeclaration : MethodHeader MethodDeclMark2 MethodBody ''' TAC.emit('ret','','','') ST.end_scope() rules_store.append(p.slice)
def p_WhMark3(p): '''WhMark3 : ''' TAC.emit('goto',p[-6][0],'','') TAC.emit('label',p[-6][2],'','') ST.end_scope() stackbegin.pop() stackend.pop()
def p_doWhMark2(p): '''doWhMark2 : ''' #TAC.emit('goto',p[-3][1],'','') TAC.emit('label',p[-3][1],'','') ST.end_scope() stackbegin.pop() stackend.pop()
def p_FoMark5(p): '''FoMark5 : ''' TAC.emit('goto',p[-6][0],'','') TAC.emit('label',p[-6][2],'','') ST.end_scope() stackbegin.pop() stackend.pop()
def p_ShiftExpression(p): ''' ShiftExpression : AdditiveExpression | ShiftExpression L_SHIFT AdditiveExpression | ShiftExpression R_SHIFT AdditiveExpression ''' 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)
def p_BreakStatement(p): ''' BreakStatement : BREAK Identifier STMT_TERMINATOR | BREAK STMT_TERMINATOR ''' if(len(p)==3 and p[1]=='break'): TAC.emit('goto', stackend[-1], '', '') rules_store.append(p.slice)
def p_ContinueStatement(p): ''' ContinueStatement : CONTINUE Identifier STMT_TERMINATOR | CONTINUE STMT_TERMINATOR ''' if(len(p)==3 and p[1]=='continue'): TAC.emit('goto', stackbegin[-1], '', '') rules_store.append(p.slice)
def p_SwMark2(p): ''' SwMark2 : ''' l1 = ST.make_label() l2 = ST.make_label() stackend.append(l1) TAC.emit('goto', l2, '', '') ST.create_new_table(l2) p[0] = [l1, l2]
def p_FoMark1(p): '''FoMark1 : ''' l1 = ST.make_label() l2 = ST.make_label() l3 = ST.make_label() stackbegin.append(l1) stackend.append(l3) TAC.emit('label',l1,'','') p[0]=[l1,l2,l3]
def p_doWhMark1(p): '''doWhMark1 : ''' l1 = ST.make_label() l2 = ST.make_label() l3 = ST.make_label() stackbegin.append(l1) stackend.append(l3) ST.create_new_table(l1) TAC.emit('label',l1,'','') p[0]=[l1,l2,l3]
def p_PreDecrementExpression(p): ''' PreDecrementExpression : DECREMENT UnaryExpression ''' if(p[2]['type']=='INT'): TAC.emit(p[2]['place'],p[2]['place'],'1','-') p[0] = { 'place' : p[2]['place'], 'type' : 'INT' } else: raise Exception("Error: decrement operator can be used with integers only") rules_store.append(p.slice)
def p_PostDecrementExpression(p): ''' PostDecrementExpression : PostfixExpression DECREMENT ''' if p[1]['type'] == 'INT': TAC.emit(p[1]['place'], p[1]['place'], '1', '-') p[0] = { 'place' : p[1]['place'], 'type' : 'INT' } else: raise Exception("Error: decrement operator can be used with integers only") rules_store.append(p.slice)
def p_ArrayAccess(p): ''' ArrayAccess : Name DimExprs ''' p[0] = {} attributes = ST.lookup(p[1]['place']) if attributes == None: raise Exception("Undeclared Symbol Used: %s" %(p[1]['place'])) if not 'is_array' in attributes or not attributes['is_array']: raise Exception("Only array type can be indexed : %s" %(p[1]['place'])) indexes = p[2] if not len(indexes) == len(attributes['arr_size']): raise Exception("Not a valid indexing for array %s" %(p[1]['place'])) arr_size = attributes['arr_size'] address_indices = p[2] t2 = ST.get_temp_var() TAC.emit(t2, address_indices[0], '', '=') for i in range(1, len(address_indices)): TAC.emit(t2, t2, arr_size[i], '*') TAC.emit(t2, t2, address_indices[i], '+') index = t2 src = p[1]['place'] + '[' + str(index) + ']' t1 = ST.get_temp_var() TAC.emit(t1, src, '', '=') p[0]['type'] = attributes['type'] p[0]['place'] = t1 p[0]['access_type'] = 'array' p[0]['name'] = p[1]['place'] p[0]['index'] = str(index) rules_store.append(p.slice)
def p_ConditionalOrExpression(p): ''' ConditionalOrExpression : ConditionalAndExpression | ConditionalOrExpression LOGICAL_OR ConditionalAndExpression ''' 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' : l1 = ST.make_label() TAC.emit(newPlace,p[1]['place'],'','=') TAC.emit('ifgoto',p[1]['place'],'eq 1',l1) TAC.emit(newPlace, p[1]['place'], p[3]['place'], '|') TAC.emit('label',l1,'','') p[0]['type'] = 'INT' else: raise Exception('Error: Type is not compatible' + p[1]['place'] + ',' + p[3]['place'] + '.') rules_store.append(p.slice)
def p_UnaryExpressionNotPlusMinus(p): ''' UnaryExpressionNotPlusMinus : PostfixExpression | BITWISE_NOT UnaryExpression | LOGICAL_NOT UnaryExpression | CastExpression ''' if len(p) == 2: p[0] = p[1] else: t = ST.get_temp_var() TAC.emit(t, p[2]['place'], '', p[1]) p[0] = p[2] p[0]['place'] = t rules_store.append(p.slice)
def p_SwMark3(p): ''' SwMark3 : ''' TAC.emit('label', p[-2][1], '', '') for i in range(len(p[-1]['labels'])): label = p[-1]['labels'][i] exp = p[-1]['expressions'][i] if exp == '': TAC.emit('goto', label, '', '') else: TAC.emit('ifgoto', p[-4]['place'], 'eq ' + exp, label) TAC.emit('label', p[-2][0], '', '') ST.end_scope()
def p_MethodDeclarator(p): ''' MethodDeclarator : Identifier L_PAREN MethodDeclMark1 R_PAREN | Identifier L_PAREN MethodDeclMark1 FormalParameterList R_PAREN ''' p[0] = { 'name' : p[1], } if len(p) == 6: p[0]['args'] = p[4] else: p[0]['args'] = [] stackbegin.append(p[1]) stackend.append(p[1]) if len(p) == 6: for parameter in p[4]: ST.insert_in_sym_table(parameter['place'],parameter['type']) TAC.emit('func', p[1], '', '') rules_store.append(p.slice)
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)
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)
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)
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]
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)
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)
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)
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],'','')
def p_IfMark4(p): ''' IfMark4 : ''' ST.end_scope() TAC.emit('label', p[-2][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],'','')
def p_SwMark1(p): ''' SwMark1 : ''' l = ST.make_label() TAC.emit('label', l, '', '') p[0] = l
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],'','')