/*参考程序源代码和测试数据 */
#include <iostream>
#include <fstream>
#include <cstring>
#define BMaxlen 10000 //定义缓冲区的最大长度
#define WMaxlen 11 //用来定义取出的标识符的最大长度,如果长度大于这个值,则接下去的字忽略不计
#define KEY_No 8 //定义要比较的关键字的个数
#define Sign_No 12 //定义要比较的符号的个数
#define Limit_No 6 //定义要比较的界符的个数
#define Maxtype '5' //定义单词的总类型共有5种
#define Longtype '8' //定义单词不合法且过长时的类型
#define Errtype '7' //定义单词不合法但没超过长度的类型
int scanner();//用来从缓冲区中取一个字符
void insource();//用来把文件中的内容放到缓冲区中
char getsym();//从缓冲区中取一个单词
using namespace std;
char Str[BMaxlen];//建立缓冲区
char Filename[100];//定义存放路径名的字符串
int pStr=-1; //用来表示从缓冲区取字母时的指针,定义为-1,为使以下的程序++pStr可以先指到缓冲区的第一个字母
char ch; //用来表示从缓冲区中取出的一个字母
char *KEY[KEY_No]={{"if"},{"int"},{"for"},{"while"},{"do"},{"return"},{"break"},{"continue"}};
char *Sign[Sign_No]={{"+"},{"-"},{"*"},{"/"},{"%"},{"="},{"<"},{">="},{"<="},{"!="},{"=="},{">"}};
char *Limit[Limit_No]={{","},{";"},{"{"},{"}"},{"("},{")"}};
int Fbuffer;//标志缓冲区中是否还有字母,如果没有的话,则Fbuffer的值为-1;如果还有的话,则其值为1
char Word[WMaxlen];//用来标识标识取出的单词,且其长度不超过
char CType;//用来标识得到的单词的类型
char Lasttype;//用来标识是其前面的单词的类型,如果是
char ty;//定义在调用取单词后取出的单词的类型
int scanner()//用来从缓冲区中取一个字符,如果成功,则返回1,否则为-1
{
ch=Str[++pStr];
if (ch=='\0') return(-1);//当取出的字符是'\0',则表明缓冲区中已无字符,返回值为-1
else return(1);
}
void insource()//用来把文件中的内容放到缓冲区中,以'\0'作为标识符
{
int i=0;//用来表示放入缓冲区数组的指针
char c; //表示从文件中读取的一个字符
fstream infile(Filename);//根据输入的路径名来打开这个文件
while (infile.get(c))
Str[i++]=c;
Str[i]='\0'; //以'\0'作为标识符
}
char getsym()//从缓冲区中取一个单词
{
bool flag=false;//用来表示取出的单词是否为关键词,如果是则flag的值为true,否则为false
int k=-1; //表示取出的字符放在单词数组的指针
CType='0'; //预先定义的取出的单词的类型
Lasttype='0'; //初始化先前的类型,此变量为判断正负数用
while (ch<=32 && ch>0)//去掉不能显示的字符
Fbuffer=scanner();