boom
This commit is contained in:
commit
1ac693fdc2
9 changed files with 670 additions and 0 deletions
86
lexer.py
Normal file
86
lexer.py
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
from tokens import TokenType, Token
|
||||
|
||||
|
||||
DIGITS = '0123456789'
|
||||
|
||||
class Lexer:
|
||||
|
||||
def __init__(self, text):
|
||||
self.text = iter(text)
|
||||
self.advance()
|
||||
|
||||
def advance(self):
|
||||
try:
|
||||
self.current_char = next(self.text)
|
||||
except StopIteration:
|
||||
self.current_char = None
|
||||
|
||||
def generate_tokens(self):
|
||||
while self.current_char != None:
|
||||
if self.current_char == '.' or self.current_char in DIGITS:
|
||||
yield self.generate_number()
|
||||
elif self.current_char == '+':
|
||||
self.advance()
|
||||
yield Token(TokenType.PLUS)
|
||||
elif self.current_char == '-':
|
||||
self.advance()
|
||||
yield Token(TokenType.MINUS)
|
||||
elif self.current_char == '~':
|
||||
self.advance()
|
||||
yield Token(TokenType.NEGATE)
|
||||
elif self.current_char == '*':
|
||||
self.advance()
|
||||
yield Token(TokenType.MULTIPLY)
|
||||
elif self.current_char == '/':
|
||||
self.advance()
|
||||
yield Token(TokenType.DIVIDE)
|
||||
elif self.current_char == '^':
|
||||
self.advance()
|
||||
yield Token(TokenType.POWER)
|
||||
elif self.current_char == '%':
|
||||
self.advance()
|
||||
yield Token(TokenType.MODULE)
|
||||
elif self.current_char == '!':
|
||||
self.advance()
|
||||
yield Token(TokenType.FACTORIAL)
|
||||
elif self.current_char == '@':
|
||||
self.advance()
|
||||
yield Token(TokenType.AVERAGE)
|
||||
elif self.current_char == '&':
|
||||
self.advance()
|
||||
yield Token(TokenType.MINIMUM)
|
||||
elif self.current_char == '$':
|
||||
self.advance()
|
||||
yield Token(TokenType.MAXIMUM)
|
||||
elif self.current_char == '[':
|
||||
self.advance()
|
||||
yield Token(TokenType.LBRACKET)
|
||||
elif self.current_char == ']':
|
||||
self.advance()
|
||||
yield Token(TokenType.RBRACKET)
|
||||
else:
|
||||
raise Exception(f"Illegal character '{self.current_char}'")
|
||||
|
||||
|
||||
def generate_number(self):
|
||||
decimal_point_count = 0
|
||||
number_str = self.current_char
|
||||
self.advance()
|
||||
|
||||
while self.current_char != None and (self.current_char == '.' or self.current_char in DIGITS):
|
||||
|
||||
if self.current_char == '.':
|
||||
decimal_point_count += 1
|
||||
if decimal_point_count > 1:
|
||||
break
|
||||
|
||||
number_str += self.current_char
|
||||
self.advance()
|
||||
|
||||
if number_str.startswith('.'):
|
||||
number_str = '0' + number_str
|
||||
if number_str.endswith('.'):
|
||||
number_str += '0'
|
||||
|
||||
# Create the token
|
||||
return Token(TokenType.NUMBER, float(number_str))
|
||||
Loading…
Add table
Add a link
Reference in a new issue