📄 wordanalyst.cpp
字号:
#include<iostream.h>
#include<fstream.h>
#include<stdlib.h>
#include<string.h>
#include<iomanip.h>
#define Lenth 32
//变量类型
#define INTEGER 1
#define CHAR 2
#define BOOL 3
#define MAX 50
char* wordTable[61];
//--------------------------标识符链表:save token
struct Id{
char *value; //记录标识符的名字
int num; //记录常量的数值
int line; //line the token in
short sym;
short seq; //变量和常量的序列
Id *next;
};
Id *IdListHead=NULL; //链头
Id *IdListTail=NULL; //链尾
int TailNum=1; //记录自定义字符的序号
//重载加入链表的函数
//关键字或字符
void addIdList(Id*s){
if(IdListHead==NULL){
IdListHead=s;
IdListTail=s;
}
else{
IdListTail->next=s;
IdListTail=s;
}
}
//自定义变量
void addIdList(Id* s,int &seq){
if(IdListHead==NULL){
seq=TailNum;
s->seq=TailNum++;
IdListHead=s;
IdListTail=s;
}
else{
seq=TailNum++;
s->seq=seq;
IdListTail->next=s;
IdListTail=s;
}
}
//查找自定义变量是否已存在
short searchIdList(Id **s,int &seq,char *A){
if(IdListHead==NULL){
return 0;
}
else{
Id *p=new Id;
p=IdListHead;
for(seq=1;p&&strcmp(p->value,A)!=0;p=p->next,seq++);
if(p==NULL) return 0;
else{
*s=p;
return 1;
}
}
}
//--------------------------------------初始变量
void iniWordTable(){
int i=0;
for(;i<61;i++){
wordTable[i]=new char[10];
wordTable[i]=" ";
}
wordTable[1]="and";
wordTable[2]="array";
wordTable[3]="begin";
wordTable[4]="bool";
wordTable[5]="call";
wordTable[6]="case";
wordTable[7]="char";
wordTable[8]="constant";
wordTable[9]="dim";
wordTable[10]="do";
wordTable[11]="else";
wordTable[12]="end";
wordTable[13]="false";
wordTable[14]="for";
wordTable[15]="if";
wordTable[16]="input";
wordTable[17]="integer";
wordTable[18]="not";
wordTable[19]="of";
wordTable[20]="or";
wordTable[21]="output";
wordTable[22]="procedure";
wordTable[23]="program";
wordTable[24]="read";
wordTable[25]="real";
wordTable[26]="repeat";
wordTable[27]="set";
wordTable[28]="stop";
wordTable[29]="then";
wordTable[30]="to";
wordTable[31]="true";
wordTable[32]="until";
wordTable[33]="var";
wordTable[34]="while";
wordTable[35]="write";
wordTable[39]="(";
wordTable[40]=")";
wordTable[41]="*";
wordTable[42]="*/";
wordTable[43]="+";
wordTable[44]=",";
wordTable[45]="-";
wordTable[46]=".";
wordTable[47]="..";
wordTable[48]="/";
wordTable[49]="/*";
wordTable[50]=":";
wordTable[51]=":=";
wordTable[52]=";";
wordTable[53]="<";
wordTable[54]="<=";
wordTable[55]="<>";
wordTable[56]="=";
wordTable[57]=">";
wordTable[58]=">=";
wordTable[59]="[";
wordTable[60]="]";
}
//-----------------------------------------词法分析程序
int wordAnalyst(){
int work=1; //工作变量,当发生错误时work=0;
ifstream rwfile;
// while(cin){
// cout<<"------------------------------"<<endl;
cout<<"请输入你要进行词法分析的文件。退出请输入:exit。"<<endl;
char* src=new char[20]; //指定文件
cin>>src;
if(strcmp(src,"exit")==0){
rwfile.close();
return 0;
}
if(IdListHead!=NULL||IdListTail!=NULL){
delete IdListHead;
IdListHead=NULL;
IdListTail=NULL;
TailNum=1;
}
work=1;
cout<<"File opening..."<<endl;
rwfile.open(src);
if(!rwfile){
cout<<"File open error!"<<endl;
exit(0);
}
else { cout<<"File has been open."<<endl;}
for(int l=1; !rwfile.eof();l++){ //l存储行数
char *line=new char[50];
rwfile.getline(line,50);
int chars=0,zsCount=0,dyCount=0; //字符数与注释对齐数,单引号对齐数
//处理该行
while(line[chars]!=0){
for(;line[chars]==' '||line[chars]==9;chars++) ; //滤掉空格或tab
//----------------------------------------------------------------数字
while(line[chars]>='0'&&line[chars]<='9'&&line[chars]!=0){
char *A=new char[Lenth]; //记录错误的单词
int num=0; //记录常量的数值
for(int k=0;line[chars]!=' '&&line[chars]>='0'&&line[chars]<='9'&&line[chars]!=0;k++,chars++){
A[k]=line[chars]; //记录值
num=num*10+line[chars]-'0';
}
if(line[chars]!=' '&&line[chars]!=0){
//如果数字后面跟的不是单界符,则是非法单词
if(line[chars]<39||line[chars]>47&&line[chars]<58||line[chars]>62&&line[chars]<91||line[chars]>93){
for(;line[chars]!=' '&&line[chars]!=0&&line[chars]<39||line[chars]>47&&line[chars]<58||line[chars]>62&&line[chars]<91||line[chars]>93;k++,chars++){
A[k]=line[chars];
}
A[k]='\0';
cout<<"第"<<l<<"行: 非法单词:"<<A<<endl;
work=0;
}
}
if(line[chars]>=0){
A[k]='\0';
Id *s=new Id;
int seq; //用于重载addIdList函数
if(searchIdList(&s,seq,A)){ //寻找是否已存在该标识符或整数或字符常数
delete A; //删除临时量
Id *p=new Id; //添加新节点
p->next=NULL;
p->value=s->value;
p->num=num;
p->sym=s->sym;
p->seq=s->seq;
p->line=l; //save line the token in
addIdList(p);
}
else{
s->next=NULL;
s->sym=37;
s->num=num;
s->value=new char[Lenth];
strcpy(s->value,A);
delete A;
s->line=l;
addIdList(s,seq);
}
if(line[chars]==0)break;
}
for(;line[chars]==' '||line[chars]==9;chars++); //滤掉空格或tab
}
//------------------------------------------------------------------字母
while((line[chars]>='A'&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z')){
char *A=new char[Lenth];
//字母和数字
for(int k=0; line[chars]!=0 && line[chars]!=' '&& ((line[chars]>='A'&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z')||line[chars]>='0'&&line[chars]<='9');k++,chars++){
A[k]=line[chars]; //记录值
}
if(line[chars]>=0){
A[k]='\0';
Id *s=new Id;
int seq;
//搜索链表
if(searchIdList(&s,seq,A)){
delete A; //删除临时量
Id *p=new Id;
p->next=NULL;
p->value=s->value;
p->sym=s->sym;
p->seq=s->seq;
p->line=l;
addIdList(p);
}
//搜索字符表
else{
for(int i=1;i<=60&&strcmp(A,wordTable[i]);i++);
if(i<=60){
s->next=NULL;
s->sym=i;
s->value=new char[Lenth];
strcpy(s->value,A);
s->line=l;
addIdList(s);
delete A; //删除临时量
}
else{
//加入链表
s->next=NULL;
s->sym=36;
s->value=new char[Lenth];
strcpy(s->value,A);
delete A; //删除临时量
s->line=l;
addIdList(s,seq);
}
}
if(line[chars]==0) break;
}
for(;line[chars]==' '||line[chars]==9;chars++);
//滤掉空格或tab
}
//modify:运算符可连续
//----------------------------------------------------------分界符
if(line[chars]!=0&&!((line[chars]>='0'&&line[chars]<='9')||(line[chars]>='A'
&&line[chars]<='Z')||(line[chars]>='a'&&line[chars]<='z'))){
//
//单引号------------------------------------------------------字符常数
if(line[chars]==39){
dyCount++; //单引号计数
char *A=new char[Lenth];
for(int k=0;line[chars]!=0&&line[++chars]!=39;k++){
A[k]=line[chars];
}
A[k]='\0';
if(line[chars]==39){
dyCount--;
chars++;
Id *s=new Id;
s->next=NULL;
s->sym=38;
s->line=l;
s->value=new char[Lenth];
strcpy(s->value,A);
delete A; //删除临时量
int seq;
addIdList(s,seq);
}
else{ delete A; break;}
for(;line[chars]==' '||line[chars]==9;chars++); //滤掉空格或tab
}
//-----------------------------------------------记录单界符
else{
char *A=new char[Lenth];
int w=1; //用来回填'/0'
A[0]=line[chars++];
if(A[0]==':'&&line[chars]=='=') {A[1]=line[chars++];w=0;}
if(A[0]=='/'&&line[chars]=='*') {A[1]=line[chars++];w=0;}
if(A[0]=='.'&&line[chars]=='.') {A[1]=line[chars++];w=0;}
if(A[0]=='<'&&line[chars]=='=') {A[1]=line[chars++];w=0;}
if(A[0]=='>'&&line[chars]=='=') {A[1]=line[chars++];w=0;}
if(A[0]=='<'&&line[chars]=='>') {A[1]=line[chars++];w=0;}
if(w) A[1]='\0';
else A[2]='\0';
if(line[chars]>=0){
for(int i=39;i<61&&strcmp(A,wordTable[i])!=0;i++);
if(i<61){
if(i==49){
//注释符计数,且过滤掉“/*” 符号和后面的所有信息
for(zsCount++;line[chars]!=0&&!(line[chars++]=='*'&&line[chars++]=='/'););
if(line[chars-2]=='*'&&line[chars-1]=='/') zsCount--;
}
else{
Id*p=new Id;
p->next=NULL;
p->sym=i;
p->value=new char[Lenth];
p->line=l;
strcpy(p->value,A);
addIdList(p);
}
}
else{
cout<<"第"<<l<<"行:非字符集定义的字符:"<<line[chars]<<endl;
if(line[chars]!=0) chars++;
work=0;
}
//end if
delete A;
if(line[chars]==0) break;
}
}
//end if
}
for(;line[chars]==' '||line[chars]==9;chars++); //滤掉空格或tab
}
if(zsCount!=0){ cout<<"第"<<l<<"行: 注释符匹配出错!"<<endl;work=0;}
if(dyCount!=0){ cout<<"第"<<l<<"行: 单引号匹配出错!"<<endl;work=0;}
delete line;
}
cout<<endl;
if(work){
//输出分析结果
Id *p=new Id;
p=IdListHead;
for(int i=0;p;i++,p=p->next){
if(i%5==0) cout<<endl;
if(p->sym!=36&&p->sym!=37&&p->sym!=38)
cout<<"("<<p->sym<<",-)"<<'\t';
else
cout<<"("<<p->sym<<","<<p->seq<<")"<<'\t';
}
// }
//end while
cout<<endl;
rwfile.close();
}
return work;
}
void main(int argc,char *argv[]){
cout<<"孙振华"<<'\t'<<"05级网络工程4班"<<'\t'<<"200530491317"<<endl;
iniWordTable(); //初始字符表
while(1){
wordAnalyst(); //词法分析正确则返回1,否则为0
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -