编译原理实验1——词法分析(python实现)

文章目录

实验目的

输入一个C语言代码串,输出单词流,识别对象包含关键字、标识符、整型浮点型字符串型常数、科学计数法、操作符和标点、注释等等。

实现

定义单词对应的种别码

自行定义相关单词的种别码
在这里插入图片描述
在这里插入图片描述

定义输出形式:三元式

# 三元式
class ThreeFml:  # 三元式def __init__(self, syn, inPoint, value):self.syn = syn  # 种别码self.inPoint = inPoint  # 内码值self.value = value  # 自身值def __eq__(self, other):  # 重载 判别对象相等的依据return self.syn == other.syn and self.value == other.valuedef __lt__(self, other):  # 重载 比较对象大小关系的依据if self.syn == other.syn:return self.inPoint < other.inPointelse:return self.syn < other.syn

每个三元组用一个自定义类表示:
类属性:种别码syn、内码值inPoint、自身值value
类方法

  • 方法1:判断两个三元组相等的方法:种别码syn和自身值value相等
  • 方法2:确定展示时的先后顺序的方法:先比较种别码syn,再比较内码值inPoint

例如:

  • 输入:double a; int a;
  • 输出:在这里插入图片描述
  • 分析:有两个标识符a,根据类方法1,判断前后两个a为同一个三元组,因此不重复输a。参见种别码表,double为6,int为2,则根据类方法2,进行三元组的展示排序。

python代码实现

import re# 三元式
class ThreeFml:  # 三元式def __init__(self, syn, inPoint, value):self.syn = syn  # 种别码self.inPoint = inPoint  # 内码值self.value = value  # 自身值def __eq__(self, other):  # 重载 判别对象相等的依据return self.syn == other.syn and self.value == other.valuedef __lt__(self, other):  # 重载 比较对象大小关系的依据if self.syn == other.syn:return self.inPoint < other.inPointelse:return self.syn < other.syn# 词法识别
class WordAnalysis:def __init__(self, input_code_str):self.input_code_str = input_code_str  # 源程序字符串self.code_char_list = []  # 源程序字符列表self.code_len = 0  # 源程序字符列表长度self.cp = 0  # 源程序字符列表指针,方便遍历字符串中的字符self.cur = ''  # 当前源程序字符列表的某个字符self.val = []  # 单词自身的值self.syn = 0  # 单词种别码self.errInfo = ""  # 错误信息self.keyWords = ["main", "int", "short", "long", "float","double", "char", "string", "const", "void","struct", "if", "else", "switch", "case","default", "do", "while", "for", "continue","break", "cout", "cin", "endl", "scanf","printf", "return", 'catch', 'class', 'delete','enum', 'export', 'extern', 'false', 'friend','goto', 'inline', 'namespace', 'new', 'not','public', 'static', 'template', 'this', 'true','try', 'typedef', 'union', 'using', 'virtual','std', 'include', 'iostream']  # 关键字self.TFs = []  # 存储三元式def nextChar(self):  # 封装cp++,简化函数scanWord中的代码self.cp += 1self.cur = self.code_char_list[self.cp]def error(self, info):  # errInfo错误信息line = 1for i in range(0, self.cp + 1):if self.code_char_list[i] == '\n':line += 1self.errInfo = "第" + str(line) + "行报错:" + infodef bracket_match(self):pattern = r'(\/\/.*?$|\/\*(.|\n)*?\*\/)'  # 匹配单行或多行注释comments = re.findall(pattern, self.input_code_str, flags=re.MULTILINE | re.DOTALL)comments = [comment[0].strip() for comment in comments]  # 处理结果,去除多余的空格i = 0code_sub_com = []  # 去除注释print(f"comment: {comments}")while i < len(self.input_code_str):ch = self.input_code_str[i]if ch == "/" and comments != []:i += len(comments[0])comments.pop(0)continuecode_sub_com.append((i, ch))i += 1pattern2 = r'"([^"]*)"'  # 匹配双引号包裹的字符串strings = re.findall(pattern2, self.input_code_str)code_sub_com_str = []  # 去除字符串变量i = 0while i < len(code_sub_com):item = code_sub_com[i]ch = item[1]if ch == "\"" and comments != []:i += len(strings[0]) + 2strings.pop(0)continuecode_sub_com_str.append(item)i += 1s = []stack = []mapping = {")": "(", "}": "{", "]": "["}for idx, char in code_sub_com_str:if char in mapping.keys() or char in mapping.values():s.append((idx, char))if not s:return "ok"for item in s:idx = item[0]char = item[1]if char in mapping.values():  # 左括号stack.append(item)elif char in mapping.keys():  # 右括号if not stack:  # 栈为空,当前右括号匹配不到return idxtopitem = stack[-1]topidx = topitem[0]topch = topitem[1]if mapping[char] != topch:  # 当前右括号匹配失败return topidxelse:stack.pop()if not stack:  # 栈为空,匹配完毕return "ok"else:  # 栈不为空,只剩下左括号item = stack[0]idx = item[0]return idxdef scanWord(self):  # 词法分析# 初始化valueself.val = []self.syn = 0# ******获取当前有效字符(去除空白,直至扫描到第一个有效字符)******self.cur = self.code_char_list[self.cp]# print(f"==={self.cp}  {self.code_len-1}===")while self.cur == ' ' or self.cur == '\n' or self.cur == '\t':self.cp += 1if self.cp >= self.code_len - 1:print(f"越界{self.cp}")return  # 越界直接返回self.cur = self.code_char_list[self.cp]# ********************首字符为数字*****************if self.cur.isdigit():# ====首先默认为整数 ====i_value = 0while self.cur.isdigit():  # string数转inti_value = i_value * 10 + int(self.cur)self.nextChar()six_flag = Falseif (self.cur == 'x' or self.cur == 'X') \and self.code_char_list[self.cp - 1] == '0':  # 十六进制整数 0x?????self.nextChar()six_flag = Trues = ""while self.cur.isdigit() or self.cur.isalpha():if self.cur.isalpha():if not (('a' <= self.cur <= 'f') or ('A' <= self.cur <= 'F')):self.syn = -999self.error("十六进制中的字母不为:a~f 或 A~F")returns += self.curself.nextChar()i_value = int(s, 16)  # 将16进制数转为整数self.syn = 201self.val = str(i_value)  # int转strif six_flag:return# ====有小数点或e,则为浮点数====d_value = i_value * 1.0if self.cur == '.':fraction = 0.1self.nextChar()while self.cur.isdigit():  # 计算小数位上的数 形如 123.45d_value += fraction * int(self.cur)fraction = fraction * 0.1self.nextChar()if self.cur == 'E' or self.cur == 'e':  # 形如 123.4E?? 或 123.E??self.nextChar()powNum = 0if self.cur == '+':  # 形如 123.4E+5self.nextChar()while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value *= 10 ** powNumelif self.cur == '-':  # 形如 123.4E-5self.nextChar()while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value /= 10 ** powNumelif self.cur.isdigit():  # 形如 123.4E5while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value *= 10 ** powNumif self.cur.isalpha():self.syn = -999self.error(f"科学计数法后含有多余字母{self.cur}")returnself.syn = 202self.val = str(d_value)  # double转strelif self.cur == 'E' or self.cur == 'e':  # 形如 123E??self.nextChar()powNum = 0if self.cur == '+':  # 形如 123E+4self.nextChar()while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value *= 10 ** powNumelif self.cur == '-':  # 形如 123E-4self.nextChar()while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value /= 10 ** powNumelif self.cur.isdigit():  # 形如 123E4while self.cur.isdigit():powNum = powNum * 10 + int(self.cur)self.nextChar()d_value *= 10 ** powNumif self.cur.isalpha():self.syn = -999self.error(f"科学计数法后含有多余字母{self.cur}")returnself.syn = 202self.val = str(d_value)# ********************首字符为字母*****************elif self.cur.isalpha():# ====标识符====while self.cur.isdigit() or self.cur.isalpha() or self.cur == '_':self.val.append(self.cur)self.nextChar()self.syn = 222# ====判断是否为关键字====for i, keyword in enumerate(self.keyWords):if ''.join(self.val) == keyword:self.syn = i + 1break# ********************首字符为标点*****************else:if self.cur == '+':self.syn = 101self.val.append(self.cur)self.nextChar()if self.cur == '+':self.syn = 131self.val.append(self.cur)self.nextChar()elif self.cur == '=':self.syn = 136self.val.append(self.cur)self.nextChar()elif self.cur == '-':self.syn = 102self.val.append(self.cur)self.nextChar()if self.cur == '-':self.syn = 132self.val.append(self.cur)self.nextChar()elif self.cur == '=':self.syn = 137self.val.append(self.cur)self.nextChar()elif self.cur == '*':self.syn = 103self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 138self.val.append(self.cur)self.nextChar()elif self.cur == '/':self.syn = 104self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 139self.val.append(self.cur)self.nextChar()# 单行注释elif self.cur == '/':self.nextChar()while self.cur != '\n':self.nextChar()self.syn = 0# 多行注释elif self.cur == '*':self.cp += 1haveEnd = Falseflag = 0for i in range(self.cp + 1, self.code_len):# print(self.code_char_list[i])if self.code_char_list[i - 1] == '*' and self.code_char_list[i] == '/':haveEnd = Trueflag = ibreakif haveEnd:self.syn = 0self.cp = flag + 1else:self.syn = -999self.error(" 多行注释没有结尾*/ ")elif self.cur == '%':self.syn = 105self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 140self.val.append(self.cur)self.nextChar()elif self.cur == '=':self.syn = 106self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 118self.val.append(self.cur)self.nextChar()elif self.cur == '(':self.syn = 107self.val.append(self.cur)self.nextChar()elif self.cur == ')':self.syn = 108self.val.append(self.cur)self.nextChar()elif self.cur == '[':self.syn = 109self.val.append(self.cur)self.nextChar()elif self.cur == ']':self.syn = 110self.val.append(self.cur)self.nextChar()elif self.cur == '{':self.syn = 111self.val.append(self.cur)self.nextChar()elif self.cur == '}':self.syn = 112self.val.append(self.cur)self.nextChar()elif self.cur == ';':self.syn = 113self.val.append(self.cur)self.nextChar()elif self.cur == '>':self.syn = 114self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 116self.val.append(self.cur)self.nextChar()elif self.cur == '>':self.syn = 119self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 141self.val.append(self.cur)self.nextChar()elif self.cur == '<':self.syn = 115self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 117self.val.append(self.cur)self.nextChar()elif self.cur == '<':self.syn = 120self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 142self.val.append(self.cur)self.nextChar()elif self.cur == '!':self.syn = 121self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 122self.val.append(self.cur)self.nextChar()elif self.cur == '&':self.syn = 123self.val.append(self.cur)self.nextChar()if self.cur == '&':self.syn = 124self.val.append(self.cur)self.nextChar()elif self.cur == '=':self.syn = 143self.val.append(self.cur)self.nextChar()elif self.cur == '|':self.syn = 125self.val.append(self.cur)self.nextChar()if self.cur == '|':self.syn = 126self.val.append(self.cur)self.nextChar()elif self.cur == '=':self.syn = 144self.val.append(self.cur)self.nextChar()elif self.cur == '\\':  # \self.syn = 127self.val.append(self.cur)self.nextChar()elif self.cur == '\'':  # ‘self.syn = 128self.val.append(self.cur)self.nextChar()elif self.cur == '\"':  # ”self.nextChar()haveEnd = Falseflag = 0for i in range(self.cp, self.code_len):if self.code_char_list[i] == '"':haveEnd = Trueflag = ibreakif haveEnd:for j in range(self.cp, flag):self.val.append(self.code_char_list[j])self.cp = flag + 1self.cur = self.code_char_list[self.cp]self.syn = 203else:self.syn = -999self.error(" string常量没有闭合的\" ")elif self.cur == ':':self.syn = 130self.val.append(self.cur)self.nextChar()if self.cur == ':':self.syn = 134self.val.append(self.cur)self.nextChar()elif self.cur == ',':self.syn = 133self.val.append(self.cur)self.nextChar()elif self.cur == '^':  # 按位异或self.syn = 146self.val.append(self.cur)self.nextChar()if self.cur == '=':self.syn = 145self.val.append(self.cur)self.nextChar()elif self.cur == '#':self.syn = 147self.val.append(self.cur)self.nextChar()else:self.syn = -999self.error(f" 无效字符: {self.cur}")def solve(self):print("\n================scan-main  begin================")self.code_char_list = list(self.input_code_str.strip())  # 去除头尾的空格self.code_char_list.append('\n')  # 末尾补充一个\n, 可在一些while判断中 防止越界self.code_len = len(self.code_char_list)if self.bracket_match() != "ok":  # 检测括号匹配self.cp = self.bracket_match()self.error(f"{self.code_char_list[self.cp]}匹配缺失!")intCnt, doubleCnt, stringCnt, idCnt = 0, 0, 0, 0  # 内码值while True:  # 至少执行一次,如同do whileself.scanWord()  # 进入词法分析value = ''.join(self.val)  # char列表 ===> Stringnew_tf = ThreeFml(self.syn, -1, value)  # 创建三元式对象if self.syn == 201:  # 整型常数# print(f"整型常数: {value}")if not any(tf == new_tf for tf in self.TFs):  # append前先判断是否有重复intCnt += 1new_tf.inPoint = intCntself.TFs.append(new_tf)elif self.syn == 202:  # 浮点型常数# print(f"浮点型常数: {value}")if not any(tf == new_tf for tf in self.TFs):doubleCnt += 1new_tf.inPoint = doubleCntself.TFs.append(new_tf)elif self.syn == 203:  # 字符串常数# print(f"字符串常数: {value}")if not any(tf == new_tf for tf in self.TFs):stringCnt += 1new_tf.inPoint = stringCntself.TFs.append(new_tf)elif self.syn == 222:  # 标识符# print(f"标识符: {value}")if not any(tf == new_tf for tf in self.TFs):idCnt += 1new_tf.inPoint = idCntself.TFs.append(new_tf)elif 1 <= self.syn <= 100:  # 关键字# print(f"关键字: {value}")if not any(tf == new_tf for tf in self.TFs):new_tf.inPoint = 1self.TFs.append(new_tf)elif self.syn == 0:  # 注释内容、或者最后的\n# print("注释 or 结束")passelif self.syn == -999:  # 报错# print(f"error: {self.errInfo}")breakelse:  # 符号:标点符、算符# print(f"符号: {value}")if not any(tf == new_tf for tf in self.TFs):new_tf.inPoint = 1self.TFs.append(new_tf)if self.cp >= (self.code_len - 1):  # 最后一个元素 为自主添加的\n,代表结束# print(f"{cp}  跳出")breakif self.errInfo:  # 检查是否有报错print(self.errInfo)returnself.TFs.sort()  # 给三元式列表TFs排序(按种别码、内码)for tf in self.TFs:  # 打印print(f"({tf.syn}, {tf.inPoint}, {tf.value})")print("================scan-main  end================")if __name__ == '__main__':filepath = "./code.txt"with open(filepath, "r") as file:code = file.read()word_analysis = WordAnalysis(code)word_analysis.solve()

运行结果

输入:通过读取txt文件输入要分析的源程序串
在这里插入图片描述

输出:
在这里插入图片描述
第一行表示注释内容
后面为三元式(种别码,内码值,自身值)
从结果可以看到:

  • 输入代码串中有两个int关键字,并没有重复输出,只保留1个
  • 输入代码串中识别到多个标识符(我设定的种别码为222),由于它们的值不同,所以在种别码相同的情况下,给出不同的内码值。

检错处理

括号匹配
在这里插入图片描述
在这里插入图片描述

字符串常量未闭合
在这里插入图片描述
在这里插入图片描述

多行注释未闭合
在这里插入图片描述
在这里插入图片描述

十六进制数不规范
在这里插入图片描述
在这里插入图片描述

科学计数法不规范
在这里插入图片描述
在这里插入图片描述

总结

体会
在本次的实验中,通过对词法分析器的编写,在理论的基础上加深了对词法分析的理解和实践,所编写的词法分析器在多次的测试中均得到了正确的结果。
此外,我是先用c++编写的代码,确认大部分功能无误后,再改用python编写。在改语言的过程中,明显感受到python 的便利之处,就比如一个简单的判断字符是否为字母,在c++里需要自定义一个函数来判断(if ch>=’a’ and if ch<=’z’),而python则直接使用系统自带的isalpha函数即可,大大简化了代码量。

问题
编写的程序中,虽然已完成绝大部分单词分析功能,但对一些小细节就没有进行直接的编写。例如在识别用科学表示法表示的浮点型常量时,并没有考虑是否会溢出C++语言中的double类型,当然,这也可以认为是语义分析的任务,而非词法分析的任务,但这可以是程序改善的一处地方。

附思路流程图
总体逻辑:
在这里插入图片描述
主函数逻辑
在这里插入图片描述

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

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

相关文章

大数据术语系列(1)——COW和MOR,我如何使用chatgpt通俗易懂地理解了hudi这两种表类型

从传统数据库到大数据的转变&#xff0c;首当其冲的是各种术语的理解。 所以我与chatgpt发生了一系列对话&#xff0c;以便于我能快速理解这些术语。 我先把汇总的结果放在前边&#xff0c;后边会一步步地来说明我是如何获取这些信息的。前边我也发过一些关于chatgpt提示词相…

寒假提升(5)[利用位操作符的算法题]

日子是一天天地走&#xff0c;书要一页页地读。 ——毕淑敏 算法 位操作符的合理使用来解决问题1、题目大概2、理解和想办法解决3、结果 位操作符的合理使用来解决问题 1、题目大概 题目要求让我们把一个数字用二进制表示出来的时候&#xff0c;将他的奇数位置和偶数位置交换…

HarmonyOS 鸿蒙应用开发(十、第三方开源js库移植适配指南)

在前端和nodejs的世界里&#xff0c;有很多开源的js库&#xff0c;通过npm(NodeJS包管理和分发工具)可以安装使用众多的开源软件包。但是由于OpenHarmony开发框架中的API不完全兼容V8运行时的Build-In API&#xff0c;因此三方js库大都需要适配下才能用。 移植前准备 建议在适…

如何找准用户真实需求,建立情感连接?

品牌如果想要长久发展&#xff0c;除了独特的理念以及过硬的产品质量外还需要一点&#xff0c;那就在于它能持续、正确的为用户创造生活幸福感。这满足了用户的真实需求&#xff0c;并与其产生了情感连接&#xff0c;从而让品牌有机会逐渐融入、改善用户的生活实现长期价值与口…

10个简单有效的编辑PDF文件工具分享

10个编辑PDF文件工具作为作家、编辑或专业人士&#xff0c;您可能经常发现自己在处理 PDF 文件。无论您是审阅文档、创建报告还是与他人共享工作&#xff0c;拥有一个可靠的 PDF 编辑器供您使用都非常重要。 10个简单适用的编辑PDF文件工具 在本文中&#xff0c;我们将介绍当今…

操作系统-信号量机制(整型信号量 记录型信号量)与用信号量实现进程互斥,同步,前驱关系

文章目录 信号量机制总览信号量机制整型信号量记录型信号量例子记录型信号量小结 小结 用信号量实现进程互斥&#xff0c;同步&#xff0c;前驱关系总览信号量机制实现进程互斥信号量机制实现进程同步进程同步信号量实现进程同步 信号量机制实现前驱关系小结 信号量机制 总览 …

freeRTOS总结(十五)软件定时

1&#xff0c;软件定时器的简介&#xff08;了解&#xff09; 定时器&#xff1a; 从指定的时刻开始&#xff0c;经过一个指定时间&#xff0c;然后触发一个超时事件&#xff0c;用户可自定义定时器的周期 硬件定时器&#xff1a; 芯片本身自带的定时器模块&#xff0c;硬件定…

使用dbeaver导入Excel到mysql数据库

最近业务需要将Excel导入到mysql数据库中&#xff0c;之前一直用的heisql&#xff0c;但是heidisql的导入功能太弱了&#xff0c;后来用了dbeaver&#xff0c;功能很强大。 一、安装dbeaver 首先去官网下载dbeaver社区版&#xff0c;社区版免费&#xff1a;dbeaver.io/ dbea…

3.2-媒资管理之MinIo分布式文件系统+上传图片

媒资管理 3 分布式文件系统 3.1 什么是分布式文件系统 要理解分布式文件系统首先了解什么是文件系统。 查阅百度百科&#xff1a; 文件系统是负责管理和存储文件的系统软件&#xff0c;操作系统通过文件系统提供的接口去存取文件&#xff0c;用户通过操作系统访问磁盘上的文…

JavaScript基础第三天

JavaScript 基础第三天 今天我们学习for循环、while循环、终止循环和无限循环。 1. for 循环 1.1. 语法 // 1. 语法格式 // for(起始值; 结束条件; 累加器) { // // 要重复执行的代码 // }1.2. 示例代码 let sum 0; for (let i 0; i < 100; i) {sum i; } alert(&q…

jsp康养小镇管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP康养小镇管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&a…

[超分辨率重建]ESRGAN算法训练自己的数据集过程

一、下载数据集及项目包 1. 数据集 1.1 文件夹框架的介绍&#xff0c;如下图所示&#xff1a;主要有train和val&#xff0c;分别有高清&#xff08;HR&#xff09;和低清&#xff08;LR&#xff09;的图像。 1.2 原图先通过分割尺寸的脚本先将数据集图片处理成两个相同的图像…

JavaScript中call、apply、bind方法的应用与区别

在JavaScript中&#xff0c;call、apply和bind是函数的三个重要方法&#xff0c;它们虽然功能不同&#xff0c;但都可以用来改变函数的执行上下文或者传递参数。本文将分别介绍call、apply和bind方法的应用和区别&#xff0c;并附带示例代码。 一、call方法 call方法的作用是…

Spring GateWay

概述简介 能干什么 反向代理 鉴权 流量控制 熔断 日志监控 Spring Cloud Gateway 与Zuul的区别 在SpringCloud Finchley正式版之前&#xff0c;Spring Cloud推荐的网关是 Netflix提供的Zuul: 1、Zuul 1.x&#xff0c;是一个基于阻塞Ⅳ/O的APl Gateway 2、Zuul 1.x基于Servl…

如何保持mac苹果电脑系统在最佳状态?不卡顿

苹果电脑一直以其卓越的性能和用户友好的操作系统而备受欢迎。然而电脑上的文件、应用程序和缓存可能会逐渐积累&#xff0c;导致性能下降。为了确保你的苹果电脑保持最佳状态&#xff0c;高效清理是至关重要的一步。在本文中&#xff0c;我们将分享一些如何清理苹果电脑更高效…

npm 上传一个自己的应用(1) 搭建一个项目环境

上文 在npm官网中注册一个账号并登录 带着大家创建了一个npm账号 我们先登录官网 然后 我们在自己电脑中创建一个文件夹 这个文件夹叫什么没有太大所谓 我这里直接叫 grnpmtext 然后 我们在这个文件夹中初始化一个项目 终端输入 npm initpackage name 要我们输入项目的名称 …

Java项目使用jasypt加密和解密配置文件中关键信息

一、使用背景 项目中application.yml 配置文件中&#xff0c;如数据库、redis、加密算法的私钥等各种配置的username&#xff0c;password的值都是明文的&#xff0c;其实存在一定的安全隐患&#xff0c;如果被人拿到这些配置文件&#xff0c;将直接对系统安全构成极大威胁&…

imgaug数据增强神器:增强器一览

官网&#xff1a;imgaug — imgaug 0.4.0 documentationhttps://imgaug.readthedocs.io/en/latest/ github:GitHub - aleju/imgaug: Image augmentation for machine learning experiments. imgaug数据增强神器&#xff1a;增强器一览_iaa 图像增强改变颜色-CSDN博客文章浏览阅…

Python环境下基于最大离散重叠小波变换和支持向量回归的金融时间序列预测

金融时间序列具有非线性、高频性、随机性等特点&#xff0c;其波动情况不仅与当前股票市场、房地产市场、贸易市场等有强联动性&#xff0c;而且大幅度起伏对于其他市场有较大的影响和冲击。由于金融市场受多种因素影响且各影响因素间也存在一定复杂动态交互关系&#xff0c;导…

开源项目的三年,我的项目经历了哪些变化?

0.前言 自己一个项目写了三年&#xff0c;到底写了什么东西了&#xff0c;这个项目经历了哪些变化呢&#xff1f;其中的心路历程如何&#xff1f; 兄弟们&#xff0c;要是感觉我的项目有价值&#xff0c;去b站给俺点点关注呐。我更新的更快。点击下面的了解就可以跳转去b站。…