从0开始的python学习:编译原理实验3:词法分析器2—自动机方法

一开始是写了的,就是把之前实验2的东西稍微修改了一下,就去和助教讲了,讲完都没发现原来是做错了的,之后理解下来应该是要现在上边用某种数据结构规定几个判断某语句的DFA,然后扫描的时候自动匹配DFA来进行分析(已经学了快半年了,没有去看,差不多忘记了,不知道说的对不对)

实验三:词法分析器2—自动机方法

实验目的: 通过编写一个扫描器(词法分析器),掌握词法分析器的构造方法之一: 自动机方法(模拟DFA法)。

实验要求:

1、本词法分析器的任务:
(1)进行C语言子集LC程序的词法分析,C语言的子集LC={C语言常用的关键字10-15个 }∪{常数}∪{变量,即标识符}∪{关系运算符}∪{其它运算符}∪{界符}。输入为任意的C语言程序源文件,经过分析后产生一个.txt中间文件,供后续语法分析使用,该分析器设定6种数据类型,分别为关键字、标识符、常数、关系运算符、其它运算符和界符,每种类型包含的关键字个数和符号自行定义,C语言常用的关键字和符号都要包含在内。
(2)其中关系运算符、标识符和常数的识别用模拟DFA算法,其它符号自行选择方法。常数限定构词规则为如下格式:数字.数字,标识符限定构词规则为:字符后接字符或数字,关系运算符按课堂讲述的构词规则构成。
(3)输出以源程序代码的一行为输出的一行进行输出。输出结果可以与实验2相同。也可以按不同的分类方式输出。
(4)给出标识符符号表内容,对出现的标识符分别标记为id0, id1,id2……。
(5)给出至少2种错误提示:如非法word(err1)、小数点后无数字(err2)、注释符号不配对(err3)、其它你认为目前编译器应该给出的词法错误提示

测试用例

(1)/测试用例
(2)for (i=1;i<=100;i++)
(3){ printf("%d ", i );
(4)}
运行词法分析程序后,得到显示结果如下的.txt文件:
(1) (/
,30)(?err1)
(2) (for,16) ((,err) (i,id0) (=,31) (1,41) (;,22) (i , id0) (<=,err) (100,42) (;,22) (i , id 0) (++,37) (),err)
(3) ({,err) (Printf, id1) ((,err) (" ,21) (%,36) (d, id2) (" ,21) (,err) (i, id 0) ( ),err) ( ;,22)
(4)( },err)
变量表(标识符表)中的内容为:
id 0,i:
id1,printf,
id 2,d

环境:python 2.7 IDE:pyCharm

错误的实验代码(实验2的修改版)

没记错应该主要就加了一些出错判断以及小数点怎么处理,没记错是加入了了标志位
而且因为没有用DFA来做,导致了后面的if else 十分冗长,elif在那个时候也是不知道的hhhhh。。。。

开始的一些数据准备

# -*- coding: UTF-8 -*-
# 下面的注释纯粹是怕自己忘记怎么用,但实际并没有看几眼。。。
# list.append(obj)   增添对象
# extend 列表
# aList = [123, 'xyz', 'zara', 'abc', 123];
# bList = [2009, 'manni'];
# aList.extend(bList)
# 设置列表
list0 = ['IF', 11, 'THEN', 12, 'ELSE', 13, 'INT', 14, 'CHAR', 15, 'FOR', 16]   # 关键词
list1 = ['{', 90, '}', 91, '(', 92, ')', 93]  # 运算符
list2 = ['=', 21, '>=', 22, "==", 23, '+', 24,  '/', 25, '%', 26, '++', 27, '"', 28, ';', 29]    # 运算符
list4 = []    # 数字  动态添加
list5 = []    # 变量名  动态添加,检查是否存在
# 分割语句
list_temp = []

下面的是用来检查的语句,其实可以写个读取文件

str = '{ int n,i,kk;' \
      ' printf("n=3.6a");  scanf("%d",&n); ' \
      ' for (i=2; i<=kk; i++) ' \
      ' if(n%i==0) break; ' \
      ' if(i \
      ' else printf("%d yes\n",n); ' \
      ' return 0; ' \
      '}'

接下去正式开始处理前的最后一点准备

list_temp = str.split()   # 先暴力按空格把句子拆开
print list_temp           # 脑子不够用,看看拆了之后会发生什么

# 事先准备好变量名,不知道在python中是不是个坏习惯
i = 0
x = 1        # 0.1 的乘方,用来计算小数部分
sum_1 = 0    # 负责整数
sum_2 = 0.0  # 负责小数
flg_num = 0  # 标志位,是否进入小数部分
j = 0        # 40+j 用来加入list4中数字标识
k = 0        # 50+k 用来加入list5中数字标识

正式开始处理,直接简单粗暴,面向过程写下来了hhhh

# 开始遍历
for idx in range(len(list_temp)):    # 先对之前temp中粗粒度处理的文本进行细粒度处理,把一个个都分开
    str_new = list_temp[idx]
    i = 0    # 每次用完之后,初始化变量的值,确保之后不会出错,可能python里还有更简单的写法
    while i < len(str_new):
        if 'a' <= str_new[i] <= 'z' or 'A' <= str_new[i] <= 'Z':    # 第一个是字母
            if i != len(str_new)-1:                                 # 判断是否长度只有1
                end = i + 1                                         # 看下一个字母
                while end < len(str_new):
                    if 'a' <= str_new[end] <= 'z' or 'A' <= str_new[end] <= 'Z' or '0' <= str_new[end] <= '9':
                        end = end + 1
                    else:
                        end = end - 1
                        break
                if i != end:
                    tmp = str_new[i:end+1]       # 提取出那个有意义的单独字段
                    if tmp.upper() in list0:
                        print tmp, "(", tmp, ",", list0[list0.index(tmp.upper()) + 1], ")"
                    else:
                        if tmp not in list5:
                            list5.append(tmp)
                            list5.append(50 + k)
                            k = k + 1
                            print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                        else:
                            print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                    i = end + 1    # i指向了end的下一个字符
                    continue
                else:
                    tmp = str_new[i]
                    if tmp not in list5:
                        list5.append(tmp)
                        list5.append(50 + k)
                        k = k + 1
                        print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                    else:
                        print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                    i = end + 1
                    continue
            else:
                tmp = str_new[i]
                if tmp not in list5:
                    list5.append(tmp)
                    list5.append(50 + k)
                    k = k + 1
                    print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                else:
                    print tmp, "(", tmp, ",", list5[list5.index(tmp) + 1], ")"
                i = i + 1
                continue
        else:      
            if '0' <= str_new[i] <= '9':    # 第一个字符不是字母,是数字
            	# 以防万一每次使用前都初始化一下
                sum_1 = 0
                sum_2 = 0.0
                flg_num = 0    # 用来判断有没有用过小数点,一个数字只能出现一个小数点
                x = 1          # 用来做乘方,小数处理
                while i < len(str_new):
                    if '0' <= str_new[i] <= '9':
                        if flg_num == 0:
                            sum_1 = sum_1 * 10 + int(str_new[i])
                            i = i + 1
                        else:
                            sum_2 = sum_1 + int(str_new[i]) * (0.1 ** x)
                            x = x + 1
                            i = i + 1
                    else:
                        if str_new[i] == '.':
                            i = i + 1
                            flg_num = 1
                            if str_new[i] <= '0' or str_new[i] >= '9':
                                print sum_1, ".", "(", sum_1, ".", "err2", ")", "(小数点后无数字)"
                                num_end = i
                                i = i + 1
                                break
                            else:
                                continue
                        else:
                            num_end = i
                            if flg_num == 0:
                                if sum_1 not in list4:
                                    list4.append(sum_1)
                                    list4.append(40 + j)
                                    j = j + 1
                                    print sum_1, "(", sum_1, ",", list4[list4.index(sum_1) + 1], ")"
                                break
                            else:
                                if sum_2 not in list4:
                                    list4.append(sum_2)
                                    list4.append(40 + j)
                                    j = j + 1
                                    print sum_2, "(", sum_2, ",", list4[list4.index(sum_2) + 1], ")"
                                break
                i = num_end-1    # i是用作index 的缘故,从0开始计的
            else:
                # = 与 ==
                if str_new[i] == '=':
                    if str_new[i + 1] == '=':
                        print "==", "(", "==", ",", 23, ")"
                        i = i + 1
                    else:
                        print "=", "(", "=", ",", 21, ")"
                else:
                    # < 与 <=
                    if str_new[i] == '>':
                        if str_new[i + 1] == '=':
                            print ">=", "(", ">=", ",", 22, ")"
                            i = i + 1
                        else:
                            print ">", "(", ">", ",", "err", ")"
                    else:
                        # + 与 ++
                        if str_new[i] == '+':
                            if str_new[i + 1] == '+':
                                print "++", "(", "++", ",", 27, ")"
                                i = i + 1
                            else:
                                print "+", "(", "+", ",", 24, ")"
                        else:
                            if str_new[i] == '/':
                                print '/', "(", '/', ",", "25", ")"
                            else:
                                if str_new[i] == '%':
                                    print '%', "(", '%', ",", "26", ")"
                                else:
                                    if str_new[i] == '"':
                                        print '"', "(", '"', ",", "28", ")"
                                    else:
                                        if str_new[i] == ';':
                                            print ';', "(", ";", ",", "29", ")"
                                        else:
                                            if str_new[i] == '{':
                                                print '{', "(", "{", ",", "90", ")"
                                            else:
                                                if str_new[i] == '}':
                                                    print '}', "(", "}", ",", "91", ")"
                                                else:
                                                    if str_new[i] == '(':
                                                        print '(', "(", "(", ",", "92", ")"
                                                    else:
                                                        if str_new[i] == ')':
                                                            print ')', "(", ")", ",", "93", ")"
                                                        else:
                                                            # 错误判断,一般就是符号错误,最多2个,看下一位'='判断
                                                            if str_new[i] not in list2 and list1:
                                                                if i != len(str_new) - 1:
                                                                    if str_new[i + 1] == '=':
                                                                        print str_new[i: i + 2], "(", str_new[i: i + 2], ",", "err1", ")"
                                                                        i = i + 1
                                                                    else:
                                                                        print str_new[i], "(", str_new[i], ",", "err1", ")"
                                                                else:
                                                                    print str_new[i], "(", str_new[i], ",", "err1", ")"
        i = i + 1    # 用的while循环,别到最后死循环了
x = 0
print("常数有:")
print list4
while x < len(list4):
    if 2 * x < len(list4):       # 防止越界
        print(list4[2 * x])
    x = x + 1
x = 0
print("变量有:")
print list5
while x < len(list5):
    if 2 * x < len(list5):
        print(list5[2 * x])
    x = x + 1

你可能感兴趣的:(学校实验报告,python,编译原理,词法分析)