合肥工业大学(HFUT)编译原理实验一(Python实现)

一. 实验一:词法分析设计

二.实验目的及要求

实现目的:

  通过本实验的编程实践,使学生了解词法分析的任务,掌握词法分析程序设

计的原理和构造方法,使学生对编译的基本概念、原理和方法有完整的和清楚的

理解,并能正确地、熟练地运用。

实验要求:

  1、编程时注意编程风格:空行的使用、注释的使用、缩进的使用等。

2、将标识符填写的相应符号表须提供给编译程序的以后各阶段使用。

3、根据测试数据进行测试。测试实例应包括以下三个部分:

  全部合法的输入。

  各种组合的非法输入。

  由记号组成的句子

三. 实验内容

VC++/VB/JAVA 语言实现对 C 语言子集的源程序进行词法分析。通过输

入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单

词符号自身值;若遇到错误则显示“Error”,然后跳过错误部分继续显示 ;同时

进行标识符登记符号表的管理。

以下是实现词法分析设计的主要工作:

1)从源程序文件中读入字符。

2)统计行数和列数用于错误单词的定位。

3)删除空格类字符,包括回车、制表符空格。

4)按拼写单词,并用(内码,属性)二元式表示。(属性值——token 的机内

表示)

5)如果发现错误则报告出错

  1. 根据需要是否填写标识符表供以后各阶段使用

(8)识别注释

(9)判别浮点数和整数

四. 核心算法流程

五.核心代码

for line in open("test.txt", 'r', encoding="UTF-8"):

    str = line  #每次读一行内容

    i = 0

    while i < len(str):  #遍历当前行

        if jud1 != 1:    #如果不是注释

            if str[i].isdigit():  # 字符为数字

                jud = 1  # 用于判断该单词是不是纯数字

                str1 = ''  # 用于暂时存储单词

                while i < len(str):

                    if str[i].isdigit() or str[i] == '.':

                        str1 += str[i]

                        i += 1

                    elif str[i].isalpha():

                        str1 += str[i]

                        i += 1

                        jud = 0

                    else: break  #非字母或者数字(空格或者换行)就退出当前循环

                if jud == 1:  # 全为数字,构建输出

                    if str1 not in u: u.append(str1) #为常数表添加新的元素

                    mes = [str1, f'(1,{str1})', '常数', f'({hang},{lie})']

                else:  # 夹杂有字母(错误情况,不满足标识符的要求)

                    mes = [str1, 'Error', 'Error', f'({hang},{lie})']

                lie += 1

                message = tep.join(mes) #以tep为分隔符创建一个字符串

                output.append(message)

            elif str[i].isalpha():  # 字符为字母

                str1 = ""

                while i < len(str):

                    if str[i].isdigit() or str[i].isalpha() or str[i] == '_':

                        str1 += str[i]

                        i += 1

                    else:

                        break #不满足标识符要求

                if str1 in k:   #如果在关键字表中

                    mes = [str1, f'(1,{k.index(str1)})', '关键字', f'({hang},{lie})']

                elif str1 not in v: # 标识符

                    v.append(str1)

                    mes = [str1, f'(6,{str1})', '标识符', f'({hang},{lie})']

                else:

                    mes = [str1, f'(6,{str1})', '标识符', f'({hang},{lie})']

                lie += 1

                message = tep.join(mes)

                output.append(message)

            elif (str[i] in s):  # 字符为算术运算符

                str1 = ""

                # 判断当前是否是注释

                if str[i] == '/' and i != len(str)-1 and str[i+1] == '/':

                    i = len(str)

                elif str[i] == '/' and i != len(str)-1 and str[i+1] == '*':

                    jud1 = 1

                else:

                    while i < len(str):

                        if str[i] in s:

                            str1 += str[i]

                            i += 1

                        else: break

                    if str1 in s:   # 字符为算数运算符

                        mes = [str1, f'(3,{s.index(str1)})', '算术运算符', f'({hang},{lie})']

                    else:

                        mes = [str1, 'Error', 'Error', f'({hang},{lie})']

                    lie += 1

                    message = tep.join(mes)

                    output.append(message)

            elif (str[i] in t):  # 字符为关系运算符

                str1 = ""

                while i < len(str):

                    if str[i] in t:

                        str1 += str[i]

                        i += 1

                    else: break

                if str1 in t: mes = [str1, f'(4,{t.index(str1)})', '关系运算符', f'({hang},{lie})']

                else: mes = [str1, 'Error', 'Error', f'({hang},{lie})']

                lie += 1

                message = tep.join(mes)

                output.append(message)

            elif (str[i] in r):  # 字符为分界符

                str1 = str[i]

                i += 1

                mes = [str1, f'(2,{r.index(str1)})', '分界符', f'({hang},{lie})']

                lie += 1

                message = tep.join(mes)

                output.append(message)

            elif (str[i] == ' '): i += 1  #字符为空格

            elif (str[i] == '\n'): #字符为换行

                hang += 1

                i += 1

                continue

            else: # 收尾工作(以奇怪字符开头)

                str1 = str[i]

                i += 1

                mes = [str1, 'Error', 'Error', f'({hang},{lie})']

                lie += 1

                message = tep.join(mes)

                output.append(message)

        else:   #如果当前是注释

            while str[i] != '*' or str[i+1] != '/':

                if (i < len(str)-2):

                    i += 1

                else: break

            if str[i] == '*' and i != len(str)-1 and str[i+1] == '/': #注释的结尾

                jud1 = 0

                hang -= 1

                i += 2

            else: break

for datas in output:

    data_list = datas.split(' ')

    print(f"{data_list[0]:<15}{data_list[1]:<15}{data_list[3]:<15}{data_list[2]:<15}")

六. 具体代码

        github仓库链接:https://github.com/1StephenCurry1/Compiler-Design.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值