技术标签: 编译原理实验 c++语言 编译原理 目标代码生成
所有的源码:https://github.com/yanguojun123/Compile
先上代码:
(其余后面完善)
#pragma once
#include<iostream>
#include<string>
#include <fstream>
#include <sstream>
#include<Windows.h>
#include "tree.h"
#include<stack>
bool success = 1;
using namespace std;
char ch;//字符变量,存放最新读进的源程序字符
char strToken[100];//字符数组,存放构成单词符号的字符串
int len = 0;//记录字符串的长度
string klabel[29] = { "+","-","*","/","=","#","<","<=",">",">=",",",";",":=","(",")",".","const","var","procedure","begin","end","odd","if","then","call"
,"while","do","read","write" };
string slabel[100] = {};
string clabel[100] = {};
string result[1000] = {};//保存所有单词的结果数组
int procedureId = 0;//记录当前的过程层数
int tableId = 0;//当前名字表的下标
int dx = 3;//当前层数的偏移地址
int ip = 0;//全局符号表的指针
int slen = 0;//标识符表的下标
int clen = 0;//常量表的下标
//判断是否为数字
const char *input;
int index = 0;
int codeId = 0;//代码的下标
bool isDigit()
{
if (ch < 58 && ch >= 48)
return true;
else
return false;
}
//判断是否为小写字母
bool issLetter()
{
if (ch <= 122 && ch >= 97)
return true;
else
return false;
}
bool isDigit(char ch1)
{
if (ch1 < 58 && ch1 >= 48)
return true;
else
return false;
}
//把字符串转化为数字
int strToint(string str)
{
int len = str.length();
int count = 0;
for (int i = 0; i < len; i++)
{
if (str.at(i) <= 57 && str.at(i) >= 48)
count = count + (str.at(i) - 48)*pow(10, len - i - 1);
else
return -1;
}
return count;
}
//把数字转化为字符串
//string intTostr(int num)
//{
//}
//判断是否为小写字母
bool issLetter(char ch1)
{
if (ch1 <= 122 && ch1 >= 97)
return true;
else
return false;
}
//判断是否为大写字母
bool islLetter()
{
if (ch <= 90 && ch >= 65)
return true;
else
return false;
}
//将下一输入字符读到ch中
void GetChar()
{
ch = input[index];
index++;
}
//判断ch中是否是空白,若是,则调用GetChar直至读入下一个非空白的字符
void GetBC()
{
while (ch == 32)
GetChar();
}
//将ch中的字符连接到strToken之后
void concat()
{
strToken[len] = ch;
len++;
}
//对strToken中的字符串查找保留字表,若他是一个保留字则返回则返回他的编码,否则返回0值
int Reserve()
{
for (int i = 0; i < 29; i++)
{
/*const char *p = klabel[i].data();
if (strcmp(p,strToken)==0)
{
return i;
}*/
if (klabel[i] == strToken)
return i;
}
return -1;
}
//将搜索指示器回调一个字符位置
void Retract()
{
index--;
ch = 32;
}
//将strToken中的标识符插入到符号表
int insertId()
{
slabel[slen] = strToken;
slen++;
return slen - 1;
}
//将strToken中的常数插入到常数表
int insertConst()
{
clabel[clen] = strToken;
clen++;
return clen - 1;
}
string readFileIntoString(char * filename)
{
ifstream ifile(filename);
//将文件读入到ostringstream对象buf中
ostringstream buf;
char ch;
while (buf&&ifile.get(ch))
buf.put(ch);
//返回与流对象buf关联的字符串
return buf.str();
}
//检测是否已经存在此标识符
int isexists(string str)
{
for (int i = 0; i < slen; i++)
if (str == slabel[i])
return 1;
return 0;
}
//检测是否已经存在此常量
int isexistc(string con)
{
for (int i = 0; i < clen; i++)
if (con == clabel[i])
return 1;
return -1;
}
int isexists()
{
for (int i = 0; i < slen; i++)
if (strToken == slabel[i])
return i;
return -1;
}
//检测是否已经存在此常量
int isexistc()
{
for (int i = 0; i < clen; i++)
if (strToken == clabel[i])
return i;
return -1;
}
//名字表的结构体
struct symble
{
string name;
string kind;
int addr;
int attribute;//val/value
}symlabel;
//判断是否退出
symble table[20];
//在符号表里查找某个标识符
int findSymble(string str)
{
for (int i = 0; i < tableId; i++)
{
if (table[i].name == str)
return i;
}
return -1;
}
//在符号表里根据地址查找变量的名字
string findSymble(int addr1)
{
for (int i = 0; i < tableId; i++)
{
if (table[i].addr == addr1)
return table[i].name;
}
return "";
}
//目标指令的结构体:
struct tarInstruc
{
string funcCode=" ";
int levelDiff = 0;
int displacement = 0;
string content = " ";
};
tarInstruc code[200];
//从关键字表查找关键字的下标
int findKlabel(string str)
{
for (int i = 0; i < 29; i++)
{
if (str == klabel[i])
return i+1;
}
return -1;
}
//添加code,运算类型
void codeAdd(string str,int lev,int place,string con)
{
code[codeId].funcCode = str;
code[codeId].levelDiff = lev;
code[codeId].displacement = place;
code[codeId].content = con;
codeId++;
}
//添加code,非运算
void codeAdd(string str, int lev, int place)
{
code[codeId].funcCode = str;
code[codeId].levelDiff = lev;
code[codeId].displacement = place;
codeId++;
}
//主程序
void lex(string file1)
{
int code, value, num = 0;
/*cout << "请输入单词长度"<<endl;
cin >> num;
cout << "请输入单词:"<<endl;
cin >> input;*/
//char filename[] = "test.txt";
//const char *file = readFileIntoString(filename).data();
std::ifstream in(file1);
std::ostringstream tmp;
tmp << in.rdbuf();
std::string str = tmp.str();
cout << str << endl;
for (int i = 0; i < str.length(); i++)//如果输入中有大写字母,则转换为小写字母
if (str.at(i) <= 90 && str.at(i) >= 65)
str.at(i) = str.at(i) + 32;
const char *file = str.data();
input = file;
while (input[index] != 0)
{
len = 0;
//strcpy(strToken,"");
memset(strToken, 0, sizeof(strToken));
//cout << strToken << endl;
//Sleep(1000);
GetChar();
GetBC();
if (issLetter())//判断是否是字母
{
while (issLetter() || isDigit())
{
concat();
GetChar();
}
Retract();
result[ip] = strToken;
ip++;
code = Reserve();
if (code == -1)//不在关键字表里,即为标识符
{
int index1 = isexists();//检测此标识符是否存在
if (index1 != -1)
cout << "(" << strToken << ",id," << index1 << ")" << endl;
else
{
value = insertId();
cout << "(" << strToken << ",id," << value << ")" << endl;//输出标识符的三元组
}//cout << strToken<<endl;
}
else
{
cout << "(" << klabel[code] << "," << klabel[code] << ",-)" << endl;//输出关键字的二元组
}
}
else if (isDigit())//如果是数字,即为常量
{
while (isDigit())
{
concat();
GetChar();
}
Retract();
result[ip] = strToken;
ip++;
int index2 = isexistc();
if (index2 != -1)
cout << "(" << strToken << ",int," << index2 << ")" << endl;
else
{
文章浏览阅读2.2k次,点赞2次,收藏10次。物联网开发技术栈 内容简介作为互联网技术的进化,物联网开发并非孤立的技术栈,而是向上承接了互联网,向下统领了嵌入式硬件开发的一个承上启下的全栈开发技术。虽然我们并不能预测物联网技术栈最终的样子:统一的开发语言是 JavaScript 还是 Python 亦或者其他编程语言;HTTP、WebSockets、MQTT、CoAP 等协议谁会是最后的赢家,并且随着物联网的不断进化,甚至我们..._物联网技术java技术栈
文章浏览阅读674次,点赞10次,收藏11次。Git是一个分布式版本控制工具,通常用来对软件开发过程中的源代码文件进行管理,通过Git仓库来存储和管理这些文件,Git仓库分为两种:指的是存储在各个开发人员自己本机电脑上的Git仓库指的是远程服务器上的Git仓库commit:提交,将本地文件和版本信息保存到本地仓库push:推送(上传),将本地仓库文件和版本信息上传到远程仓库pull:拉取(下载),将远程仓库文件和版本信息下载到本地仓库。
文章浏览阅读4.6k次。pprof (gperftools)使用谷歌的工具集,可查看CPU采样结果。pprof (google-perftool),用于来分析程序,必须保证程序能正常退出。使用步骤:1.准备工具,先安装工具包libunwind-1.1.tar.gzgperftools-2.1.tar.gz解压后 configure到系统默认路径即可,之后直接-lprofiler 2.再安装图形工具sudo yum ins..._gperftools pprof
文章浏览阅读118次。JavaScript BOM:Navigator、History、Location
文章浏览阅读6.2k次,点赞16次,收藏66次。在前面通过使用MongoDB在命令窗口操作数据库,而MySQL数据库也同样可以在命令窗口使用sql语句操作数据库,在安装数据库的时候提到可以安装这个图形化工具的,为了节省安装时间和卡顿选择后续安装MongoDB图形化工具,在MySQL数据中同样也有这个MySQL workbench 图形化工具可以选择进行安装;那么本篇就来安装MongoDB的图形化工具 — MongoDBCompass。_mongodb数据库图形化工具
文章浏览阅读1.4k次,点赞13次,收藏10次。未来城市的大模型包括城市总体规划、城市交通运输管理、城市公共安全和应急管理、经济发展和产业园区发展、社区发展、资源承载调控、污染调控、社会资源优化调控、基础设施调控、人口研究等模型。其对城市要素、关键指标、函数、流程、模型、平台、技术、资金、人才、市场、自然环境等内外部因素进行仿真建模。采用物联网、云计算、大数据、数字孪生和人工智能等技术来获取地、物、人、组织、环境、社会、经济、业务逻辑和运营规律等相关数据。、物联网、大数据、云计算、数字孪生、元宇宙、可穿戴生理传感器、分布式新能源等各类新技术。
文章浏览阅读3.6k次。在上一篇文章中,我们知道了如何使用配置文件自定义主题,以允许商店所有者自己更改Shopify主题。 如上所述,这些设置会在用户单击管理面板的在线商店>主题部分中的自定义主题按钮时显示,并在主题开发文件的config / settings_schema.json文件中定义。在这篇文章中,我们将了解如何访问这些设置并在开发主题时调用它们。调用配置要调用模板中的配置信息,需要使用li..._shopify自定义主题
文章浏览阅读2.6k次。1.查看本地分支git branch绿色表示当前分支#######################################################2.查看远程分支git branch -a#######################################################3.切换分支git checkout branch_name..._本地分支 '(no branch)' (远程分支 = '(no branch)') 是无效的。引用名称必须遵循
文章浏览阅读2.2w次,点赞18次,收藏28次。java连接mysql出现The server time zone value '�й���ʱ��' is unrecognized的解决方法在Idea中连接数据库是抛出The server time zone value ‘�й���ʱ��’ is unrecogni错误 原因是因为使用了Mysql Connector/J 6.x以上的版本,然后就报了时区的错误。解决办法在配置url中添..._java.lang.runtimeexception: the server time zone value '嚙請對蕭嚙踝蕭
文章浏览阅读671次,点赞11次,收藏9次。并且在这个固定的serverless服务中去增加这个,应该不是应用元服务开发者有这个加入权限的,应该是要统一解决,类似实现和手机注册验证一样的,直接可以使用或者少量代码配置即可使用。另外就是如果是新的元服务应用,使用的serverless,如果不支持华为账户功能,就没法上架,这个也是比较麻烦的,前面已经使用serverless开发基本完成或者已经完成的,得用其他方式去实现才行吧。对于已经上架的应用和元服务、升级也没法进行。3月1日的时间是快到了。
文章浏览阅读5.7k次,点赞2次,收藏8次。准备工作:安装XAMPP,登陆apache,mysql,并通过phpadmin来创建数据库,新建一个表,插入一些数据:http://localhost/phpmyadmin,最好设置密码,不然后面连接数据库的时候可能会无法访问设置密码方式:修改密码--->一定要使用生成的密码来登陆,包括后面的数据库url也是。我简历的数据如下:这时候就可以在eclipse中编程开发_xammp进入可视化界面
文章浏览阅读119次。转自:http://blog.csdn.net/cailiang517502214/article/details/4797642spring.jar是包含有完整发布的单个jar包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到spring-mock.jar来进行辅助测试,正式应用系统中是用不得这些类的。...