# of same precedence right_side = context.expression(self.lbp) return left + right_side class Substraction(Token): lbp = 10 # Same precedence as addition def led(self, left, context): return left - context.expression(self.lbp) def nud(self, context): """When a '-' is present on the left of an expression.""" # This means that we are returning the opposite of the next expression return - context.expression(self.lbp) class Multiplication(Token): lbp = 20 # Higher precedence than addition/substraction def led(self, left, context): return left * context.expression(self.lbp) lexer = Lexer(with_parens=True) lexer.register_token(Integer, re.compile(r'\d+')) lexer.register_token(Addition, re.compile(r'\+')) lexer.register_token(Substraction, re.compile(r'-')) lexer.register_token(Multiplication, re.compile(r'\*')) def parse(text): return lexer.parse(text)
# Fetch the expression to the right, stoping at the next boundary # of same precedence right_side = context.expression(self.lbp) return left + right_side class Substraction(Token): lbp = 10 # Same precedence as addition def led(self, left, context): return left - context.expression(self.lbp) def nud(self, context): """When a '-' is present on the left of an expression.""" # This means that we are returning the opposite of the next expression return - context.expression(self.lbp) class Multiplication(Token): lbp = 20 # Higher precedence than addition/substraction def led(self, left, context): return left * context.expression(self.lbp) lexer = Lexer(with_parens=True) lexer.register_token(Integer, re.compile(r'\d+')) lexer.register_token(Addition, re.compile(r'\+')) lexer.register_token(Substraction, re.compile(r'-')) lexer.register_token(Multiplication, re.compile(r'\*')) def parse(text): return lexer.parse(text)
class Power(Token): lbp = 30 # Higher than mult def led(self, left, context): # We pick expressions with a lower precedence, so that # 2 ** 3 ** 2 computes as 2 ** (3 ** 2) return left ** context.expression(self.lbp - 1) class Log(Token): lbp = 30 # Higher than mult def nud(self, context): return log(float(context.expression(self.lbp - 1))) lexer = Lexer(with_parens=True) lexer.register_token(Integer, re.compile(r'\d+')) lexer.register_token(Float, re.compile(r'\d+\.\d+')) lexer.register_token(Addition, re.compile(r'\+')) lexer.register_token(Substraction, re.compile(r'-')) lexer.register_token(Multiplication, re.compile(r'\*')) lexer.register_token(Division, re.compile(r'/')) lexer.register_token(Power, re.compile(r'\*\*')) lexer.register_token(Log, re.compile(r'log')) def parse(text): return lexer.parse(text)
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)))")}' )