def var_parse(i: int, tokens, parent): v = ast.VarDecAST() v.set_parent(parent) if tokens[i].type == 'VAR': i += 1 if tokens[i].type == 'ID': obj = parent.get_children(tokens[i].value) if obj is not None: error = "Переменная с именем " + tokens[ i].value + " существует." print(error) return None, i, error else: parent.add_child(tokens[i].value, v) v.set_name(tokens[i].value) else: error = "Ошибка объявления переменной. Не указано имя." print(error) return None, i, error i += 1 if utils.is_type(tokens[i].type): v.set_type(tokens[i].type) else: error = "Ошибка объявления переменной. Некорректно указан тип." print(error) return None, i, error i += 1 if tokens[i].type == 'SEMI': return v, i, "" else: error = "Ошибка. Нет точки с запятой." print(error) return None, i, error
def func_parse(i, tokens, parent=None): func = ast.FunctionDefAST(parent) error = "" while tokens[i].type != 'END': if tokens[i].type == 'FUNC': i += 1 continue elif tokens[i].type == 'ID': obj = parent.get_children(tokens[i].value) if obj is not None: error = "Переменная с именем " + tokens[ i].value + " уже объявлена." print(error) return None, i, error parent.add_child(tokens[i].value, func) func.set_name(tokens[i].value) i += 1 elif tokens[i].type == 'LPAREN': i += 1 while tokens[i].type != 'RPAREN': if tokens[i].type == 'ID': a = parent.get_children(tokens[i].value) if a is not None: error = "Переменная с именем " + tokens[ i].value + " уже объявлена во внешней области видимости." print(error) return None, i, error a = ast.VarDecAST(func) a.set_name(tokens[i].value) func.add_arg(a) i += 1 if utils.is_type(tokens[i].type): a.set_type(tokens[i].type) else: error = "Не указан тип у переменной с именем " + tokens[ i].value + "." print(error) return None, i, error i += 1 i += 1 continue elif utils.is_type(tokens[i].type): func.set_type(tokens[i].type) i += 1 continue elif tokens[i].type == 'COLON': if func.type is None: error = "Не указан возвращаемый тип у функции с именем " + func.name + "." print(error) return None, i, error i += 1 while tokens[i].type != 'END': _, i, error = compound_expression_parse(i, tokens, func) i += 1 if error != "": print(error) return None, i, error return func, i, error
def proc_parse(i, tokens, parent=None): proc = ast.ProcedureDefAST(parent) error = "" while tokens[i].type != 'END': if tokens[i].type == 'PROC': i += 1 continue elif tokens[i].type == 'ID': obj = parent.get_children(tokens[i].value) if obj is not None: error = "Переменная с именем " + tokens[ i].value + " уже объявлена." print(error) return None, i, error parent.add_child(tokens[i].value, proc) proc.set_name(tokens[i].value) i += 1 elif tokens[i].type == 'LPAREN': i += 1 while tokens[i].type != 'RPAREN': if tokens[i].type == 'ID': a = parent.get_children(tokens[i].value) if a is not None: error = "Переменная с именем " + tokens[ i].value + " уже объявлена во внешней области видимости." print(error) return None, i, error a = ast.VarDecAST(proc) a.set_name(tokens[i].value) proc.add_arg(a) i += 1 if utils.is_type(tokens[i].type): a.set_type(tokens[i].type) else: error = "Не указан тип у переменной с именем " + tokens[ i].value + "." print(error) return None, i, error i += 1 i += 1 continue elif tokens[i].type == 'COLON': i += 1 while tokens[i].type != 'END': _, i, error = compound_expression_parse(i, tokens, proc) i += 1 if error != "": print(error) return None, i, error return proc, i, error
def var_parse(i: int, tokens_str, tokens_type, parent) -> Tuple[Union[ast.VarDecAST, None], int, str]: """ Функция парсинга объявления переменной. Переменная объявляется следующим образом: var имя_переменной тип_переменной; Пример: var x int; :param i: :param tokens_str: :param tokens_type: :param parent: :return: """ v = ast.VarDecAST() v.set_parent(parent) if tokens_type[i] == my_token.DEF_VAR: i += 1 if tokens_type[i] == my_token.IDENTIFIER: obj = parent.get_names(tokens_str[i]) if obj is not None: error = "Переменная с именем " + tokens_str[i] + " существует." print(error) return None, i, error else: parent.add_name(tokens_str[i], v) v.set_name(tokens_str[i]) else: error = "Ошибка объявления переменной. Не указано имя." print(error) return None, i, error i += 1 if ast.is_type(tokens_type[i]): v.set_type(tokens_type[i]) else: error = "Ошибка объявления переменной. Некорректно указан тип." print(error) return None, i, error i += 1 if tokens_type[i] == my_token.SEMI: # i += 1 return v, i, "" else: error = "Ошибка. Нет точки с запятой." print(error) return None, i, error
def func_def_parse(i: int, tokens_str: List[str], tokens_type, parent=None): dunc_obj = ast.FunctionDefAST(parent) error = "" while tokens_type[i] != my_token.RBRACE: if tokens_type[i] == my_token.DEF_FUNC: i += 1 continue elif tokens_type[i] == my_token.IDENTIFIER: obj = parent.get_names(tokens_str[i]) if obj is not None: error = "Переменная с именем " + tokens_str[ i] + " уже объявлена." print(error) return None, i, error parent.add_name(tokens_str[i], dunc_obj) dunc_obj.set_name(tokens_str[i]) i += 1 elif tokens_type[i] == my_token.LPAR: i += 1 while tokens_type[i] != my_token.RPAR: if tokens_type[i] == my_token.IDENTIFIER: a = parent.get_names(tokens_str[i]) if a is not None: error = "Переменная с именем " + tokens_str[ i] + " уже объявлена во внешней области видимости." print(error) return None, i, error a = ast.VarDecAST(dunc_obj) a.set_name(tokens_str[i]) dunc_obj.add_arg(a) i += 1 if ast.is_type(tokens_type[i]): a.set_type(tokens_type[i]) else: error = "Не указан тип у переменной с именем " + tokens_str[ i] + "." print(error) return None, i, error i += 1 i += 1 continue elif tokens_type[i] == my_token.ARROW: i += 1 if ast.is_type(tokens_type[i]): dunc_obj.set_type(tokens_type[i]) i += 1 continue else: error = "Не указан возвращаемый тип у функции с именем " + dunc_obj.name + "." print(error) return None, i, error elif tokens_type[i] == my_token.LBRACE: i += 1 # compound_expression = ast.CompoundExpression(dunc_obj) while tokens_type[i] != my_token.RBRACE: compound_expression, i, error = compound_expression_parse( i, tokens_str, tokens_type, dunc_obj) # if tokens_type[i] == my_token.RBRACE: # break i += 1 if error != "": print(error) return None, i, error # elif tokens_type[i] == my_token.RETURN: # i += 1 # obj, i, error = expr_parse(i, tokens_str, tokens_type, parent) # if obj is None: # print(error) # return None # if parent.__class__ == ast.FunctionDefAST: # parent.add_return_value(obj) # else: # error = "Недопустимая конструкция: return в " + parent.__class__.__name__ # print(error) # return None return dunc_obj, i, error