本文章实现内容:
以二元式形式输出单词(单词种类,值)
关键字: if、int、for、while、do、return、break、continue;单词种别码为1。
标识符;单词种别码为2
常数为无符号整形数;单词种别码为3。
运算符包括:+、-、*、/、=、>、<、>=、<=、!= ;单词种别码为4。
分隔符包括: ,、;、{、}、(、);单词种别码为5;
基于上一篇c语言版本改写
输入数据举例:
编辑一个文本文件 program.txt,在文件中输入如下内容:
main()
{
int a,b;
a = 10;
b = a + 20;
}
输出结果
(2,“main”)
(5,“(”)
(5,“)”)
(5,“{”)
(1,“int”)
(2,“a”)
(5,“,”)
(2,“b”)
(5,“;”)
(2,“a”)
(4,“=”)
(3,“10”)
(5,“;”)
(2,“b”)
(4,“=”)
(2,“a”)
(4,“+”)
(3,“20”)
(5,“;”)
(5,“}”)
代码如下:
# 输出结果
def output(str, a, b, type):
print("(%d,“%s”)" % (type, str[a:b + 1]))
# 判断字符串一部分是否属于关键字
# 是返回1不是返回2
def iskeywords(str, a, b):
# 关键字
keywords = {"if", "int", "for", "while", "do", "return", "break", "continue"}
s = str[a:a + b + 1] # 拷贝字符
if s in keywords: # 判断是否存在,存在返回1,否则返回2
return 1
else:
return 2
# 判断字符是否属于运算符或分隔符的一部分。
# 不是返回0,是返回1,是且后面能跟=号返回2
def belong_to(str, type):
if type == 4: # 选择运算符
library = "+-*/=>= 4:
return 2
else:
return 1
return 0
# 递归的词法分析函数,读入一行str字符串,初始位置 n = 0
# 分离+判断,打印输出类型
# 由之前的c语言版本改写而成
def scan(str, n):
# 7 种类型(最后输出1 - 5)
# -1
# 0: 初始
# 1: 关键字, 在keywords中
# 2: 标识符
# 3: 常数(无符号整型)
# 4: 运算符和界符:+ - * / = > < >= <= !=
# 5: 分隔符:, ; {}()
i = n
type = 0
while i < len(str):
if type == 0: # 初始态
if str[i] == ' ': # 空格跳过
n += 1
i += 1
continue
elif str[i] == '\0' or str[i] == '\n': # 是结束
return
elif ('a' <= str[i] <= 'z') or ('A' <= str[i] <= 'Z'):
type = 1 # 是字母,
elif '0' <= str[i] <= '9':
type = 3 # 是数字,常数
else:
type = belong_to(str[i], 4)
if type > 0: # 是运算符
# 是能跟=号的运算符,后面是=号
if type == 2 and str[i + 1] == '=':
i = i + 1 # 结束位置后移
output(str, n, i, 4) # 输出 + 递归 + 结束
scan(str, i + 1)
return
elif belong_to(str[i], 5): # 是分隔符
output(str, n, i, 5) # 输出 + 递归 + 结束
scan(str, i + 1)
return
else:
print("失败:", str[i])
return
elif type == 1: # 关键字或标识符
if not (('a' <= str[i] <= 'z') or ('A' <= str[i] <= 'Z')): # 不是字母了
if '0' <= str[i] <= '9': # 是数字,只能是标识符
type = 2
else: # 非字母数字
type = iskeywords(str, n, i - 1)
output(str, n, i - 1, type) # 输出 + 递归 + 结束
scan(str, i)
return
elif type == 2: # 标识符
if not (('a' <= str[i] <= 'z') or ('A' <= str[i] <= 'Z')):
# 不是字母了
if not ('0' <= str[i] <= '9'):
# 不是数字
output(str, n, i - 1, type) # 输出 + 递归 + 结束
scan(str, i)
return
elif type == 3:
if not ('0' <= str[i] <= '9'):
# 不是数字
output(str, n, i - 1, type) # 输出 + 递归 + 结束
scan(str, i)
return
else:
print("%d失败" % type)
i += 1
file = "program.txt"
file = open(file) # 读取文件
while i := file.readline():
scan(i,0)
file.close()
# 这里的运算符界符有些区别,这里识别的是+ - * / = > < ! == >= <= !=