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()