所完成功能
1.词法分析
2.语法分析
3.语义分析和中间代码生成
4.代码优化
5.目标代码生成
所实现语言的文法
采用下降分析方法,已将原来的文法改写成LL(1)文法。
- <程序> → <main关键字>(){<声明序列><语句序列>}
- <声明序列> → <声明语句><声明序列'> | ε
- <声明序列'> → <声明语句><声明序列'> | ε
- <声明语句> → <int关键字><标识符表>;
- <标识符表> → <标识符><标识符表'>
- <标识符表'> → ,<标识符><标识符表'> | ε
- <语句序列> → <语句><语句序列'>
- <语句序列'> → <语句><语句序列'> | ε
- <语句> → <if语句> | <while语句> | <for语句> || <复合语句> | <赋值语句>
- <if语句> → <if关键字> (<表达式>)<复合语句><else部分>
- <else部分> → <else关键字><复合语句> | ε
- <while语句> → <while关键字> (<表达式>)<复合语句>
- <for语句> → <for关键字> (<表达式>;<表达式>;<表达式>) <复合语句>
- <复合语句> → {<语句序列>}
- <赋值语句> → <标识符>=<表达式>
- <表达式> → <算数表达式> | <布尔表达式>
- <布尔表达式> → <算数表达式><关系运算符><算数表达式> | <算数表达式>
- <关系运算符> → > | < | >= | <= | == | !=
- <算数表达式> → <项><算数表达式'>
- <算数表达式'> → +<项><算数表达式'> | -<项><算数表达式'> | ε
- <项> → <因子><项'>
- <项'> → *<因子><项'> | /<因子><项'> | ε
- <因子> → <标识符> | <无符号整数> | (<算数表达式>)
- <标识符> → <字母><标识符'>
- <标识符'> → <字母><标识符'> | <数字><标识符'> | ε
- <无符号整数> → <数字><无符号整数'>
- <无符号整数'> → <数字><无符号整数'> | ε
- <字母> → a | b | ... | z | A | B | ... | Z
- <数字> → 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
- <main关键字> → main
- <if关键字> → if
- <else关键字> → else
- <while关键字> → while
- <for关键字> → for
- <int关键字> → int
总体概述:
1、词法分析器:该部分负责将输入的源代码文件转化为一个个字符串,将字符串中的内容逐个读取并存储到stringstream对象中,并使用while循环迭代读取其中的每个单词。识别关键字、标识符、常星、运算符等,并使用数组存储起来作为语法分析的输入。
2、语法分析器:语法分析器根据词法分析器生成的token,进行基本的语法分析,识别出语法结构,如声明语句、赋值语句、条件语句、循环语句等。然后采用递归下降解析来分析。
3、语义分析和优化︰在这个简单的程序中,包括一些简单的语义分析和优化,例如类型检查、常量折叠、构建DAG等。但其中没有完善其功能,只能部分实现。
4、目标代码生成:最后一个阶段是生成目标代码,根据经过优化的中间表示形式(如DAG)生成目标代码,即汇编语言代码
编译程序功能描述
该程序可以进行词法分析功能、语法分析功能、语义分析功能、DAG代码及优化功能和目标代码生成功能。
其中词法分析可以分析出关键字、边界符、标识符、数字和运算符。
语法分析可以推出采用了哪些文法进行推导代码。
语义分析可以处理赋值语句,生成相应的中间代码。此外,还可以通过拉链回填生成四元式。
优化方法可以输出DAG优化前和优化后的表达式。
目标代码生成,通过输入的寄存器个数,生成对应的汇编语言。
图1-1词法分析框图
部分函数如下图所示
语法分析
#include <bits/stdc++.h>
#include <fstream>
using namespace std;
vector<string> keywords = {"main", "if", "else", "for", "while", "int"};
vector<string> danci;
int cnt = 0;
int te = 0;
int m;
char fileadress[50] = "D://编译原理//分析结果存储//";
char name[30];
fstream ff;
void lalian();
void huitian();
bool isdigit(char ch) {
return (ch >= '0' && ch <= '9');
}
bool ischaractor(char ch) {
return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'));
}
bool isboundary(char ch) {
return (ch == '(' || ch == ')' || ch == '{' || ch == '}' || ch == ',' || ch == ';');
}
bool iskeyword(const string& s1) {
return find(keywords.begin(), keywords.end(), s1) != keywords.end();
}
bool isoperator(char ch) {
return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '=' || ch == '!' || ch == '<' || ch == '>');
}
void cifa() {
cout << "请输入文件名:";
ff << "请输入文件名:";
// char name[30];
cin >> name;
// gets(name);
ff << name;
strcat(fileadress, name);
ff.open(fileadress, ios::out);
ifstream myfile(name);
if (!myfile.is_open()) {
cout << "文件打开失败" << endl;
ff << "文件打开失败" << endl;
}
cout << endl << "****************************" << endl;
cout << "========词法分析如下========" << endl;
cout << "****************************" << endl;
ff << endl << "****************************" << endl;
ff << "========词法分析如下========" << endl;
ff << "****************************" << endl;
string str, s, s1;
stringstream ss;
while (getline(myfile, str)) {
if (str == "##")
break;
s1 += str;
}
ss << s1;
s = "";
myfile.close();
while (ss >> s) {//ss将s逐个读取
int len = s.length();//获取该字符串的长度
for (int i = 0; i < len;) {
if (isboundary(s[i])) {//判断是否为界符
cout << "(boundary," << s[i] << ")" << endl;
ff << "(boundary," << s[i] << ")" << endl;
danci.push_back(string(1, s[i]));//把该界符存起来
i++;
} else if (isdigit(s[i])) {//判断是否为数字
string s1 = "";
while (isdigit(s[i])) {//把整个数字取完
s1 += s[i++];
}
cout << "(integer," << s1 << ")" << endl;
ff << "(integer," << s1 << ")" << endl;
danci.push_back(s1);
} else if (ischaractor(s[i]) ) {//判断单词
string s1 = "";//单个读取,数字或者运算不止一个
while (ischaractor(s[i]) || isdigit(s[i])) {
s1 += s[i++];
}
if (iskeyword(s1)) {//判断是否为关键字
cout << "(keyword," << s1 << ")" << endl;
ff << "(keyword," << s1 << ")" << endl;
danci.push_back(s1);
} else {//不是关键字,则为标识符
cout << "(identifier," << s1 << ")" << endl;
ff << "(identifier," << s1 << ")" << endl;
danci.push_back(s1);
}
} else if (isoperator(s[i])) {//判断是否为标识符
if (i + 1 < len && s[i + 1] == '=') {
cout << "(operator," << s[i] << s[i + 1] << ")" << endl;
ff << "(operator," << s[i] << s[i + 1] << ")" << endl;
danci.push_back(s.substr(i, 2));//存取两个字母
i += 2;//若为==,则 i 要加 2
} else {//不是 == 则单个存起来
cout << "(operator," << s[i] << ")" << endl;
ff << "(operator," << s[i] << ")" << endl;
danci.push_back(string(1, s[i]));//存取一个字母
i++;
}
}
}
}
}
语法分析
void yuju() {
if (danci[cnt] == "if") {
cout << "<语句> → <if语句>" << endl;
ff << "<语句> → <if语句>" << endl;
ifyuju();
} else if (danci[cnt] == "while") {
cout << "<语句> → <while语句>" << endl;
ff << "<语句> → <while语句>" << endl;
whileyuju();
} else if (danci[cnt] == "for") {
cout << "<语句> → <for语句>" << endl;
ff << "<语句> → <for语句>" << endl;
foryuju();
} else if (danci[cnt][0] >= 'a' && danci[cnt][0] <= 'z' || danci[cnt][0] >= 'A' && danci[cnt][0] <= 'Z') {
cout << "<语句> → <赋值语句>" << endl;
ff << "<语句> → <赋值语句>" << endl;
fuzhiyuju();
} else {
// cout << danci[cnt] << endl;
error();
}
}
void yujuxulie1() {
if (danci[cnt][0] >= 'a' && danci[cnt][0] <= 'z' || danci[cnt][0] >= 'A' && danci[cnt][0] <= 'Z') {
cout << "<语句序列'> → <语句><语句序列'>" << endl;
ff << "<语句序列'> → <语句><语句序列'>" << endl;
yuju();
yujuxulie1();
}
}
void yujuxulie() {
if (danci[cnt + 1] == "}") {
cout << "<语句序列> → ε" << endl;
ff << "<语句序列> → ε" << endl;
} else {
cout << "<语句序列> → <语句><语句序列'>" << endl;
ff << "<语句序列> → <语句><语句序列'>" << endl;
yuju();
yujuxulie1();
}
}
void intkeyword() {
if (danci[cnt] == "int") {
cnt++;
cout << "<int关键字> → int" << endl;
ff << "<int关键字> → int" << endl;
} else {
error();
}
}
void biaoshifubiao1() {
if (danci[cnt] == ",") {
cnt++;
cout << "<标识符表'> → ,<标识符><标识符表'>" << endl;
ff << "<标识符表'> → ,<标识符><标识符表'>" << endl;
biaoshifu();
biaoshifubiao1();
} else {
cout << "<标识符表'> → ε" << endl;
ff << "<标识符表'> → ε" << endl;
}
}
void biaoshifubiao() {
te = 0;
cout << "<标识符表> → <标识符><标识符表'> " << endl;
ff << "<标识符表> → <标识符><标识符表'> " << endl;
biaoshifu();
biaoshifubiao1();
}
void shengmingyuju() {
cout << "<声明语句> → <int关键字><标识符表>;" << endl;
ff << "<声明语句> → <int关键字><标识符表>;" << endl;
intkeyword();
biaoshifubiao();
if (danci[cnt] == ";") {
cnt++;
}
}
void shengmingxulie() {
if (danci[cnt] == "int") {
cout << "<声明序列> → <声明语句><声明序列'>" << endl;
ff << "<声明序列> → <声明语句><声明序列'>" << endl;
shengmingyuju();
shengmingxulie1();
} else {
cout << "<声明序列> → ε" << endl;
ff << "<声明序列> → ε" << endl;
}
}
void mainkeyword() {
if (danci[cnt] == "main") {
cnt++;
cout << "<main关键字> → main" << endl;
ff << "<main关键字> → main" << endl;
} else {
error();
}
}
void yufa() {
cout << endl << "****************************" << endl;
cout << "========语法分析如下========" << endl;
cout << "****************************" << endl;
cout << endl;
ff << endl << "****************************" << endl;
ff << "========语法分析如下========" << endl;
ff << "****************************" << endl;
cnt = 0;//从0开始
if (danci[cnt] == "main") {//若等于main,则进入下一步分析
cout << "<程序> → <main关键字>(){<声明序列><语句序列>}" << endl;
ff << "<程序> → <main关键字>(){<声明序列><语句序列>}" << endl;
mainkeyword();
if (danci[cnt] == "(") {//匹配左括号(
cnt++;
if (danci[cnt] == ")") {//匹配右括号(
cnt++;
if (danci[cnt] == "{") {//匹配左大括号{
cnt++;
if (danci[cnt] == "int") {
shengmingxulie();//匹配int,进入声明序列分析
yujuxulie();//进入语句序列分析
if (danci[cnt] == "}") {
cnt++;//匹配左大括号}
} else {//语法错误,抛出错误信息
error();
}
} else {//语法错误,抛出错误信息
error();
}
} else {//语法错误,抛出错误信息
error();
}
} else {//语法错误,抛出错误信息
error();
}
} else {//语法错误,抛出错误信息
error();
}//语法错误,抛出错误信息
} else {
error();
}
}
..........待续
后续代码,私信联系,不免费
整体代码基本完善,有些功能未全能覆盖,在此作出声明!!!
标签:cnt,语法分析,int,词法,编译,&&,------,danci,编译程序 From: https://blog.csdn.net/qq_63933556/article/details/139334959