def c_desc(self):
     name = self.pop_from_semantic_stack()
     var_type = self.get_top_semantic_stack()
     if not self.symbol_table.is_var_declared(name):
         self.symbol_table.new_variable(name, var_type)
     else:
         error_handler(
             "Syntax Error",
             "variable with name " + name + " has already declared ")
 def c_desc_normal_array(self):
     name = self.pop_from_semantic_stack()
     var_type = self.get_top_semantic_stack()
     if not self.symbol_table.is_var_declared(name):
         self.symbol_table.new_array(name, var_type,
                                     self.get_next_token_value())
     else:
         error_handler(
             "Syntax Error",
             "variable with name " + name + " has already declared ")
 def for_simple_declaration(self):
     value = self.get_address_or_immediate_value(
         self.get_next_token_value())
     var_name = self.pop_from_semantic_stack()
     var_type = self.pop_from_semantic_stack()
     if not self.symbol_table.is_var_declared(var_name):
         self.symbol_table.new_variable(var_name, var_type, 1)
         code = ["mov", self.symbol_table.get_var_address(var_name), value]
         self.add_code(code)
     else:
         error_handler(
             "Syntax Error",
             "variable with name " + var_name + " has already declared ")
 def c_desc_with_assign(self):
     name = self.pop_from_semantic_stack()
     var_type = self.get_top_semantic_stack()
     if not self.symbol_table.is_var_declared(name):
         self.symbol_table.new_variable(name, var_type)
         operand2 = self.get_address_or_immediate_value(
             self.get_next_token_value())
         code = ["mov", self.symbol_table.get_var_address(name), operand2]
         self.add_code(code)
     else:
         error_handler(
             "Syntax Error",
             "variable with name " + name + " has already declared ")
Пример #5
0
	def _fill_parse_table(self):
		for variable in self._variables:
			self._parse_table[variable] = {}
			for terminal in self._terminals:
				self._parse_table[variable][terminal] = Parser._INVALID
		for rule_id in range(len(self._rules)):
			variable = self._rules[rule_id][0]
			for terminal in self._terminals:
				if terminal in self._predicts[rule_id]:
					if self._parse_table[variable][terminal] != Parser._INVALID:
						error_handler("Grammer Error",
									  "The grammar is not LL1. Variable: " + str(variable) + " Terminal: " + str(
										  terminal))
					else:
						self._parse_table[variable][terminal] = rule_id
Пример #6
0
 def get_var(self, var_name):
     best_var_scope = -1
     best_symbol_address = -1
     var = {}
     for symbol in self.symbols:
         if symbol.var_name == var_name and symbol.function == self.function and symbol.scope > best_var_scope:
             best_symbol_address = symbol.address
             best_var_scope = symbol.scope
             var = symbol
     if best_symbol_address == -1:
         for symbol in self.symbols:
             if symbol.var_name == var_name and symbol.function == "Global":
                 var = symbol
                 best_symbol_address = symbol.address
     if best_symbol_address == -1:
         error_handler("Syntax Error", str(var_name) + " is not declared")
     return var
    def check_all_function_have_signature(self):
        for item in self.function_signatures:
            for signature in item['signatures']:
                if signature['start_point'] == self._WILL_BE_SET_LATER:
                    error_handler(
                        "Syntax Error", " function " + item['function_name'] +
                        " has not declared")
        if not self.finalCode.have_main():
            error_handler("Syntax Error",
                          "There is not int main that have no input variable")

        for item in self.function_call_jmp_that_do_not_have_pc:
            item = list(item)
            self.finalCode.update_code(
                item[0], 1,
                str(self.function_signatures[item[1]]["signatures"][item[2]]
                    ['start_point']))
 def function_called(self, signature):
     idx = len(signature["var_names"]) - 1
     while idx >= 0:
         var_name = signature["var_names"][idx]
         var_type = signature["var_types"][idx]
         if not self.symbol_table.is_var_declared(var_name):
             self.symbol_table.new_variable(var_name, var_type)
         else:
             error_handler(
                 "Syntax Error", "variable with name " + var_name +
                 " has already declared ")
         code = ["pop", self.get_address_or_immediate_value(var_name)]
         self.add_code(code)
         idx -= 1
     dest_temp = self.symbol_table.new_temp("int")
     code = ["pop", self.get_address_or_immediate_value(dest_temp)]
     self.add_code(code)
     self.function_return_address = dest_temp
 def array(self):
     index = self.get_address_or_immediate_value(
         self.pop_from_semantic_stack())
     array_name = self.pop_from_semantic_stack()
     array = self.symbol_table.get_var(array_name)
     if array.type_of_data != "array":
         error_handler("Syntax Error", array_name + " is not array")
     array_start = array.address
     array_type_size = array.type_size
     temp1_address = self.get_address_or_immediate_value(
         self.get_temp("int"))
     temp2 = self.get_temp("int")
     temp2_address = self.get_address_or_immediate_value(temp2)
     code1 = ["mult", temp1_address, array_type_size, index]
     code2 = ["add", temp2_address, array_start, temp1_address]
     self.add_code(code1)
     self.add_code(code2)
     self.push_to_semantic_stack("@" + str(temp2))
Пример #10
0
	def _update_grammar(self, rule_text):
		idx = len(self._rules)
		rule_text_tokens = rule_text.split()
		self._update_variables(rule_text_tokens)
		self._update_terminals(rule_text_tokens)
		if len(rule_text_tokens) < 3:
			error_handler("Grammer Error", "Error in rule number " + str(idx))
		if not self.is_variable(rule_text_tokens[0]) or rule_text_tokens[1] != Parser._ARROW_STRING:
			error_handler("Grammer Error", "Error in rule number " + str(idx))
		if len(rule_text_tokens) == 3 and rule_text_tokens[2] == Parser._NIL_STRING and rule_text_tokens[
			0] not in self._nullable_variables:
			self._nullable_variables.append(rule_text_tokens[0])
		key = rule_text_tokens[0]
		del rule_text_tokens[1]
		self._rules.append(copy.deepcopy(rule_text_tokens))
		del rule_text_tokens[0]
		temp_list = []
		if key in self._variable_rules:
			temp_list = self._variable_rules[key]
		temp_list.append(rule_text_tokens)
		self._variable_rules[key] = temp_list
 def check_type(self, operand0, operand2, operand3):
     if self.symbol_table.get_var_type(
             operand2) == "double" and self.symbol_table.get_var_type(
                 operand3) == "double":
         return "double"
     if self.symbol_table.get_var_type(
             operand2) == "int" and self.symbol_table.get_var_type(
                 operand3) == "int":
         return "int"
     if self.symbol_table.get_var_type(
             operand2) == "bool" and self.symbol_table.get_var_type(
                 operand3) == "bool":
         return "bool"
     if self.symbol_table.get_var_type(
             operand2) == "bool" and self.symbol_table.get_var_type(
                 operand3) == "char":
         error_handler("Syntax Error", "Types does not match")
     if self.symbol_table.get_var_type(
             operand2) == self.symbol_table.get_var_type(operand3):
         return self.symbol_table.get_var_type(operand2)
     error_handler("Syntax Error", "Types does not match")
 def c_desc_weird_array(self):
     datas = []
     while self.get_top_semantic_stack() != ']':
         datas.append(self.pop_from_semantic_stack())
     self.pop_from_semantic_stack()
     name = self.pop_from_semantic_stack()
     var_type = self.pop_from_semantic_stack()
     if not self.symbol_table.is_var_declared(name):
         self.symbol_table.new_array(name, var_type, len(datas))
     else:
         error_handler(
             "Syntax Error",
             "variable with name " + name + " has already declared ")
     var = self.symbol_table.get_var(name)
     type_size = var.type_size
     address = var.address
     for data in reversed(datas):
         self.add_code([
             "mov",
             str(address),
             self.get_address_or_immediate_value(data)
         ])
         address += int(type_size)
 def signature_function_declaration(self):
     pushed = []
     while self.get_top_semantic_stack() != self._START_OF_FUNCTION:
         pushed.append(self.pop_from_semantic_stack())
     self.pop_from_semantic_stack()
     if len(pushed) == 2 and pushed[1] == "void" and pushed[0] == "main":
         self.update_code(0, 1, self.get_pc())
     function_return_type = pushed.pop()
     function_name = pushed.pop()
     self.symbol_table.set_function_name(function_name)
     function_variables_names = []
     function_variables_types = []
     while len(pushed) != 0:
         function_variables_types.append(pushed.pop())
         function_variables_names.append(pushed.pop())
     state = 0
     function_declaration = {}
     for item in self.function_signatures:
         if item['function_name'] != function_name:
             continue
         if item['function_name'] == "main":
             error_handler("Syntax Error",
                           "There is at least 2 main in your code")
         if item['function_return_type'] != function_return_type:
             error_handler(
                 "Syntax Error", " function " + function_name +
                 "has declared with different return type ")
         state = 1
         function_declaration = item
         for signature in item['signatures']:
             is_same = True
             if len(signature['var_types']) != len(
                     function_variables_types):
                 continue
             for i in range(0, len(function_variables_types)):
                 if signature['var_types'][i] != function_variables_types[i]:
                     is_same = False
                     break
             if is_same:
                 error_handler(
                     "Syntax Error", " function " + function_name +
                     " has declared with same signature")
         break
     obj = {
         "var_types": function_variables_types,
         "var_names": function_variables_names,
         "start_point": self._WILL_BE_SET_LATER
     }
     if state == 0:
         function_declaration['function_return_type'] = function_return_type
         function_declaration['function_name'] = function_name
         function_declaration['signatures'] = [obj]
         self.function_signatures.append(function_declaration)
     elif state == 1:
         function_declaration['signatures'].append(obj)
Пример #14
0
	def parse(self, tokens):
		tokens.append(Token('eof', 'keyword'))
		tokens.append(self._END_OF_FILE_CHARACTER)
		last_idx = -1
		idx = 0
		self._parse_stack.append(self._END_OF_FILE_CHARACTER)
		self._parse_stack.append(self._start_variable)
		top = self._start_variable
		loop_counter = 0
		open_parentheses_count = 0
		while top != self._END_OF_FILE_CHARACTER:
			loop_counter += 1
			last_token = tokens[-2]

			if top == self._BOOLEAN_EXPRESSION_STRING and open_parentheses_count == 1 and tokens[idx - 1].value == '(':
				self._parse_stack.pop()
				top = self._get_parse_stack_top()
				boolean_expression_tokens = []
				while open_parentheses_count != 0:
					boolean_expression_tokens.append(tokens[idx])
					if tokens[idx].value == "(":
						open_parentheses_count += 1
					if tokens[idx].value == ")":
						open_parentheses_count -= 1
					idx += 1
				idx -= 1
				open_parentheses_count += 1
				boolean_expression_tokens.pop()
				try:
					self._boolean_expression_parser.parse(boolean_expression_tokens)
				except:
					error_handler("Syntax Error:", " error in boolean expression")
				continue

			elif top == self._BOOLEAN_EXPRESSION_STRING and tokens[idx - 1].value == ';':
				self._parse_stack.pop()
				top = self._get_parse_stack_top()
				boolean_expression_tokens = []
				while tokens[idx].value != ";":
					boolean_expression_tokens.append(tokens[idx])
					if tokens[idx].value == "(":
						open_parentheses_count += 1
					if tokens[idx].value == ")":
						open_parentheses_count -= 1
					idx += 1
				try:
					self._boolean_expression_parser.parse(boolean_expression_tokens)
				except:
					error_handler("Syntax Error:", " error in boolean expression")
				continue

			top = self._get_parse_stack_top()
			if top == self._NIL_STRING:
				top = self._get_parse_stack_top()
				continue
			if self.is_semantic_rule(top):					
				semantic = top
				self._parse_stack.pop()
				top = self._get_parse_stack_top()
				self._code_generator.generate_code(semantic, tokens[idx])
				continue
			if loop_counter > len(tokens) * 20:
				error_handler("Syntax Error:", " (1) next token should not be " + str(tokens[idx]))
			if top == self._IDENTIFIER_STRING:
				if tokens[idx].type == TokenType.identifier:
					idx = idx + 1
					self._parse_stack.pop()
					top = self._get_parse_stack_top()
					continue
				else:
					error_handler("Syntax Error:", " (2) next token should not be " + str(tokens[idx]))
			elif top == self._NUMBER_STRING:
				if tokens[idx].type == TokenType.number:
					idx = idx + 1
					self._parse_stack.pop()
					top = self._get_parse_stack_top()
					continue
				else:
					error_handler("Syntax Error:", " (3) next token should not be " + str(tokens[idx]))
			elif self.is_terminal(top):
				if tokens[idx].value == "(":
					open_parentheses_count += 1
				if tokens[idx].value == ")":
					open_parentheses_count -= 1
				if top == "{":
					self._symbol_table.one_scope_in()
				if top == "}":
					self._symbol_table.one_scope_out()
				if tokens[idx].value == top:
					idx = idx + 1
					self._parse_stack.pop()
					top = self._get_parse_stack_top()
					continue
				else:
					error_handler("Syntax Error:", " (4) next token should not be " + str(tokens[idx]))
			try:
				try:
					nxt = tokens[idx].value
					if tokens[idx].type == TokenType.identifier:
						nxt = self._IDENTIFIER_STRING
					if tokens[idx].type == TokenType.number:
						nxt = self._NUMBER_STRING
					rule_idx = self._parse_table[top][nxt]
					product = self._rules[rule_idx][1:]
					self._parse_stack.pop()
					if product != [self._NIL_STRING]:
						self._parse_stack.extend(reversed(product))
				except:
					error_handler("Syntax Error:", " (5)")
			except KeyError:
				error_handler("Syntax Error:", "6: Unable to find derivation of '{0}' on '{1}'".format(top, nxt))
			top = self._get_parse_stack_top()
		return True
 def finish_function_call(self):
     pushed = []
     while self.get_top_semantic_stack() != self._START_OF_FUNCTION_CALL:
         pushed.append(self.pop_from_semantic_stack())
     self.pop_from_semantic_stack()
     function_name = pushed.pop()
     pushed = list(reversed(pushed))
     func_id = 0
     sign_id = 0
     start_point_of_jump = -1
     found = False
     for function_dec in self.function_signatures:
         if function_dec["function_name"] != function_name:
             func_id += 1
             continue
         sign_id = 0
         for signature in function_dec["signatures"]:
             is_same = True
             if len(signature['var_types']) != len(pushed):
                 sign_id += 1
                 continue
             for i in range(0, len(pushed)):
                 if signature['var_types'][i] != self.get_type(pushed[i]):
                     is_same = False
                     break
                 i += 1
             if is_same:
                 found = True
                 start_point_of_jump = signature["start_point"]
                 break
             sign_id += 1
         if found:
             break
         else:
             error_handler("Syntax error",
                           "no function with this name and signature")
     if not found:
         error_handler("Syntax error", "function is not declared")
     return_value_size = self.symbol_table.get_size(
         self.function_signatures[func_id]['function_return_type'])
     var_size = self.symbol_table.get_all_var_size()
     variables = var_size[1]
     pop_code = []
     for var in variables:
         address = var[0]
         now_address = address
         while now_address < (address + var[1]):
             code = ["push",
                     now_address]  # , "-", str(now_address + var[2])
             pop_code.append(["pop", now_address
                              ])  # , "-", str(now_address + var[2])
             self.add_code(code)
             now_address += var[2]
     code = ["push", "#" + str(self.get_pc() + 2 + len(pushed))]
     self.add_code(code)
     for push in pushed:
         code = ["push", self.get_address_or_immediate_value(push)]
         self.add_code(code)
     code = ["jmp", start_point_of_jump]
     if start_point_of_jump == self._WILL_BE_SET_LATER:
         self.function_call_jmp_that_do_not_have_pc.append(
             [int(self.get_pc()), func_id, sign_id])
     self.add_code(code)
     if return_value_size > 0:
         temp = self.symbol_table.new_temp(
             self.function_signatures[func_id]['function_return_type'])
         code = ["pop", self.get_address_or_immediate_value(temp)]
         self.add_code(code)
         self.push_to_semantic_stack(temp)
     pop_code = reversed(pop_code)
     for pop in pop_code:
         self.add_code(pop)
Пример #16
0
def _error_handler(e):
    return error_handler(e)