# Eat the next token, that should be a ')' context.consume(expect_class=RightParen) return expr class RightParen(Token): regexp = r'\)' class Comma(Token): regexp = r',' lexer = Lexer() lexer.register_tokens( Symbol, Number, String, Addition, Substraction, Multiplication, Division, LeftParen, RightParen, Comma) _variable_format = re.compile('^' + variable_format + '$') def parse_expression(expression): equal = expression.find('=') if equal == -1: raise InvalidOperation("Missing target variable name", "new_var = %s" % expression, (0, 7)) else: target = expression[:equal].strip() if not _variable_format.match(target):
class ExistType(Token): regexp = r':' lbp = 10 def led(self, left, context): right = context.expression(self.lbp) if not isinstance(left, Key): raise ParserError("Typed existence condition does not involve a " "key") elif not isinstance(right, Key) or right.text not in ('int', 'str'): raise ParserError("Existence condition missing type") return left.text, {'type': right.text} lexer.register_tokens(Key, Number, String, Operator, ExistType) def _update_conditions(conditions, expr): key, cond = expr prec = conditions.get(key) if prec is not None: if prec['type'] != cond['type']: raise ParserError("Differing types for conditions on key %s: " "%s, %s" % (key, prec['type'], cond['type'])) for k in cond.keys(): if k != 'type' and k in prec: raise ParserError("Multiple conditions %s on key %s" % (k, key)) prec.update(cond) else:
class ExistType(Token): regexp = r':' lbp = 10 def led(self, left, context): right = context.expression(self.lbp) if not isinstance(left, Key): raise ParserError("Typed existence condition does not involve a " "key") elif not isinstance(right, Key) or right.text not in ('int', 'str'): raise ParserError("Existence condition missing type") return left.text, {'type': right.text} lexer.register_tokens(Key, Number, String, Operator, ExistType) def _update_conditions(conditions, expr): key, cond = expr prec = conditions.get(key) if prec is not None: if prec['type'] != cond['type']: raise ParserError("Differing types for conditions on key %s: " "%s, %s" % (key, prec['type'], cond['type'])) for k in cond.keys(): if k != 'type' and k in prec: raise ParserError("Multiple conditions %s on key %s" % ( k, key)) prec.update(cond) else:
expr = context.expression() # Eat the next token, that should be a ')' context.consume(expect_class=RightParen) return expr class RightParen(Token): regexp = r'\)' class Comma(Token): regexp = r',' lexer = Lexer() lexer.register_tokens(Symbol, Number, String, Addition, Substraction, Multiplication, Division, LeftParen, RightParen, Comma) _variable_format = re.compile('^' + variable_format + '$') def parse_expression(expression): equal = expression.find('=') if equal == -1: raise InvalidOperation("Missing target variable name", "new_var = %s" % expression, (0, 7)) else: target = expression[:equal].strip() if not _variable_format.match(target): right = equal if right > 0 and expression[right - 1] == ' ': right -= 1
class LeftParen(Token): match = RightParen def nud(self, context): expr = context.expression() context.consume(expect_class=self.match) return expr def __repr__(self): return '<(>' # регистрация токенов lexer = Lexer() lexer.register_tokens(Integer, Addition, Multiplication, Division) lexer.register_token(LeftParen, re.compile(r'\(')) lexer.register_token(RightParen, re.compile(r'\)')) def parse(text): """Преобразует лексические токены в представление""" return lexer.parse(text) print("(((10+1)*(5+6/(3+1))+4*(3+1)))") print( f'Результат вычеслений после разбора: {parse("(((10+1)*(5+6/(3+1))+4*(3+1)))")}' )