def _validate_rpn(self): counter = 0 for elem in self._res: if elem.isdigit() or elem.text in ['x', 'X']: counter += 1 elif elem.text in OPS and elem.text not in ['@', '#']: counter -= 2 if counter < 0: raise ValidateError("Чего-то тут не хватает", elem) counter += 1 elif elem.text in ['@', '#']: counter -= 1 if counter < 0: raise ValidateError("Чего-то тут не хватает", elem) counter += 1 if counter != 1: raise ValidateError("Уравнение не корректно!")
def _handle_eos(self) \ -> None: if self._moved_left: self._handle_parentheses(Token(')', 0)) while not self._stack.is_empty(): val = self._stack_to_res() if val.text == '(': raise ValidateError("Brackets not balanced", val)
def _handle_parentheses(self, val: Token) \ -> None: while not self._stack.is_empty(): if self._stack.is_bracket(): self._stack.pop() return self._stack_to_res() raise ValidateError("Brackets not balanced", val)
def _add_token(self, token: Token) -> None: if token.text in operations: token = Node(token, NODE_OP) elif token.text in unary_op: token = Node(token, NODE_UNARY) elif token.text in ['x', 'X']: token = Node(token, NODE_VAR) elif token.isdigit(): token = Node(token, NODE_NUM) else: raise ValidateError("Undefined token", token) self._stack.push(token)
def select_action(self, val: Token) \ -> None: if val.position >= self._position: self._position = val.position if val.text in OPS: self._handle_operator(val) elif val.text.isspace(): pass elif val.isdigit(): if self._previous_token == ')': self.select_action(Token('*', self._position)) self._res.append(val) self._possible_unary = False elif val.text in ['x', 'X']: if self.__previous_is_digit() or \ self._previous_token in ['x', 'X'] or \ self._previous_token == ')': self.select_action(Token('*', self._position)) self._res.append(val) self._possible_unary = False elif val.text == '(': self.__increase_stack(val) self._possible_unary = True elif val.text == ')': if self._previous_token in OPS: raise ValidateError( "Перед закрывающими скобками стоит " "знак операции", val) self._handle_parentheses(val) self._possible_unary = False elif val.text == '=': if self._moved_left: raise ValidateError("Not more than one quality sign allowed", val) self._handle_eos() self._move_to_left() self._possible_unary = True else: raise ValidateError(f"Unknown token '{val.text}'", val)
def create_tokens(equation: str) -> Generator: pattern = re.compile(r"(" r"(?:[-+()])" r"|(?:[\d.]+)" r"|(?:[*/])" r"|(?:[xX])" r"|(?:\^)" r"|(?:\s+)" r"|(?:=)" r")") position: int = 0 while position < len(equation): match_obj = pattern.match(equation, position) if match_obj is None: raise ValidateError("Символ не опознан. Уравнение не валидно.", Token("", position)) text = match_obj.group(1) yield Token(text, match_obj.start(1)) position = match_obj.end()
def pop(self) -> Node: if self.is_empty(): raise ValidateError("Стак дерева пустой") self._size -= 1 return self._stack.pop()