该程序模拟小型词法分析器,读入的文件从in.txt。输出到 out.txt 。对输入的程序做如下转化:
如果是关键字 象 void ,if,while 这些,。如果不是关键字,这考虑是否为标志符。
同样其他的象运算符,分界符,分别输出到out.txt文件。
假设in.txt中为 :
#include<stdio.h>
#include<stdlib.h>
int main()
{
int a,b;
float c,d;
return 0;
}
out.txt中应为(# , sign)
(include , identifier)
(< , op)
(stdio , identifier)
(. , seprator)
(h , identifier)
(> , op)
(# , sign)
(include , identifier)
(< , op)
(stdlib , identifier)
(. , seprator)
(h , identifier)
(> , op)
(int , keyword)
(main , identifier)
(( , seprator)
() , seprator)
({ , seprator)
(int , keyword)
(a , identifier)
(, , seprator) 等 等,当然该程序还存在好多不足与缺陷,
现在我想问的问题是,为什么in.txt中如果 内容很多的话会出现 调试窗口, 内容很少时不会出现 。内存为512M,跟内存应该没多大关系吧。。。麻烦哪位知道的 帮帮忙,谢了。
请回复到邮箱zhangyou1010@126.com ,QQ382973481 非常感谢。
同时祝您 新年快乐!
#include<iostream>
#include<fstream>
#include<string.h>
#include<stdlib.h>
using namespace std;
bool iskeyword(char *str); //为关键字
bool is_digit(char ch); //判断是否为数字
bool is_letter(char ch ); //判断字母
bool is_identifier(char *type); //为标志符
bool is_operator(char ch); //运算符
bool is_seprator(char ch); //分界符
char getstr(fstream & src); //读入一个字符
char get(fstream src) ; //读入空格符
// 判断是否为关键字
bool iskeyword(char *str)
{
bool b = false; //做标记用
char *key[]=
{"true","break","case","char","const","continue","default","do","double",
"else","false","extern","float","for","goto","if","int","long","register",
"return","short","signed","sizeof","static","struct","switch","typedef",
"union","unsigned","void","volatile","while","printf"};//C语言所有关键字
for(int i=0;i<33;i++)
{
if(strcmp(key[i],str)==0)
{
b=true;
break;
}
}
return b;
}
//判断是否为数字
bool is_digit(char ch)
{
if('0'<=ch&&ch<='9')
return true;
else return false;
}
//判断字母
bool is_letter(char ch )
{
if('a'<=ch&&ch<='z'||'A'<=ch&&ch<='Z')
return true;
else return false;
}
//运算符
bool is_operator(char ch)
{
if(strchr("+-*/%><=",ch))
return true;
else false;
}
//分界符
bool is_seprator(char ch)
{
if(strchr(";:'{},.()",ch))
return true;
else return false;
}
//读入下一个字符
char getstr(ifstream &src)
{
char c;
src.get(c);
return c;
}
// 读入空格
char get(ifstream &src)
{
char c=' ';
src.get(c);
while(c==' ')
src.get(c);
return c;
}
// 光标后退一个字符
void back(ifstream& src)
{
src.seekg(-1, ios::cur);
}
//分析函数
void lex(ifstream &src, ofstream &dst)
{
char ch,token[10],*temp;
int i=0;
src.get(ch);
while(ch==' ')
src.get(ch);
if(is_letter(ch))//判断为关键字形式或标志符
{
while(isalpha(ch)||is_digit(ch)||ch=='_')
{
token[i++]=ch;
ch=getstr(src);
}
temp=new char[i];
memcpy(temp,token,i);
temp[i]='\0';
back(src);
if(iskeyword(temp)) dst<<"("<<temp<<" , "<<"keyword"<<")"<<endl;
else dst<<"("<<temp<<" , "<<"identifier"<<")"<<endl;
}
//判断为整数或实数形式
else if(is_digit(ch))
{
while(is_digit(ch)||ch=='.')
{
token[i++]=ch;
ch=getstr(src);
}
temp=new char[i+1];
memcpy(temp,token,i);
temp[i]='\0';
back(src);
dst<<"("<<temp<<" , "<<"num"<<")"<<endl;
}
//判断字符串的情况
else if(ch=='\"')
{ src.get(ch);
if(ch=='%')
{
token[i++]=ch;
src.get(ch);
while(ch!='\"')
{
token[i++]=ch;
src.get(ch);
}
temp=new char[i+1];
memcpy(temp,token,i);
temp[i]='\0';
back(src);
dst<<"("<<temp<<" , "<<"convert"<<")"<<endl;
}
else
{
token[i++]=ch;
while(ch!='\"')
{
src.get(ch);
token[i++]=ch;
}
temp=new char[i+1];
memcpy(temp,token,i);
temp[i]='\0';
back(src);
dst<<"("<<temp<<" , "<<"string"<<")"<<endl;
}
}
//消除注释
else if(ch=='/')
{if((ch=getstr(src))=='/')
while(ch!='\n') ch=getstr(src);
}
//判断单目运算符情形
else if(is_operator(ch))
{
dst<<"("<<ch<<" , "<<"op"<<")"<<endl;
}
//为分界符情形
else if(is_seprator(ch))
{
dst<<"("<<ch<<" , "<<"seprator"<<")"<<endl;
}
else if(ch=='#')
dst<<"("<<ch<<" , "<<"sign"<<")" <<endl;
else if(ch=='~')
dst<<"("<<ch<<" , "<<")"<<"sign" <<endl;
else if(ch=='!')
dst<<"("<<ch<<" , "<<")"<<"sign" <<endl;
else if(ch=='$')
dst<<"("<<ch<<" , "<<"sign"<<")" <<endl;
else if(ch==' ') while(ch==' ') src.get(ch);
else if(ch=='\n') ;
else dst<<"error"<<endl;
}
int main()
{
ifstream src("in.txt",ios::in);
ofstream dst("Result.txt",ios::out);
if(!src) cout<<"can't open the file !"<<endl;
else {
cout<<"******************************词法分析器***********************************"<<endl;
while(!src.eof())
lex(src,dst);
dst.close();
src.close();
cout<<"The Program running success !"<<endl;
}
return 0;
}