编译原理:设计与实现一个简单词法分析器

news2024/12/23 22:31:07

设计与实现一个简单词法分析。具体内容是产生一个二元式文本文件,扩展名为dyd,可将Java或C程序(测试程序)分解成为一个一个的单词及类型。

(选做:并查“单词符号与种别对照表”得出其种别,用一数字表示。)

词法编译器基本功能包括:
(1) 输入源程序:输入C/java源程序;

(2) 输出单词,输出形式为:(序号,类型,单词);

(3) 输出出错信息,输出形式为:(出错行号,出错列号,出错信息);

为了运行代码并进行实验,需要满足以下条件:

1.Python环境:确保计算机上安装了Python,并且可以在命令行中运行python命令。

2.输入源程序文件:创建一个名为input.java或input.c的文件,其中包含想要进行词法分析的Java/C源程序。确保源程序的语法是正确的,否则可能会导致词法分析错误。

3.下载依赖:下载需要的依赖库。

4.查看输出文件:运行成功后,将生成一个名为output.dyd的文件,其中包含了词法分析的结果,包括单词及其类型的二元式信息。

词法分析器源程序文件:(lexer.py)

import re
import tkinter as tk
from tkinter import filedialog

# 定义单词种别码
KEYWORD = 1
IDENTIFIER = 10
CONSTANT = 11
OPERATOR = 4
DELIMITER = 5

# 定义关键字列表
keywords = ["if", "int", "for", "while", "do", "return", "break", "continue"]


class LexicalAnalyzer:
    def __init__(self, window):
        # 窗口设置
        self.window = window
        self.window.title("词法分析器")
        self.window.geometry("500x500")

        # 顶部文件选择与运行控制区域
        self.top_frame = tk.Frame(self.window)
        self.top_frame.pack(side=tk.TOP, pady=10, padx=10)

        # 文件选择按钮
        self.select_file_button = tk.Button(self.top_frame, text="选择文件", command=self.select_file)
        self.select_file_button.pack(side=tk.LEFT)

        # 运行按钮
        self.run_button = tk.Button(self.top_frame, text="运行", state=tk.DISABLED, command=self.run_analysis)
        self.run_button.pack(side=tk.RIGHT)

        # 中间的文本显示框
        self.text_frame = tk.Frame(self.window)
        self.text_frame.pack(pady=10)

        self.scrollbar = tk.Scrollbar(self.text_frame)
        self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.display_area = tk.Text(self.text_frame, wrap=tk.WORD, yscrollcommand=self.scrollbar.set)
        self.display_area.pack(side=tk.LEFT, fill=tk.BOTH)

        self.scrollbar.config(command=self.display_area.yview)

        # 底部状态栏区域
        self.status_bar = tk.Frame(self.window)
        self.status_bar.pack(side=tk.BOTTOM, pady=10)

        self.status_label = tk.Label(self.status_bar, text="请选择一个文件")
        self.status_label.pack()

        # 初始化属性
        self.input_file = None
        self.tokens = []

    def select_file(self):
        self.input_file = filedialog.askopenfilename(filetypes=[("C源程序", "*.c"), ("文本", "*.txt"), ("所有文件", "*.*")])
        if self.input_file:
            self.status_label.config(text=f"已选择文件:{self.input_file}")
            self.run_button.config(state=tk.NORMAL)

    def run_analysis(self):
        if not self.input_file:
            return

        self.status_label.config(text="运行中,请稍候...")
        self.window.update()

        with open(self.input_file, 'r', encoding='utf-8') as file:
            lines = file.readlines()

        token_count = 0
        error_count = 0
        self.tokens.clear()

        for line_number, line in enumerate(lines, start=1):
            words = re.findall(r'[a-zA-Z_][a-zA-Z0-9_]*|\d+|&&|\|\||==|>=|<=|!=|[+\-*/=><,;(){}]', line)
            column_number = 1
            for word in words:
                category = classify_token(word)
                if category != -1:
                    self.tokens.append((line_number, column_number, category, word))
                    token_count += 1
                else:
                    self.display_area.insert(tk.END, f'Invalid token: {word} at Line {line_number}, Column {column_number}\n')
                    error_count += 1
                column_number += len(word) + 1

        if error_count == 0:
            self.status_label.config(text=f"词法分析完成,共生成 {token_count} 个二元式。")
            self.display_tokens()
            self.save_results()  # 保存结果到文件中
        else:
            self.status_label.config(text=f"词法分析失败,请查看输出窗口。")

    def display_tokens(self):
        self.display_area.delete('1.0', tk.END)
        for token in self.tokens:
            line_number, column_number, category, word = token
            self.display_area.insert(tk.END, f'({line_number},{column_number})\t{category}\t{word}\n')

   def save_results(self):
    output_file = filedialog.asksaveasfilename(defaultextension=".dyd", filetypes=[("二元式文件", "*.dyd")])
    if output_file:
        with open(output_file, 'w', encoding='utf-8') as file:
            for token in self.tokens:
                line_number, column_number, category, word = token
                file.write(f"{line_number}\t{column_number}\t{category}\t{word}\n")
            self.status_label.config(text=f"结果已保存至文件:{output_file}")

    def show(self):
        self.window.mainloop()


# 判断单词种别函数
def classify_token(word):
    if word in keywords:
        return KEYWORD
    elif re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', word):
        return IDENTIFIER
    elif re.match(r'^\d+$', word):
        return CONSTANT
    elif word in ['+', '-', '*', '/', '=', '>', '<', '==', '>=', '<=', '!=', '&&', '||']:
        return OPERATOR
    elif word in [',', ';', '(', ')', '{', '}']:
        return DELIMITER
    else:
        return -1  # 无法分类的单词种别码


if __name__ == '__main__':
    window = tk.Tk()
    analyzer = LexicalAnalyzer(window)
    analyzer.show()

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1277734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis数据结构之压缩列表

压缩列表是Redis为节约内存而开发的&#xff0c;是由一系列特殊编码的连续内存块组成的顺序型数据结构。一个压缩列表可以包含任意多个节点&#xff0c;每个节点可以保存一个字节数组或者整数值。 压缩列表构成 zlbytes: 记录整个压缩列表占用的内存字节数&#xff0c;对压缩列…

【每日一题】1094. 拼车-2023.12.2

题目&#xff1a; 1094. 拼车 车上最初有 capacity 个空座位。车 只能 向一个方向行驶&#xff08;也就是说&#xff0c;不允许掉头或改变方向&#xff09; 给定整数 capacity 和一个数组 trips , trip[i] [numPassengersi, fromi, toi] 表示第 i 次旅行有 numPassengersi…

Android 缩减、混淆处理和优化应用

为了尽可能减小应用的大小&#xff0c;您应在发布 build 中启用缩减功能来移除不使用的代码和资源。启用缩减功能后&#xff0c;您还会受益于两项功能&#xff0c;一项是混淆处理功能&#xff0c;该功能会缩短应用的类和成员的名称&#xff1b;另一项是优化功能&#xff0c;该功…

eclipse中设置自动补齐代码

eclipse中设置自动补齐代码 01 在window里找到preference 02 在preference里搜索content assist 03 在Java的content assist设置 设置为.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 04 apply and close即可

PyLMKit(3):基于角色扮演的应用案例

角色扮演应用案例RolePlay 0.项目信息 日期&#xff1a; 2023-12-2作者&#xff1a;小知课题: 通过设置角色模板并结合在线搜索、记忆和知识库功能&#xff0c;实现典型的对话应用功能。这个功能是大模型应用的基础功能&#xff0c;在后续其它RAG等功能中都会用到这个功能。功…

Linux基础项目开发1:量产工具——UI系统(五)

前言&#xff1a; 前面我们已经把显示系统、输入系统、文字系统搭建好了&#xff0c;现在我们就要给它实现按钮操作了&#xff0c;也就是搭建UI系统&#xff0c;下面让我们一起实现UI系统的搭建吧 目录 一、按钮数据结构抽象 ui.h 二、按键编程 1.button.c 2.disp_manager…

赤峰学院师资培养管理系统的设计与实现

摘 要 随着我国国民经济建设的蓬勃发展和信息技术的越发成熟&#xff0c;各个行业都在积极使用现代化的管理工具&#xff0c;不断改善企业的服务质量&#xff0c;提高工作效率。对师资培养进行现代化的管理&#xff0c;提高工作效率是师资培养管理系统的一大优点。本文是一篇关…

Aspice(Automotive Software Process Improvement and Capability Determination)

Aspice&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09; 1. 引言&#xff1a;ASPICE概述 定义 ASPICE简介&#xff1a;ASPICE&#xff08;Automotive Software Process Improvement and Capability Determination&#xff09;…

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2

Qt Creator 11.0.3同时使用Qt6.5和Qt5.14.2 概要方法1.打开Qt Creator中的Kit&#xff0c;这里我直接附上几张截图&#xff0c;不同的版本打开位置可能有所不同&#xff0c;总之最终目的是要打开构建套件&#xff08;Kit&#xff09;2.可以看到构建套件里面有包含了“构建套件K…

栈顺序存储的实现(详解)

栈是一种数据结构&#xff0c;它具有后进先出&#xff08;LIFO&#xff09;的特性。栈可以用来存储一组元素&#xff0c;并且只能在栈顶进行插入和删除操作。栈的基本概念包括&#xff1a; 1. 入栈&#xff08;push&#xff09;&#xff1a;将元素添加到栈顶的操作。 2. 出栈&…

【halcon】C# halcon 内存暴增

1 读取图片需要及时手动释放 一个6M的图片通过halcon进行加载&#xff0c;大约会消耗200M的内存&#xff0c;如果等待GC回收&#xff0c;而你又在不停的读取图片&#xff0c;你的内存占用&#xff0c;将在短时间内飙升。 2 halcon控件显示图片需要清空。 /// <summary>…

Motion 5 for Mac,释放创意,打造精彩视频特效!

Motion 5 for Mac是一款强大的视频后期特效处理软件&#xff0c;为Mac用户提供了无限的创意可能性。无论你是专业的影视制作人&#xff0c;还是想为个人视频添加独特特效的爱好者&#xff0c;Motion 5都能满足你的需求&#xff0c;让你的视频脱颖而出。 Motion 5提供了丰富多样…

数据链路层之VLAN基本概念和基本原理

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

线程与多线程编程

1. 线程 1.1 概念 线程又可以称为轻量级进程 &#xff0c;在进程的基础上做出了改进。 一个进程在刚刚启动时&#xff0c;做的第一件事就是申请内存和资源&#xff0c;进程需要把依赖的代码和数据&#xff0c;从磁盘加载到内存中这件事是比较耗费时间的&#xff0c;有的业务…

国产AI边缘计算盒子,双核心A55丨2.5Tops算力

边缘计算盒子 双核心A55丨2.5Tops算力 ● 2.5TopsINT8算力&#xff0c;支持INT8/INT4/FP16多精度混合量化。 ● 4路以上1080p30fps视频编解码&#xff0c;IVE模块独立提供图像基础算子加速。 ● 支持Caffe、ONNX/PyTorch深度学习框架&#xff0c;提供resnet50、yolov5等AI算…

vue项目报错及解决npm run build:prod打包错误

vue项目报错及解决npm run build:prod打包错误 执行dev环境时加载失败了该变量&#xff0c;在package.json文件中 删掉 解决方法&#xff1a; 打包成功&#xff1a;

kerberos详解

一、介绍 kerberos概述 Kerberos始于20世纪80年代早期麻省理工学院&#xff08;MIT&#xff09;的一个研究项目&#xff0c;是一个网络身份验证系统。Kerberos提供的完整定义是安全的、单点登录的、可信的第三方相互身份验证服务。 认证过程 相关概念 KDC&#xff08;key D…

GD32 定时器输入捕获模式测量PWM占空比和频率

简介 利用GD32 定时器的PWM输入捕获模式来实现PWM波形的占空比和频率的测量。相应的简介可以参考GD32用户手册中关于定时器输入捕获的章节&#xff0c;PWM输入捕获模式是输入捕获模式的一个特例。(记录自己学习过程&#xff0c;如有错误请留言指出) 原理 如何利用定时器测量…

JavaSE-习题-循环结构等

第 1 题&#xff08;编程题&#xff09; 题目名称&#xff1a; 打印 X 图形 题目内容&#xff1a; https://www.nowcoder.com/practice/83d6afe3018e44539c51265165806ee4 假设i代表行&#xff0c;j代表列&#xff0c;当ij 或者 ij1 n&#xff0c;此时为星号。其余的都是空格。…

杨志丰:OceanBase助力企业应对数据库转型深水区挑战

11 月 16 日&#xff0c;OceanBase 在北京顺利举办 2023 年度发布会&#xff0c;正式宣布&#xff1a;将持续践行“一体化”产品战略&#xff0c;为关键业务负载打造一体化数据库。OceanBase 产品总经理杨志丰发表了《助力企业应对数据库转型深水区挑战》主题演讲。 以下为演讲…