Explorar el Código

added files with errors

Olesya Ivanova hace 3 años
padre
commit
39a038e04c
Se han modificado 4 ficheros con 101 adiciones y 0 borrados
  1. 1 0
      interpreter/__init__.py
  2. 67 0
      interpreter/interpreter.py
  3. 27 0
      interpreter/tokens.py
  4. 6 0
      main.py

+ 1 - 0
interpreter/__init__.py

@@ -0,0 +1 @@
+from .interpreter import Interpreter

+ 67 - 0
interpreter/interpreter.py

@@ -0,0 +1,67 @@
+from .tokens import TokenType, Token
+
+
+class InterpreterException(Exception):
+    pass
+
+
+class Interpreter():
+    def __init__(self):
+        self._pos: int = -1
+        self._current_token: Token = None
+        self._current_char: str = None
+        self._text: str = ""
+
+    def _next_token(self) -> Token:
+        while self._current_char is not None:
+            self._current_char: str = self._text[self._pos]
+            if self._current_char.isdigit():
+                self._forward()
+                return Token(TokenType.INTEGER, self._current_char)
+            if self._current_char == "+":
+                self._forward()
+                return Token(TokenType.PLUS, self._current_char)
+            if self._current_char == "-":
+                self._forward()
+                return Token(TokenType.MINUS, self._current_char)
+            raise InterpreterException(f"bad token {self._current_char}")
+        return Token(TokenType.EOS, None)
+
+    def _forward(self):
+        self._pos += 1
+        if self._pos >= len(self._text):
+            self._current_char = None
+        else:
+            self._current_char = self._text[self._pos]
+
+    def _check_token_type(self, type_: TokenType):
+        if self._current_token.type_ == type_:
+            self._current_token = self._next_token()
+        else:
+            raise InterpreterException("invalid token order")
+
+    def _expr(self) -> int:
+        self._current_token = self._next_token()  # берём первый токен
+        left = self._current_token
+        self._check_token_type(TokenType.INTEGER)
+        op = self._current_token
+        if op.type_ == TokenType.PLUS:
+            self._check_token_type(TokenType.PLUS)
+        else:
+            self._check_token_type(TokenType.MINUS)
+        right = self._current_token
+        self._check_token_type(TokenType.INTEGER)
+        if op.type_ == TokenType.PLUS:
+            return int(left.value) + int(right.value)
+        elif op.type_ == TokenType.MINUS:
+            return int(left.value) - int(right.value)
+        raise InterpreterException("bad operator")
+
+    def __call__(self, text: str):
+        return self.interpret(text)
+
+    def interpret(self, text: str):
+        self._text = text
+        self._pos = -1
+        self._forward()
+        return self._expr()

+ 27 - 0
interpreter/tokens.py

@@ -0,0 +1,27 @@
+from enum import Enum, auto
+
+
+class TokenType(Enum):
+    INTEGER = auto()
+    PLUS = auto()
+    MINUS = auto()
+    EOS = auto()  # конец строки
+
+
+class Token():
+    def __init__(self, type_: TokenType, value: str):
+        self.type_ = type_
+        self.value = value
+
+    def __str__(self):
+        return f"Token({self.type_}, {self.value})"  # явное приведение
+
+    def __repr__(self):
+        return str(self)
+
+
+if __name__ == "__main__":
+    print(list(TokenType))
+
+    t = Token(TokenType.INTEGER, "2")
+    print([t])

+ 6 - 0
main.py

@@ -0,0 +1,6 @@
+from interpreter import Interpreter
+
+if __name__ == "__main__":
+    interpreter = Interpreter()
+    print(interpreter("2+2"))
+    print(interpreter.interpret("3+ "))