Keta/ekg/Parse.py

147 lines
4.2 KiB
Python

# A Simple Parser For Ekg
import TokenLib
from TokenLib import Token
class Parser():
def __init__(self, source: str):
self.source = source
def parse(self, optional_source: str = "") -> [TokenLib.Token]:
# Assumes that the source is already balanced
# Variables used for determining if a block is being parsed/
# if an escape sequence is present
escaped = False
block_level = 0
temp_block = ""
token_list = []
string_mode = False
temp_string = ""
integer_mode = False
temp_integer = ""
if optional_source:
code = optional_source
else:
code = self.source
for char in code:
#print(char, temp_integer, [str(x) for x in token_list])
if integer_mode:
if char not in "0123456789" and char != ".":
integer_mode = False
if block_level:
temp_block += temp_integer
else:
token_list.append(Token(TokenLib.NUMBER,
eval(temp_integer)))
temp_integer = ""
elif char == ".":
if "." in temp_integer:
raise SyntaxError("Misplaced '.'")
temp_integer += "."
else:
temp_integer += char
continue
elif string_mode:
if escaped:
escaped = False
temp_string += char
else:
if char == '"':
string_mode = False
if block_level:
temp_block += '"' + temp_string + '"'
else:
token_list.append(Token(TokenLib.STRING,
temp_string))
temp_string = ""
elif char == "\\":
escaped = True
temp_string += char
else:
temp_string += char
continue
elif escaped:
self.token_list.append(Token(TokenLib.ESCAPE, char))
escaped = False
continue
elif char == "\\":
escaped = True
continue
elif char in "0123456789":
temp_integer += char
integer_mode = True
continue
elif char == '"':
string_mode = True
continue
if char == "[":
if block_level >= 1:
block_level += 1
temp_block += char
else:
block_level = 1
elif block_level:
if char == "]":
if block_level == 1:
token_list.append(Token(TokenLib.BLOCK,
self.parse(temp_block)))
block_level = 0
temp_block = ""
else:
temp_block += char
block_level -= 1
else:
temp_block += char
else:
if char == " ":
continue
token_list.append(Token(TokenLib.INSTRUCTION,
char))
if temp_block:
token_list.append(Token(TokenLib.BLOCK,
temp_block))
elif temp_integer:
token_list.append(Token(TokenLib.NUMBER,
eval(temp_integer)))
elif temp_string:
token_list.append(Token(TokenLib.STRING,
temp_string))
return token_list
if __name__ == "__main__":
source: str = "384+89"
parser: Parser = Parser(source)
tokens: [Token] = parser.parse()
for token in tokens:
print(token.get_data())