编译原理词法分析器

算法描述

对于给出的源代码,我们按行将其读入,对于每一行单独进行词法分析。

  1. 过滤行前后空格
  2. 对字符串进行词语的分割
    • 有空格则把空格前的字符归为一个词
    • 比较上一个字符和当前字符是否需要进行分割
  3. 检查词语是否合法
  4. 词语合法则按 [待测代码中的单词符号] [TAB] <[单词符号种别],[单词符号内容]> 进行输出,其中,单词符号种别为 KW(关键字)、OP(运算符)、SE(界符)、IDN(标识符)INT(整形数);单词符号内容 KW、OP、SE 为其编号(见单词表),其余为其值。
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>using namespace std;const int WORD_NUM = 26;
const string WORD[WORD_NUM] = {"int", "void", "return", "const", "main", "struct", "+",  "-",  "*",  "/","%",   "=",    ">",      "<",     "==",   "<=", ">=", "!=", "&&","||",  "(",    ")",      "{",     "}",    ";",  ",",
};
const string OPERATOR = "+-*/%><=&|";
const string SEPARATER = "(){};,[]";
int kws = 0, kwe = 6, ops = 6, ope = 20, ses = 20, see = 26;class Analyzer {private:vector<string> lines;vector<string> token;string fileName;ofstream fout;int isWord(string word) {for(int i = 0; i < WORD_NUM; i++) {if(word == WORD[i])return i;}return -1;}bool isKeyWord(int idx) {return kws <= idx && idx < kwe;}bool isOperator(int idx) {return ops <= idx && idx < ope;}bool isOperator(char ch) {return OPERATOR.find(ch) != OPERATOR.npos;}bool isSeparater(int idx) {return ses <= idx && idx < see;}bool isSeparater(char ch) {return SEPARATER.find(ch) != SEPARATER.npos;}inline bool isNumber(char ch) {return ch >= '0' && ch <='9';}bool isInt(string word) {for(int i = 0; i < word.size(); i++) {if(!isNumber(word[i]))return false;}return true;}inline bool isCharacter(char ch) {return ch >= 'a' && ch <= 'z' || ch >='A' && ch <= 'Z';}bool isPartOfIdentifier(char c) {return isCharacter(c) || isNumber(c) || c == '_';}bool isIdentifier(string word) {if(isNumber(word[0])) {return false;}for(int i = 1; i < word.size(); i++) {if(!isPartOfIdentifier(word[i]))return false;}return true;}//输出inline void record(string word, string type, string content) {char TAB = '\t';string msg = word + TAB + "<" + type + "," + content + ">";fout << msg << endl;token.push_back(msg);}//int 转 stringstring to_string(int val) {stringstream ss;ss << val;string result;ss >> result;return result;}//分析一个单词bool anaylyseWord(string word) {if(word.empty()) {return true;}int idx = isWord(word);if(idx > -1) {string type;if(isKeyWord(idx)) type = "KW";if(isOperator(idx)) type = "OP";if (isSeparater(idx)) type = "SE";record(word, type, to_string(idx + 1));return true;} else {if(isIdentifier(word)) {record(word,"IND", word);return true;}if(isInt(word)) {record(word,"INT", word);return true;}}fout << "ERROR detected!" << endl;cout << "ERROR detected!" << endl;return false;}//去除字符串前后空格string trim(string s) { if(s == "") {return "";}int l = 0, r = s.size() - 1;while(s[l] == ' ' && l < s.size()) l++;while(s[r] == ' ' && r > l) r--;return s.substr(l,r + 1);}//判断两个相邻字符是否需要分割bool check(char a, char b) {if ((isOperator(a) && !isOperator(b)) ||(!isOperator(a) && isOperator(b)) || isSeparater(a) ||(!isSeparater(a) && isSeparater(b)))return false;return true;}public:Analyzer(string fileName) {readFile(fileName);}~Analyzer() {fout.close();}vector<string> getToken() {return token;}void readFile(string fileName) {this->fileName = fileName;fstream fin(fileName.c_str());if (!fin.is_open()) {throw "无法打开文件";}string line;while (getline(fin, line)) {line = trim(line);if(!line.empty())lines.push_back(line);}fin.close();// fout.open("token.txt");fout.open(fileName.substr(0,fileName.find_last_of(".")) + ".out");}void analyse() {int l = 0;string word = "";while(l < lines.size()) {string line = lines[l++]; //读入一行word.clear();for(int i = 0; i < line.size(); i++) {if(line[i] == ' ' || line[i] == '\t') { //分割单词if(!anaylyseWord(word)) return; //判断单词是否合法并打印word.clear();continue;}if(!check(word[word.size() - 1], line[i])) { //分割单词if(!anaylyseWord(word)) return; //判断单词是否合法并打印word.clear();}word += line[i]; }anaylyseWord(word); //到行末结束后,将剩余的拼成一个单词}}
};int main() {try {Analyzer analyzer("a.sy");analyzer.analyse();system("pause");} catch (const char *msg) {cout << msg << endl;}return 0;
}

算法NFA和DFA及单词表

请添加图片描述
请添加图片描述

单词符号种类种别码
int关键字1
void关键字2
return关键字3
const关键字4
main关键字5
struct关键字6
+运算符7
-运算符8
*运算符9
/运算符10
%运算符11
=运算符12
<运算符13
>运算符14
==运算符15
<=运算符16
>=运算符17
!=运算符18
&&运算符19
||运算符20
(界符21
)界符22
{界符23
}界符24
;界符25
,界符26

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

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

相关文章

常见树种(贵州省):019滇白珠、杜茎山、苍山越桔、黄背越桔、贵州毛柃、半齿柃、钝叶柃、细枝柃、细齿叶柃木、土蜜树、山矾、胡颓子、檵木

摘要&#xff1a;本专栏树种介绍图片来源于PPBC中国植物图像库&#xff08;下附网址&#xff09;&#xff0c;本文整理仅做交流学习使用&#xff0c;同时便于查找&#xff0c;如有侵权请联系删除。 图片网址&#xff1a;PPBC中国植物图像库——最大的植物分类图片库 一、滇白珠…

【Leetcode】【实现循环队列】【数据结构】

代码实现&#xff1a; typedef struct {int front;int back;int k;int* a;} MyCircularQueue;bool myCircularQueueIsEmpty(MyCircularQueue* obj) {return obj->frontobj->back; }bool myCircularQueueIsFull(MyCircularQueue* obj) {return (obj->back1)%(obj->…

【数据中台】开源项目(2)-Wormhole流式处理平台

Wormhole 是一个一站式流式处理云平台解决方案&#xff08;SPaaS - Stream Processing as a Service&#xff09;。 Wormhole 面向大数据流式处理项目的开发管理运维人员&#xff0c;致力于提供统一抽象的概念体系&#xff0c;直观可视化的操作界面&#xff0c;简单流畅的配置管…

GEE 22:基于GEE实现物种分布模型(更新中。。。。。。)

物种分布模型 1. 数据点准备1.1 数据加载1.2 去除指定距离内的重复点1.3 定义研究区范围1.4 选择预测因子1.5 伪不存在点生成 1. 数据点准备 1.1 数据加载 首先需要将CSV文件导入到GEE平台中&#xff0c;同样也可以导入shp格式文件。 // 1.Loading and cleaning your species …

P17C++析构函数

目录 前言 01 什么是析构函数 1.1 举个栗子 02 为什么要写析构函数 前言 今天我们要讨论一下它的“孪生兄弟”&#xff0c;析构函数&#xff0c;它们在某些方面非常相似。 与构造函数相反&#xff0c;当对象结束其生命周期&#xff0c;如对象所在的函数已调用完毕时&…

如何深刻理解从二项式分布到泊松分布

泊松镇贴 二项分布和泊松分布的表达式 二项分布&#xff1a; P ( x k ) C n k p k ( 1 − p ) n − k P(xk) C_n^kp^k(1-p)^{n-k} P(xk)Cnk​pk(1−p)n−k 泊松分布&#xff1a; P ( x k ) λ k k ! e − λ P(xk) \frac{\lambda^k}{k!}e^{-\lambda} P(xk)k!λk​e−…

坚鹏:中国工商银行数字化背景下银行公司业务如何快速转型培训

中国工商银行作为全球最大的银行&#xff0c;资产规模超过40万亿元&#xff0c;最近几年围绕“数字生态、数字资产、数字技术、数字基建、数字基因”五维布局&#xff0c;深入推进数字化转型&#xff0c;加快形成体系化、生态化实施路径&#xff0c;促进科技与业务加速融合&…

【JMeter】不同场景下的接口请求

场景1: 上传文件接口即Content-Type=multipart/form-data 步骤: 1. 接口url,method以及path正常填写 2.文件上传content-type是multipart/form-data,所以可以勾选【use multipart/form-data】,如果还有其他请求头信息可以添加一个请求头元件 3.请求参…

痤疮分类-yolov5 学习过程

1、在github上下载yolov5-5.0的源码。 GitHub - ultralytics/yolov5: YOLOv5 &#x1f680; in PyTorch > ONNX > CoreML > TFLite

【数据中台】开源项目(2)-Dbus系统架构

大体来说&#xff0c;Dbus支持两类数据源&#xff1a; RDBMS数据源 日志类数据源 1 RMDBMS类数据源的实现 以mysql为例子. 分为三个部分&#xff1a; 日志抽取模块(最新版DBus已经废弃该模块&#xff0c;使用canal直接输出到kafka) 增量转换模块 全量拉取模块 1.1 日志抽…

【JavaEE初阶】线程安全问题及解决方法

目录 一、多线程带来的风险-线程安全 1、观察线程不安全 2、线程安全的概念 3、线程不安全的原因 4、解决之前的线程不安全问题 5、synchronized 关键字 - 监视器锁 monitor lock 5.1 synchronized 的特性 5.2 synchronized 使用示例 5.3 Java 标准库中的线程安全类…

【Spring Boot】如何集成Swagger

Swagger简单介绍 Swagger是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化RESTful风格的Web服务。功能主要包含以下几点&#xff1a; 可以使前后端分离开发更加方便&#xff0c;有利于团队协作接口文档可以在线自动生成&#xff0c;有利于降低后端开发人员编写…

【源码分析】zeebe actor模型源码解读

zeebe actor 模型&#x1f64b;‍♂️ 如果有阅读过zeebe 源码的朋友一定能够经常看到actor.run() 之类的语法&#xff0c;那么这篇文章就围绕actor.run 方法&#xff0c;说说zeebe actor 的模型。 环境⛅ zeebe release-8.1.14 actor.run() 是怎么开始的&#x1f308; Lon…

【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

那些年,关于CKACKS认证的那些事儿?

前言 遥想2020年的年初&#xff0c;疫情封城封村之际&#xff0c;工作之余在B站将尚硅谷的linux中的k8s视频完整系统的学习了一遍&#xff0c;自此像是打通了任督二脉一般&#xff0c;开启了对k8s的探索之旅&#xff0c;一路也是磕磕绊绊的在工作中使用k8s。 终于在23年的6月仲…

【办公软件】电脑开机密码忘记了如何重置?

这个案例是家人的电脑&#xff0c;已经使用多年&#xff0c;又是有小孩操作过的&#xff0c;所以电脑密码根本不记得是什么了&#xff1f;那难道这台电脑就废了吗&#xff1f;需要重新装机吗&#xff1f;那里面的资料不是没有了&#xff1f; 为了解决以上问题&#xff0c;一般…

技术前沿探索:人工智能与大数据融合的未来

技术前沿探索&#xff1a;人工智能与大数据融合的未来 摘要&#xff1a;本博客将探讨人工智能与大数据融合领域的最新技术趋势、前沿研究方向以及挑战与机遇。通过介绍相关技术和案例&#xff0c;我们希望激发读者对这一领域的兴趣&#xff0c;并为其职业发展提供有益参考。 一…

万字解析设计模式之模板方法与解释器模式

一、模板方法模式 1.1概述 定义一个操作中算法的框架&#xff0c;而将一些步骤延迟到子类中&#xff0c;模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 例如&#xff0c;去银行办理业务一般要经过以下4个流程&#xff1a;取号、排队、办理具体业…

qt pdf 模块简介

文章目录 1. 技术平台2. Qt pdf 模块3. cmake 使用模块4. 许可证5. 简单示例5.1 CMakeLists.txt5.2 main.cpp 6. 总结 1. 技术平台 项目说明OSwin10 x64Qt6.6compilermsvc2022构建工具cmake 2. Qt pdf 模块 Qt PDF模块包含用于呈现PDF文档的类和函数。 QPdfDocument 类加载P…

监控同一局域网内其它主机上网访问信息

1.先取得网关IP 2.安装IPTABLES路由表 sudo apt-get install iptables 3.启用IP转发 sudo sysctl -p 查看配置是否生效 4.配置路由 iptables -t nat -A POSTROUTING -j MASQUERADE 配置成功后,使用sudo iptables-save查看