Files
School/Anul 3/Semestrul 1/Formal Languages and Compiler Design/Scanner.py
T
2025-02-06 20:33:26 +02:00

85 lines
3.1 KiB
Python

from operator import le
from SymbolTable import SymbolTable
from Hashtable import HashTable
import re
class Scanner:
def __init__(self, tokensPath):
self.tokensPath = tokensPath
self.symbolTable = SymbolTable()
self.indentifierRegex = r"^[a-zA-Z][a-zA-Z0-9]*$"
self.constantRegex = r"^0$|^[1-9][0-9]*$|^-[1-9][0-9]*$"
self.tokens = []
self.pif = {}
self.readTokens()
def readTokens(self):
with open(self.tokensPath, "r") as file:
isKeyword = True
isOperator = False
for line in file:
self.tokens.append(line.strip())
self.tokensRegex = '|'.join(map(re.escape, self.tokens))
def isIdentifier(self, token):
return re.match(self.indentifierRegex, token)
def isConstant(self, token):
return re.match(self.constantRegex, token)
def isToken(self, token):
return token in self.tokens
def scan(self, codePath):
with open(codePath, "r") as file:
identifierCounter = 1
constantCounter = 1
lineCounter = 0
try:
for line in file:
line = line.strip()
tokens = re.findall(self.tokensRegex + r"|\w+", line)
for token in tokens:
if self.isToken(token):
self.pif[token] = -1
elif self.isIdentifier(token):
position = self.symbolTable.getPositionIdentifier(token)
if position is None:
self.symbolTable.addIdentifier(token, identifierCounter)
self.pif["Identifier"] = identifierCounter
identifierCounter += 1
else:
self.pif["Identifier"] = position[1]
elif self.isConstant(token):
position = self.symbolTable.getPositionConstants(token)
if position is None:
self.symbolTable.addConstants(token, constantCounter)
self.pif['Constant'] = constantCounter
constantCounter += 1
else:
self.pif["Constant"] = position[1]
else:
raise Exception(f"Invalid token {token} at line {lineCounter}")
lineCounter += 1
print("Lexically correct")
except Exception as e:
print(e)
return
def main():
scanner = Scanner("tokens.in")
scanner.scan("p1error.in")
#save output to file
with open("PIF.out", "w") as file:
for key in scanner.pif:
file.write(f"{key} -> {scanner.pif[key]}\n")
with open("ST.out", "w") as file:
file.write(str(scanner.symbolTable))
if __name__ == "__main__":
main()