📄 词法分析.txt
字号:
#include<iostream.h>
#include<string.h>
#include<ctype.h>
const int maxsize=500;//输入程序的总容量
struct table
{
char keyword[20];
int no;
};
struct table tab[37]={{"and",1},{"begin",2},{"bool",3},{"do",4},{"else",5},{"end",6},{"false",7},{"if",8},
{"integer",9},{"not",10},{"or",11},{"program",12},{"real",13},{"then",14},{"true",15},
{"var",16},{"while",17},{"标识符",18},{"整数",19},{"实数",20},{"(",21},{")",22},{"+",23},
{"-",24},{"*",25},{"/",26},{".",27},{",",28},{":",29},{";",30},{":=",31},{"=",32},
{"<=",33},{"<",34},{"<>",35},{">",36},{">=",37}
};//关键字表
struct table1
{
char word[20];
};
struct table1 stab[50];//符号表
struct table1 ctab[50];//常数表
int slen=0,clen=0; //记录符号表长度,和常数表长度
/*-------------------------------------------------*/
char getchar(char s[],int &i)
{
return s[++i];
}
/*-------------------------------------------------*/
char getbc(char s[],int &i)
{
char ch;
ch=s[i];
while(ch==' '||ch=='\r')
ch=s[++i];
return ch;
}
/*-------------------------------------------------*/
void concat(char s[],char ch)
{
int i;
i=strlen(s);//cout<<i<<endl;
s[i]=ch;//cout<<s<<endl;
}
/*-------------------------------------------------*/
void concat1(char s[],char ch)
{
for(int i=0;s[i];i++)
s[i]=ch;
s[++i]='\0';
}
/*-------------------------------------------------*/
int reserve(char s[])//返回字符串中关键字编码 否则返回0
{
for(int i=0;i<37;i++)
{
if(strcmp(s,tab[i].keyword)==0)//串比较
return tab[i].no;
}
return 0;
}
/*-------------------------------------------------*/
char retract(char s[],int &i)//回调一个字符位置
{
return s[--i];
}
/*-------------------------------------------------*/
char pretract(char s[],int &i)//后退一个字符位置
{
return s[++i];
}
/*-------------------------------------------------*/
int insertid(char s[])
{
for(int i=0;i<slen;i++)
{
if(strcmp(stab[i].word,s)==0) return i+1;//查找标识符在符号表中的位置
}
strcpy(stab[i].word,s);//将标识符插到符号表中
slen++;
return i+1;
}
/*-------------------------------------------------*/
int insertconst(char s[])//常数表
{
for(int i=0;i<clen;i++)
{
if(strcmp(ctab[i].word,s)==0) return i+1;
}
strcpy(ctab[i].word,s);
clen++;
return i+1;
}
/*-------------------------------------------------*/
void scan(char s[],int &i)
{
int code,value;//分别代表机内码和入口地址
//static int value=1;
static int no=0;//代表输入序列
char strtoken[10]="";
char ch;
ch=getchar(s,i);
ch=getbc(s,i);
if(isalpha(ch))//当变元为字母表中的字母时,函数返回非0值,否则返回0.
{
while(isalpha(ch)||isdigit(ch))//变元为字母或数字均可
{
concat(strtoken,ch);
ch=getchar(s,i);
//cout<<ch<<endl;
}
ch=retract(s,i);//2状态退回一个字符
code=reserve(strtoken);
if(code==0)
{
no++;
value=insertid(strtoken);
cout<<"<"<<no<<"\t "<<strtoken<<"\t 18\t "<<' '<<value<<"\t >"<<endl;
}
else
{
no++;
cout<<"<"<<no<<"\t "<<strtoken<<"\t "<<code<<"\t-1\t >"<<endl;
}
}
else if(isdigit(ch))//当变元为数字时
{
while(isdigit(ch))
{
concat(strtoken,ch);
ch=getchar(s,i);
}
if(isalpha(ch))
{
cout<<"第"<<++no<<"个符号是非法的以数字开头的字母串!"<<endl;
cout<<"正确的格式如下:"<<endl;
ch=retract(s,i);
value=insertconst(strtoken);
cout<<"<"<<no<<"\t "<<strtoken<<"\t 19\t "<<value<<"\t >"<<endl;
}
else
{
if(ch='.')
{
concat(strtoken,ch);
ch=getchar(s,i);
while(isdigit(ch))
{
concat(strtoken,ch);
ch=getchar(s,i);
}
if(ch='.')
ch=retract(s,i);
value=insertconst(strtoken);
no++;
cout<<"<"<<no<<"\t "<<strtoken<<"\t 20\t "<<value<<"\t >"<<endl;
}
else
{
no++;
ch=retract(s,i);
value=insertconst(strtoken);
cout<<"<"<<no<<"\t "<<strtoken<<"\t 19\t "<<value<<"\t >"<<endl;
}
}
}
else if(ch=='(')
{
no++;
cout<<"<"<<no<<"\t "<<"(\t 21\t -1\t>"<<endl;
}
else if(ch==')')
{
no++;
cout<<"<"<<no<<"\t "<<")\t 22\t-1\t >"<<endl;
}
else if(ch=='+')
{
no++;
cout<<"<"<<no<<"\t "<<"+\t 23\t-1\t >"<<endl;
}
else if(ch=='-')
{
no++;
cout<<"<"<<no<<"\t "<<"-\t 24\t-1\t >"<<endl;
}
else if(ch=='*')
{
no++;
cout<<"<"<<no<<"\t "<<"*\t 25\t-1\t >"<<endl;
}
else if(ch=='/')
{
no++;
cout<<"<"<<no<<"\t "<<"/\t 26\t-1\t >"<<endl;
}
else if(ch=='.')
{
no++;
cout<<"<"<<no<<"\t "<<".\t 27\t-1\t >"<<endl;
}
else if(ch==',')
{
no++;
cout<<"<"<<no<<"\t "<<",\t 28\t-1\t >"<<endl;
}
else if(ch==':')
{
no++;
cout<<"<"<<no<<"\t "<<":\t 29\t-1\t >"<<endl;
}
else if(ch==';')
{
no++;
cout<<"<"<<no<<"\t "<<";\t 30\t-1\t >"<<endl;
}
else if(ch==':=')
{
no++;
cout<<"<"<<no<<"\t "<<":=\t 31\t-1\t >"<<endl;
}
else if(ch=='=')
{
no++;
cout<<"<"<<no<<"\t "<<"=\t 32\t-1\t >"<<endl;
}
else if(ch=='<=')
{
no++;
cout<<"<"<<no<<"\t "<<"<=\t 33\t-1\t >"<<endl;
}
else if(ch=='<')
{
no++;
cout<<"<"<<no<<"\t "<<"<\t 34\t -1\t>"<<endl;
}
else if(ch=='<>')
{
no++;
cout<<"<"<<no<<"\t "<<"<>\t 35\t-1\t >"<<endl;
}
else if(ch=='>')
{
no++;
cout<<"<"<<no<<"\t "<<">\t 36\t-1\t >"<<endl;
}
else if(ch=='>=')
{
no++;
cout<<"<"<<no<<"\t "<<">=\t 37\t-1\t >"<<endl;
}
else
cout<<"此处输入错误!"<<endl;
}
/*-------------------------------------------------*/
void main()
{
int i=0,num=0,len;
char buf[maxsize];
cout<<"请输入程序代码(以!结束):"<<endl;
cin.unsetf(ios::skipws);
cin>>buf[num];
while(buf[num]!='!'&&num<maxsize)
{
num++;
cin>>buf[num];
}
len=num;
cout<<len<<endl;
cout<<endl<<"词法分析如下:"<<endl;
cout<<"输入序列"<<" 单词"<<"\t 机内码"<<"\t入口地址"<<endl;
i=-1;
/*while(i<len-2)
{
scan(buf,i);
}*/
scan(buf,i);
while(i<len-2)//排除文件最后一位
{
if((buf[i]=' ')&&(i<len-2))
{
scan(buf,i);
}
else if((buf[i]='\r')&&(i<len-2))//此处回车有问题
{
scan(buf,++i);
}
else i++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -