#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fstream>
#include <math.h>
using namespace std;
//相关结构体
struct words //每个单词作为一个结构体,其中code为种别码,本结构体在整个编译过程中最为重要
{
int code;
int num;
words *next;
};
words *wordshead,*wordstail;
struct str //把单词作为字符串的结构体
{
int num;
str *next;
string word;
};
str *strhead,*strtail;
struct product //文法产生式结构体
{
char left;
string right;
int length;
};
product formular[22];
struct pank //action表的结构体
{
char sr;
int state;
};
pank action[51][22]; //action表
int go_to[51][12]; //goto表
struct analyze //语法分析栈结构体,每个结点有前后指针
{
analyze *pre;
int num; //状态
int word; //符号编码
analyze *next;
};
analyze *analyzehead,*analyzetail;
struct L //语义四元式的数据结构
{
int k;
string op; //操作符
string op1; //操作数
string op2; //操作数
string result;//结果
L *next; //语义四元式向后指针
L *Ltrue; //回填true链向前指针
L *Lfalse; //回填false链向前指针
};
L *Lfourhead,*Lfourtail,*Ltruehead,*Lfalsehead;/*四元式链,true链,false链*/
struct symbolList//语义输入时符号表
{
string word;//变量名称
int addr;//变量地址
symbolList *next;
};
symbolList *symbolhead,*symboltail;//语义符号链表
//~~~~~~~~~~~~~~~词法分析相关函数声明
void outdaima();
void scan();//按字符读取源文件
void lexical();//词法分析主程序
int judgech(char ch);//判断输入字符的类型
void out1(char ch);// 写入words.txt
void out2(char ch,string word);
void out6(char ch,string word);//写入string.txt
void input1(words *temp);//插入结点到队列words
void input2(str *temp);//插入结点到队列string
void output();//输出三个队列的内容
void outfile();//输出三个队列的内容到相应文件中
//~~~~~~~~~~~~~~~~语法分析有关函数声明
void grammerMain();//语法分析主程序
void grammerInitialize();//初始化语法分析数据结构
int grammerSLR1(int a);//语法分析主体部分
int ID1(int a);//给输入字符编号,转化成action表列编号
string ID10(int i);//给输入字符反编号
int ID2(char ch);//给非终结状态编号,转化成go_to表列编号
int ID20(char ch);//给非终结状态编号
char ID21(int j);//给非终结状态反编号
void addToAnalyze(analyze *temp);//给analyze分析栈链表增加一个结点
void DELETE();//给ike分析栈链表删除一个结点
//~~~~~~~~~~~~~~~~语义分析有关函数声明
void meaningMain(int x);
void addToL_four(L *temp);
void addToSymList(symbolList *temp);//向语义符号表链中加一个结点
void addToLtrue(L *temp);
void addToLfalse(L *temp);
void outputMeaning();
string numToString(int m);//把数字变成字符串
string numToName(int num);//把编号转换成相应的变量名
int lookup(string m);//变量声明检查
//~~~~~~~~~~~~~~~~~~目标代码生成的函数
void asmLanguage();
//~~~~~~~~~~~~~~~~~全局变量的声明
FILE *fp;//文件指针
int wordCount;//标志符计数
int error;//标志词法分析结果正确或错误
int line;//读取行数
int yuyi_linshi;//语义临时变量
string E_name,H_name,K_name,G_name,id_name,id1_name,id2_name,errword;//用于归约时名称传递和未声明变量的输出
int id_num,id1_num,id2_num,id_left,id_then,id_else,G19;//用于记录一些特殊的字符位置信息
int main()
{
cout<<"1.词法分析 "<<endl;
cout<<"2.语法分析 "<<endl;
cout<<"3.语义分析及中间代码生成"<<endl;
cout<<"4.目标代码生成"<<endl;
lexical();
grammerMain();
outputMeaning();
asmLanguage();
cout<<endl;
system("pause");
return(0);
}
//////////////////////词法分析程序
void lexical()
{
wordshead=new words;
wordshead->next=NULL;
wordstail=new words;
wordstail->next=NULL;
strhead=new str;
strhead->next=NULL;
strtail=new str;
strtail->next=NULL;
Lfourhead=new L;
Lfourhead->next=NULL;
Lfourhead->k=0;
Lfourtail=new L;
Lfourtail->k=0;
Lfourtail->next=NULL;
Ltruehead=new L;
Ltruehead->Ltrue=NULL;
Lfalsehead=new L;
Lfalsehead->Lfalse=NULL;
symbolhead=new symbolList;
symbolhead->next=NULL;
symboltail=new symbolList;
symboltail->next=NULL;
yuyi_linshi=-1;
id_num=0;
G19=0;
wordCount=0; //初始化字符计数器
error=0; //初始化词法分析错误标志
line=1; //初始化读取行数
scan();
if(error==0)
{
char input;
output();
cout<<" 词法分析完成!"<<endl<<endl<<" 将结果保存到文件中请输入y或Y,否则请输入其它字符:";
cin>>input;
cout<<endl;
if(input=='y'||input=='Y')
{
outfile();
cout<<" 结果成功保存在word.txt和sting.txt两个文件中"<<endl;
cout<<endl;
}
}
}
void scan()
{
cout<<endl;
system("pause");
cout<<endl;
char ch;
string word;
char local[21];
int flag=0;
cout<<" 请输入代码文件路径:";
cin>>local;
cout<<endl;
cout<<"* ------------------------ *"<<endl;
cout<<"* -- 1.词法分析 -- *"<<endl;
cout<<"* ------------------------ *"<<endl;
if((fp=fopen(local,"rt"))==NULL)
{
error=1;
cout<<" 无法找到该文件,请确认文件路径!"<<endl;
return;
}
while(!feof(fp))
{
word="";
ch=fgetc(fp);
flag=judgech(ch);
if(flag==1)
out1(ch);
else if(flag==2)
out2(ch,word);
else if(flag==3||flag==5||flag==7)
continue;
else if(flag==4)
{
line++;
continue;
}
else if(flag==6)
out6(ch,word);
else
{
cout<<line<<" 行 "<<" 错误:非法字符! "<<endl;
error=1;
exit(0);
}
}
fclose(fp);
}
int judgech(char ch)
{
int flag=0;
if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/'||ch==';'||ch==','||ch=='('||ch==')'||ch=='{'||ch=='}'||ch=='>'||ch=='$')
flag=1; //界符
else if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
flag=2; //字母(标识符或关键字)
else if(ch==' ')
flag=3; //空格
else if(ch=='\n')
flag=4; //换行符
else if(feof(fp))
flag=5; //输入$表示结束
else if(ch>='0'&&ch<='9')
flag=6;
else if(ch=='.')
flag=7;
else
flag=0;
return flag;
}
void out1(char ch)
{
int n;
switch(ch)
{
case '=': n=1;break;
case '+': n=2;break;
case '-': n=3;break;
case '*': n=4;break;
case '/': n=5;break;
case ';': n=6;break;
case ',': n=7;break;
case '(': n=8;break;
case ')': n=9;break;
case '{': n=10;break;
case '}': n=11;break;
case '>': n=12;break;
case '$': n=50;break;
default : n=0;
}
words *p;
p=new words;
p->code=n;
p->next=NULL;
p->num=-1;
input1(p);
return;
}
void out2(char ch,string word)
{
int n=0;
words *p=new words;
p->num=-1;
p->code=-1;
p->next=NULL;
str *q=new str;
q->next=NULL;
q->num=-1;
q->word="";
word+=ch;
ch=fgetc(fp);
n=judgech(ch);
if(n==1||n==2||n==3||n==4||n==5)
{
if(word=="int"||word=="double"||word=="float"||word=="main"||word=="if"||word=="then"||word=="else")
{
if(word=="int")
p->code=13;
else if(word=="double")
p->code=15;
else if(word=="float")
p->code=14;
else if(word=="main")
p->code=16;
else if(word=="if")
p->code=17;
else if(word=="then")
p->code=18;
else if(word=="else")
p->code=19;
input1(p);
if(n==1)
out1(ch);
else if(n==3||n==4||n==5)
return;
}
else if(n==1)
{
wordCount++;
p->code=22; //标识符的种别码
p->num=wordCount;
input1(p);
q->num=wordCount;
q->word=word;
input2(q);
out1(ch);
return;
}
else if(n==2)
- 1
- 2
前往页