CompilerDesign/GrammarAnalysis.py

103 lines
2.6 KiB
Python

import re
class GrammarAnalysis:
keyword = {
r'begin': 1,
r'end': 2
}
symbol = {
r'+': 13,
r'-': 14,
r'*': 15,
r'/': 16,
r';': 17,
r'=': 18,
r'<': 19,
r'<>': 20,
r'<=': 21,
r'>': 22,
r'>=': 23,
r'(': 24,
r')': 25,
r'#': 0
}
regex = {
r'^[a-zA-Z][a-zA-Z0-9]*$': 10,
r'^\d+$': 11
}
def readfile(self, filename: str) -> str:
s = ''
with open(filename, 'r', encoding='utf-8') as f:
for x in f.readlines():
s = s.strip()
if len(x) != 0:
s = x
break
return s
def strsplit(self, s: str) -> list[str]:
lt = []
l = 0
r = 1
while r < len(s):
if not (s[r].isalpha() or s[r].isdigit()):
k = s[l:r].strip()
if len(k) != 0:
lt.append(k)
k = s[r].strip()
if len(k) != 0:
lt.append(k)
l = r + 1
r = l
else:
r += 1
if l < len(s):
lt.append(s[l:r])
return lt
def analyze(self, lt: list[str]) -> list[(int, str)]:
ans = []
i = 0
while i < len(lt):
s = lt[i]
if s in self.keyword:
ans.append((self.keyword[s], s))
elif s in self.symbol:
if i + 1 < len(lt) and s + lt[i + 1] in self.symbol:
ans.append((self.symbol[s + lt[i + 1]], s + lt[i + 1]))
i += 1
else:
ans.append((self.symbol[s], s))
else:
no_answer = True
for key, value in self.regex.items():
if re.match(key, s):
ans.append((value, s))
no_answer = False
break
if no_answer:
ans.append((-1, 'error'))
i += 1
return ans
def result_print(self, lt: list[(int, str)]) -> None:
with open('output.txt', 'w', encoding='utf-8') as f:
for key, value in lt:
if key == -1:
print(value)
f.write(value + '\n')
else:
print(key, value, sep=' ')
f.write(f'{key} {value}\n')
def f(self) -> None:
s = self.readfile('testfile.txt')
s = self.strsplit(s)
s = self.analyze(s)
self.result_print(s)
GrammarAnalysis().f()