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
- Open your terminal (or command prompt).
- Navigate to the directory where you saved
basic_compiler.py
. - Run the script using the command:bashCopy code
python 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.
Leave a Reply