def p_ExprSwitchStmt(p): '''ExprSwitchStmt : SWITCH SimpleStmt SEMICOLON LCURLY ExprCaseClauseList RCURLY | SWITCH SimpleStmt SEMICOLON Expression LCURLY ExprCaseClauseList RCURLY | SWITCH LCURLY ExprCaseClauseList RCURLY | SWITCH Expression LCURLY ExprCaseClauseList RCURLY ''' global current_scope if len(p) == 6: l1 = labelGen() l2 = labelGen() p[0] = TreeNode('ExprSwitchStmt', 0, 'INT') p[0].TAC.append_TAC(p[2].TAC) t1 = tempGen() node = symboltable_node() node.name = t1 node.scope = current_scope node.value = p[2].data node.type = insertType(p[2].data) SymbolTable.add_node(node) p[0].TAC.add_line(['=', t1, p[2].data, '']) p[0].TAC.append_TAC(p[4].data) for i in range(len(p[4].children)): p[0].TAC.add_line( ['ifgotoeq', t1, p[4].children[i][0], p[4].children[i][1]]) for i in range(p[4].TAC.length()): if i in p[4].TAC.leaders[1:]: p[0].TAC.add_line(['goto', l2, '', '']) p[0].TAC.add_line(p[4].TAC.code[i]) p[0].TAC.add_line([l2]) return
def p_Expression(p): '''Expression : UnaryExpr | Expression OR_OR Expression | Expression AMP_AMP Expression | Expression EQ_EQ Expression | Expression NOT_EQ Expression | Expression LT Expression | Expression LT_EQ Expression | Expression GT Expression | Expression GT_EQ Expression | Expression PLUS Expression | Expression MINUS Expression | Expression OR Expression | Expression CARET Expression | Expression STAR Expression | Expression DIVIDE Expression | Expression MODULO Expression | Expression LS Expression | Expression RS Expression | Expression AMP Expression | Expression AND_OR Expression ''' global current_scope if len(p) == 2: p[0] = p[1] elif len(p) == 4: expression = p[1].data + p[2] + p[3].data expr_node = SymbolTable.search_expr(expression) if not expr_node: temp = tempGen() node = symboltable_node() node.name = temp node.value = p[1].data + p[2] + p[3].data node.expr = p[1].data + p[2] + p[3].data node.type = p[1].input_type node.scope = current_scope SymbolTable.add_node(node) #print(f"Evaluating expression {node.value}") node.value = evalExpr(p[1], p[2], p[3]) #SymbolTable.print_symbol_table() #print(node.value, node.name) p[0] = TreeNode('IDENTIFIER', temp, 'INT', 1, [], p[1].TAC) node.exprnode = p[0] p[0].TAC.append_TAC(p[3].TAC) p[0].TAC.add_line([p[2], p[0].data, p[1].data, p[3].data]) else: p[0] = expr_node.exprnode p[0].name = 'Expression' return
def p_ShortVarDecl(p): '''ShortVarDecl : ExpressionList ASSIGN_OP ExpressionList | Expression ASSIGN_OP Expression ''' global current_scope p[0] = TreeNode('ShortVarDecl', 0, 'INT') if p[1].name == 'ExpressionList': l1 = len(p[1].children) l2 = len(p[3].children) p[0].TAC.append_TAC(p[3].TAC) p[0].TAC.append_TAC(p[1].TAC) if l1 == l2: for i in range(l1): if p[1].children[i].isLvalue == 0: print("*** Error: Cannot assign to constant ***", p.lineno(1)) else: if SymbolTable.search_node(p[1].children[i].data) == []: node = symboltable_node() node.name = p[1].children[i].data node.type = insertType(p[3].children[i].data) node.scope = current_scope node.value = p[3].children[i].data SymbolTable.add_node(node) p[0].TAC.add_line([ p[2], p[1].children[i].data, p[3].children[i].data, '' ]) else: print("*** Error: Assignment mismatch:", l1, "identifier(s) but", l2, "value(s)! ***") print(p.lineno(1)) elif p[1].name == 'Expression': if p[1].isLvalue == 0: print("*** Error: Cannot declare and assign to constant ***") return else: p[0].TAC.append_TAC(p[3].TAC) p[0].TAC.append_TAC(p[1].TAC) p[0].TAC.add_line([p[2], p[1].data, p[3].data, '']) if SymbolTable.search_node(p[1].data) == []: node = symboltable_node() node.name = p[1].data node.type = insertType(p[3].data) node.scope = current_scope node.value = p[3].data SymbolTable.add_node(node) return
def p_UnaryExpr(p): '''UnaryExpr : PrimaryExpr | unary_op UnaryExpr ''' global current_scope if len(p) == 2: p[0] = p[1] elif len(p) == 3: temp = tempGen() node = symboltable_node() node.name = temp node.value = p[2].data node.scope = current_scope SymbolTable.add_node(node) p[0] = TreeNode('IDENTIFIER', temp, 'INT', 1) p[0].TAC.add_line([p[1].data, p[0].data, p[2].data]) p[0].name = 'UnaryExpr' return
def p_VarSpec(p): '''VarSpec : IDENTIFIER Type | IDENTIFIER EQ Expression | IDENTIFIER Type EQ Expression | IdentifierList Type | IdentifierList EQ ExpressionList | IdentifierList Type EQ ExpressionList ''' # Insert into symbol table p[0] = TreeNode('VarSpec', 0, 'NONE') if hasattr(p[1], 'name') and p[1].name == 'IdentifierList': zero_val = TreeNode('decimal_lit', 0, 'INT') else: p[1] = TreeNode('IDENTIFIER', p[1], 'INT', 1) if p[2].input_type != 'NONE': node = symboltable_node() node.name = p[1].data node.value = None node.scope = current_scope node.type = p[1].input_type SymbolTable.add_node(node) p[0] = TreeNode('VarSpec', p[1].data, 'INT') return
def p_Assignment(p): '''Assignment : ExpressionList assign_op ExpressionList | Expression assign_op Expression ''' global current_scope p[0] = TreeNode('Assignment', 0, 'INT') if p[1].name == 'ExpressionList': l1 = len(p[1].children) l2 = len(p[3].children) p[0].TAC.append_TAC(p[3].TAC) p[0].TAC.append_TAC(p[1].TAC) if l1 == l2: for i in range(l1): if p[1].children[i].isLvalue == 0: print("*** Error: Cannot assign to constant ***") else: #print("Looking for: ", p[1].children[i].data) if SymbolTable.search_node(p[1].children[i].data) == []: node = symboltable_node() node.name = p[1].children[i].data node.type = insertType(p[3].children[i].data) node.scope = current_scope node.value = p[3].children[i].data SymbolTable.add_node(node) if SymbolTable.search_node( p[3].children[i].data ) == [] and p[3].children[i].isLvalue == 1: #print("Looking for: ", p[3].children[i].data) node = symboltable_node() node.name = p[3].children[i].data node.type = insertType(p[3].children[i].data) node.scope = current_scope node.value = p[3].children[i].data SymbolTable.add_node(node) p[0].TAC.add_line([ p[2].data, p[1].children[i].data, p[3].children[i].data, '' ]) else: print("*** Error: Assignment mismatch:", l1, "identifier(s) but", l2, "value(s)! ***") elif p[1].name == 'Expression': # p[0] = TreeNode('Assignment', 0, 'INT', 0, p[1].children + p[3].children, p[1].TAC.append_TAC(p[3].TAC)) if p[1].isLvalue == 0: print("*** Error: Cannot assign to constant ***") return else: p[0].TAC.append_TAC(p[3].TAC) p[0].TAC.append_TAC(p[1].TAC) p[0].TAC.add_line([p[2].data, p[1].data, p[3].data, '']) # and p[1].children[i].isLvalue ==1: if SymbolTable.search_node(p[1].data) == []: print("*** Error: Variable not declared: ", p[1].data) if SymbolTable.search_node(p[3].data) == [] and p[3].isLvalue == 1: node = symboltable_node() node.name = p[3].data node.type = insertType(p[3].data) node.scope = current_scope node.value = p[3].data SymbolTable.add_node(node) return