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

设计与实现一个简单词法分析。具体内容是产生一个二元式文本文件,扩展名为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()

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Java 连接数据库

数据库&#xff1a;存储数据&#xff08;集中管理&#xff09; 目的&#xff1a; 文件中的数据能够放在数据库中集中管理 管理方法&#xff1a;一个项目一个库&#xff0c;每个库中包含最小化数据的表 开发&#xff1a; 节省存储空间&#xff0c;节省运行空间&#xff0c;采…

ELK分布式日志管理平台部署

目录 一、ELK概述 1、ELK概念&#xff1a; 2、其他数据收集工具&#xff1a; 3、ELK工作流程图&#xff1a; 4、ELK 的工作原理&#xff1a; 5、日志系统的特征&#xff1a; 二、实验部署&#xff1a; 1、ELK Elasticsearch 集群部署 2、安装 Elasticsearch-head 插件 …

【HTTP协议】简述HTTP协议的概念和特点

&#x1f38a;专栏【网络编程】 &#x1f354;喜欢的诗句&#xff1a;更喜岷山千里雪 三军过后尽开颜。 &#x1f386;音乐分享【如愿】 &#x1f970;欢迎并且感谢大家指出小吉的问题 文章目录 &#x1f33a;概念&#x1f33a;特点&#x1f384;请求协议&#x1f384;响应协议…

map()的用法

JavaScript Array map() 方法 先说说这个方法浏览器的支持&#xff1a; 支持五大主流的浏览器&#xff0c; 特别注意&#xff1a;IE 9 以下的浏览器不支持&#xff0c;只支持IE 9以上的版本的浏览器 特别注意&#xff1a;IE 9 以下的浏览器不支持&#xff0c;只支持IE 9以上的…

uniapp微信小程序地图实现绘制polygon(保姆级教程 全网最全!!!)

用户需求&#xff1a;需要在填写表单信息时&#xff0c;在地图上标绘自己房屋的位置信息。 这个问题处理了很久&#xff0c;在网上也没有找到全面的相关案例&#xff0c;所以我将我的思路分享给大家&#xff0c;希望可以解决大家遇到的问题。如果大家有更好的思路&#xff0c;…

分享几种 Java8 中通过 Stream 对列表进行去重的方法

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 1. Stream 的 distinct…

java商城系统选型技巧

近期有很多网友在知乎、百度上咨询如何选择java商城系统&#xff0c;本文我们介绍目前有哪些java商城系统&#xff0c;如何选择商城系统&#xff0c;希望有所帮助。 我们之前做过调研&#xff0c;目前java语言开发的商城系统主要有shop、javashop、ejavashop、远丰、mall4j、li…

重测序项目文章 | Fungal Diversity(IF:20.3)发表杯伞科真菌系统分类和毒蝇碱进化的研究

Clitocybaceae&#xff08;杯伞科&#xff09;是近期建立的真菌家族。目前&#xff0c;由于取样和用于系统发育分析的基因有限&#xff0c;该家族内的亚科分化和关系尚不清晰。该家族的一些蘑菇含有神经毒性毒蕈碱&#xff0c;导致全球范围内许多严重甚至致命的中毒事件。然而&…

vue2使用ElementUI

elementui官网&#xff1a;组件 | Element 1、全部引入 下载&#xff1a;npm i element-ui 在 main.js 中写入以下内容&#xff1a;import Vue from vue; import ElementUI from element-ui; import element-ui/lib/theme-chalk/index.css; import App from ./App.vue;Vue.use(…

『Fiddler数据抓包功攻略』| 如何使用Fiddler进行数据抓包与分析?

『Fiddler数据抓包功攻略』| 如何使用Fiddler进行数据抓包与分析&#xff1f; 1 关于Fiddler2 Fiddler安装3 Fiddler信息查看3.1 查看请求信息3.2 查看响应信息3.3 查看会话信息统计 4 Fiddler暂停抓包5 Fiddler清除抓包数据6 Fiddler设置Filters过滤6.1 关于Actions6.2 关于Us…

c++ day 4

代码整理&#xff0c; 将学过的三种运算符重载&#xff0c;每个至少实现一个运算符的重载:分别是-&#xff0c;-&#xff0c;<。 #include <iostream>using namespace std; class Stu {friend const Stu operator-(const Stu &L,const Stu &R);friend bool o…

picgo配置又拍云

又拍云控制台配置操作员账号 添加操作员账号 进入又拍云的控制台 又拍云控制台 (upyun.com) 右上角选择账号下拉框&#xff0c;选择账户管理 在账户管理中&#xff0c;选择操作员&#xff0c;添加操作员 输入操作员名字&#xff0c;点击生成密码&#xff0c;填入操作员备注…

音频修复和增强软件iZotope RX 10 mac特点介绍

iZotope RX 10 mac是一款音频修复和增强软件&#xff0c;主要特点包括&#xff1a; 声音修复&#xff1a;iZotope RX 10可以去除不良噪音、杂音、吱吱声等&#xff0c;使音频变得更加清晰干净。 音频增强&#xff1a;iZotope RX 10支持对音频进行音量调节、均衡器、压缩器、限…

Jinja2使用Layui报 “d is not defined“

问题出现场景在使用Jinja2渲染Layui的表格时候&#xff0c;要做自定义templte的传入 Jinja2这块本来就是支持 {{ }} 插值的模板语言&#xff0c;所以这块的第一种渲染方式会冲突 所以只能用函数返回代码块进行填充&#xff0c;不能使用插值&#xff0c;只能拼接字符串 templt…

web项目添加防调试

新建js文件debug-vconsole.js /**防止非法调试*/ (function () {function getLocationHrefParams(name) {var reg new RegExp("(^|&)" name "([^&]*)(&|$)");var r window.location.search.substr(1).match(reg);if (r ! null) return un…

docker部署elasticsearch+kibana+head

前言 最近&#xff0c;项目需要使用elasticsearch&#xff0c;所以就想快速安装一个使用&#xff0c;最开始是docker安装了7.10.1版本。 后面计划使用Java开发&#xff0c;发现有 RestHighLevelClient 和 Elasticsearch Java API Client两种客户端连接方式。 然后网上查阅了一…

【微服务 SpringCloudAlibaba】实用篇 · Nacos配置中心

微服务&#xff08;6&#xff09; 文章目录 微服务&#xff08;6&#xff09;1. 统一配置管理1.1 在nacos中添加配置文件1.2 从微服务拉取配置 2. 配置热更新2.1 方式一2.2 方式二 3. 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&am…

数字人可以为文化传播带来什么?

近日&#xff0c;由哈萨克斯坦驻华大使馆、中国外文局文化传播中心、中关村科幻产业创新中心联合发起的中哈青年友谊数字人怡漾和苏路&#xff08;Сұлу&#xff09;正式发布。其中&#xff0c;代表中方形象的数字人怡漾&#xff0c;不仅将成为中哈青年文化交流的标志与代言…

seq2seq:中英文翻译

文章目录 一、完整代码二、论文解读2.1 RNN模型2.2 Attention-based ModelsGlobal attentional modelLocal attentional model 2.3 Input-feeding Approach2.4 模型效果 三、过程实现3.1 导包3.2 数据准备3.3 构建相关类3.4 模型配置3.5 模型推理 四、整体总结 论文&#xff1a…

Facebook公共主页受限、被封?一文教你排雷解决

一、Facebook公共主页是什么&#xff1f; 现在人们的生活已经离不开各种社交媒体&#xff0c;只要有智能手机&#xff0c;或多或少会使用一些社交平台&#xff0c;而Facebook是一个拥有大量用户的社交平台。这对于各种企业而言&#xff0c;也是一个十分优秀的营销平台&#xf…