Create the Basic Compiler

Create a file named basic_compiler.py and add the following code:

pythonCopy codeclass Lexer:
    def __init__(self, text):
        self.text = text
        self.position = 0
        self.current_char = self.text[self.position]

    def error(self):
        raise Exception("Invalid character")

    def advance(self):
        """Advance the 'position' pointer and set the 'current_char'."""
        self.position += 1
        if self.position > len(self.text) - 1:
            self.current_char = None  # Indicates the end of the input
        else:
            self.current_char = self.text[self.position]

    def skip_whitespace(self):
        """Skip whitespace characters."""
        while self.current_char is not None and self.current_char.isspace():
            self.advance()

    def variable(self):
        """Return a variable identifier."""
        result = ''
        while self.current_char is not None and self.current_char.isalnum():
            result += self.current_char
            self.advance()
        return result

    def number(self):
        """Return a multi-digit integer."""
        result = ''
        while self.current_char is not None and self.current_char.isdigit():
            result += self.current_char
            self.advance()
        return int(result)

    def get_next_token(self):
        """Tokenize the input string."""
        while self.current_char is not None:
            if self.current_char.isspace():
                self.skip_whitespace()
                continue

            if self.current_char.isalpha():
                return ('VARIABLE', self.variable())

            if self.current_char.isdigit():
                return ('NUMBER', self.number())

            if self.current_char == '+':
                self.advance()
                return ('PLUS', '+')

            if self.current_char == '-':
                self.advance()
                return ('MINUS', '-')

            if self.current_char == '=':
                self.advance()
                return ('EQUALS', '=')

            self.error()

        return ('EOF', None)


class Interpreter:
    def __init__(self, lexer):
        self.lexer = lexer
        self.current_token = self.lexer.get_next_token()
        self.variables = {}

    def error(self):
        raise Exception("Invalid syntax")

    def eat(self, token_type):
        """Consume the current token if it matches the expected type."""
        if self.current_token[0] == token_type:
            self.current_token = self.lexer.get_next_token()
        else:
            self.error()

    def factor(self):
        """Parse a factor."""
        token = self.current_token
        if token[0] == 'NUMBER':
            self.eat('NUMBER')
            return token[1]
        elif token[0] == 'VARIABLE':
            var_name = token[1]
            self.eat('VARIABLE')
            return self.variables.get(var_name, 0)

    def term(self):
        """Parse a term (factor)."""
        result = self.factor()
        return result

    def expression(self):
        """Parse an expression."""
        result = self.term()

        while self.current_token[0] in ('PLUS', 'MINUS'):
            token = self.current_token
            if token[0] == 'PLUS':
                self.eat('PLUS')
                result += self.term()
            elif token[0] == 'MINUS':
                self.eat('MINUS')
                result -= self.term()

        return result

    def assignment(self):
        """Parse an assignment statement."""
        var_name = self.current_token[1]
        self.eat('VARIABLE')
        self.eat('EQUALS')
        value = self.expression()
        self.variables[var_name] = value
        return value


def main():
    while True:
        try:
            text = input("Enter a statement (or 'exit' to quit): ")
            if text.lower() == 'exit':
                break
            lexer = Lexer(text)
            interpreter = Interpreter(lexer)
            result = interpreter.assignment()
            print(f"Result: {result}")
        except Exception as e:
            print(f"Error: {e}")


if __name__ == "__main__":
    main()

Step 2: Running the Basic Compiler

  1. Open your terminal (or command prompt).
  2. Navigate to the directory where you saved basic_compiler.py.
  3. Run the script using the command:bashCopy codepython basic_compiler.py

How It Works

  • Lexer: The Lexer class tokenizes the input string into meaningful components like numbers, variables, and operators.
  • Interpreter: The Interpreter class parses the tokens and evaluates expressions and assignments. It maintains a dictionary to store variable values.
  • Input Handling: The user can enter statements to assign values to variables or evaluate expressions.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *