def _parse_rest_of_relation_condition(self): self._next_token() right = self._parse_expression() if right: raise ParserError( self.current_token.value, self.current_token.end, "Unable to parse second operand of relation condition.")
def _next_token(self, token_type=None): if not token_type or token_type == self.current_token.type: self.current_token = self.lexer.get_token() return True raise ParserError(self.current_token, self.current_token.start, f'Expected:{token_type}, got:{self.current_token}')
def _parse_assign_or_function_call(self): if self.current_token.type != TokenType.VALUE_ID: return None name = self.current_token.value self._next_token(TokenType.VALUE_ID) object_name = [] while self.current_token.type == TokenType.DOT: self._next_token(TokenType.DOT) object_name.append(self.current_token.value) self._next_token(TokenType.VALUE_ID) instruction = self._parse_rest_of_function_call(name, object_name) if instruction: return instruction instruction = self._parse_rest_of_assign(name, object_name) if instruction: return instruction self._next_token(TokenType.SEMICOLON) raise ParserError( self.current_token.value, self.current_token.end, "Unexpected data instead of function call or assignment statement." )
def parse(self): if not self._next_token(TokenType.LEFT_BRACKET): return None while self._parse_function_definition( ) or self._parse_class_definition(): pass if not self._next_token(TokenType.RIGHT_BRACKET): raise ParserError(self.current_token.value, self.current_token.end, "Program not ended with \'}\'.") if self.current_token.type != TokenType.EOT: raise ParserError(self.current_token.value, self.current_token.end, "Unexpected data after program definition.") return nodes.Program(self.functions_dict, self.classes_dict)
def _parse_while(self): if self.current_token.type != TokenType.K_WHILE: return None self._next_token(TokenType.K_WHILE) self._next_token(TokenType.LEFT_PARENT) condition = self._parse_condition() if condition is None: raise ParserError(self.current_token.value, self.current_token.end, "Couldn't find a valid while condition.") self._next_token(TokenType.RIGHT_PARENT) instructions = self._parse_block() if instructions is None: raise ParserError(self.current_token.value, self.current_token.end, "Couldn't parse while statement block.") return nodes.WhileStat(condition, instructions)
def _parse_parenth_expression(self): if self.current_token.type != TokenType.LEFT_PARENT: return None self._next_token(TokenType.LEFT_PARENT) condition = self._parse_condition() self._next_token(TokenType.RIGHT_PARENT) if condition: return condition raise ParserError(self.current_token.value, self.current_token.end, "Couldn't parse parentheses.")
def _parse_class_definition(self): if self.current_token.type != TokenType.K_CLASS: return None self._next_token(TokenType.K_CLASS) name = self.current_token.value self._next_token(TokenType.VALUE_ID) if self.classes_dict and (name in self.classes_dict.keys()): raise ParserError(self.current_token.value, self.current_token.start, " - Class redefinition.") self._next_token(TokenType.LEFT_BRACKET) return self._parse_rest_of_class_definition(name)
def _parse_rest_of_function_definition(self, member_type, name): self._next_token(TokenType.LEFT_PARENT) params = self._parse_parameters_definitions() self._next_token(TokenType.RIGHT_PARENT) instructions = self._parse_block() if not instructions: raise ParserError(self.current_token.value, self.current_token.start, " Function is empty.") function = nodes.FunctionDef(member_type, name, params, instructions) return function
def _parse_condition(self): left = self._parse_and_condition() if not left: return None while self.current_token.type == TokenType.VERTICAL_LINE: operator = self.current_token.type self._next_token(operator) right = self._parse_and_condition() if not right: raise ParserError( self.current_token.value, self.current_token.end, "Couldn't find right operand of or operation.") left = nodes.OrOperation(left, right) return left
def _parse_parameters_definitions(self): params = [] param = self._parse_parameter_definition() if param: params.append(param) while self.current_token.type == TokenType.COMMA: self._next_token(TokenType.COMMA) param = self._parse_parameter_definition() if param: params.append(param) else: raise ParserError( self.current_token.value, self.current_token.start, "Couldn't find next parameter " "definition.") return params
def _parse_and_condition(self): left = self._parse_equality_condition() if not left: return None while self.current_token.type == TokenType.AMPERSAND: operator = self.current_token.type self._next_token(operator) right = self._parse_equality_condition() if not right: raise ParserError( self.current_token.value, self.current_token.end, "Couldn't find right operand of and operation.") left = nodes.AndOperation(left, right) return left
def _parse_function_definition(self): func_type = self._parse_function_type() if not func_type: return None name = self.current_token.value self._next_token(TokenType.VALUE_ID) if self.functions_dict and name in self.functions_dict.keys(): raise ParserError(self.current_token.value, self.current_token.start, " - Function redefinition.") function = self._parse_rest_of_function_definition(func_type, name) self.functions_dict[name] = function return function
def _parse_relation_condition(self): expression = self._parse_boolean_value() if expression: return expression is_negated = False if self.current_token.type == TokenType.EXCLAMATION: is_negated = True self._next_token(TokenType.EXCLAMATION) left = self._parse_expression() if not left: if is_negated: raise ParserError( self.current_token.value, self.current_token.end, "Exclamation mark left without any " "negable expression.") return None if self.is_a_relation_operation(TokenType.LESS_EQUAL): right = self._parse_rest_of_relation_condition() left = nodes.LessEqualOperation(left, right) elif self.is_a_relation_operation(TokenType.GREATER_EQUAL): self._next_token() right = self._parse_expression() left = nodes.GreaterEqualOperation(left, right) elif self.is_a_relation_operation(TokenType.LESS): self._next_token() right = self._parse_expression() left = nodes.LessOperation(left, right) elif self.is_a_relation_operation(TokenType.GREATER): self._next_token() right = self._parse_expression() left = nodes.GreaterOperation(left, right) if is_negated: left = nodes.NotOperation(left) return left
def _parse_equality_condition(self): left = self._parse_relation_condition() if not left: return None if self.current_token.type in [TokenType.EQUAL, TokenType.NOT_EQUAL]: operator = self.current_token.type self._next_token(operator) right = self._parse_relation_condition() if not right: raise ParserError( self.current_token.value, self.current_token.end, "Couldn't find right operand of equality operation.") if operator == TokenType.EQUAL: left = nodes.EqualOperation(left, right) else: left = nodes.NotEqualOperation(left, right) return left
def _parse_multiply_expression(self): left = self._parse_primary_expression() if not left: return None while self.current_token.type in [ TokenType.MUL_OR_REFER, TokenType.DIV ]: operator = self.current_token.type self._next_token(operator) right = self._parse_primary_expression() if not right: raise ParserError( self.current_token.value, self.current_token.end, "Couldn't find right operand of mul operation.") if operator == TokenType.MUL_OR_REFER: left = nodes.MulOperation(left, right) else: left = nodes.DivOperation(left, right) return left
def _parse_expression(self): left = self._parse_multiply_expression() if not left: return None while self.current_token.type in [ TokenType.PLUS_OR_CONC, TokenType.MINUS ]: operator = self.current_token.type self._next_token(operator) right = self._parse_multiply_expression() if not right: raise ParserError( self.current_token.value, self.current_token.end, "Couldn't find right operand of add operation.") if operator == TokenType.PLUS_OR_CONC: left = nodes.AddOperation(left, right) else: left = nodes.SubOperation(left, right) return left