parser.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from .tokens import TokenType, Token
  2. from .lexer import Lexer
  3. from .node import Node, BinOp, Number
  4. class ParserException(Exception):
  5. pass
  6. class Parser():
  7. def __init__(self):
  8. self._current_token: Token = None
  9. self._lexer = Lexer()
  10. def __call__(self, text: str) -> Node:
  11. return self.parse(text)
  12. def _check_token_type(self, type_: TokenType):
  13. if self._current_token.type_ == type_:
  14. self._current_token = self._lexer.next()
  15. else:
  16. raise ParserException("invalid token order")
  17. def _factor(self) -> Node:
  18. token = self._current_token
  19. if token.type_ == TokenType.FLOAT:
  20. self._check_token_type(TokenType.FLOAT)
  21. return Number(token)
  22. if token.type_ == TokenType.LPAREN:
  23. self._check_token_type(TokenType.LPAREN)
  24. result = self._expr()
  25. self._check_token_type(TokenType.RPAREN)
  26. return result
  27. raise ParserException("invalid factor")
  28. def _term(self) -> Node:
  29. result = self._factor()
  30. ops = [TokenType.MUL, TokenType.DIV]
  31. if self._current_token.type_ in ops:
  32. token = self._current_token
  33. if token.type_ == TokenType.MUL:
  34. self._check_token_type(TokenType.MUL)
  35. elif token.type_ == TokenType.DIV:
  36. self._check_token_type(TokenType.DIV)
  37. else:
  38. self._check_token_type(TokenType.POW)
  39. return BinOp(result,token,self._factor())
  40. return result
  41. def _expr(self) -> Node:
  42. ops = [TokenType.PLUS, TokenType.MINUS]
  43. result = self._term()
  44. if self._current_token.type_ in ops:
  45. token = self._current_token
  46. if token.type_ == TokenType.PLUS:
  47. self._check_token_type(TokenType.PLUS)
  48. else:
  49. self._check_token_type(TokenType.MINUS)
  50. return BinOp(result,token,self._term())
  51. return result
  52. def parse(self, text: str) -> Node:
  53. self._lexer.init(text)
  54. self._current_token = self._lexer.next()
  55. return self._expr()