//添加头文件
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include <string.h>
//变量声明
FILE *fp;
char cbuffer,cbuffer_next; // cbuffer_next记录下一字符
const char *key[29]={"main","int","if","else","for","while","do","return","break","continue","float","double","char","void","long","short"
,"switch","case","default","goto","auto","static","register","extern","struct","union","enum","typedef","sizeof"}; //1.加入其他关键字
int atype,id=4;
const char* space_word_table[11] = { ",",";","(",")","[","]","{","}",".","\"","#"}; //2.加入界限符
const char* maths_calcu_table[12] = { "+","-","*","/","++","--","+=","-=","*=","/=","<<",">>"}; //3.加入运算符
const char* relation_calcu_table[7] = {"<","<=",">",">=","=","<>","=="}; //4.加入关系符
//函数声明
char alphaprocess(char buffer);
int search(char searchchar[ ],int wordtype);
char digitprocess(char buffer);
char otherprocess(char buffer);
int isKeyWord(char *buffer);
char operatorProcess(char buffer);
bool isOperator(char buffer);
char calcuProcess(char buffer);
bool isCalcu(char buffer);
//void 改int
int main()
{
//fopen函数需要加入#include<stdio.h>
if ((fp=fopen("example2.c","r"))==NULL)
printf("error"); //NULL宏没有被声明
else
{
cbuffer = fgetc(fp); // 从指定的文件流中读取一个字符
while (cbuffer!=EOF)
{
if(cbuffer==' '||cbuffer=='\n'||cbuffer== '\t') // 5.忽略空格、制表符(新加)和换行符
cbuffer=fgetc(fp);
else if(isalpha(cbuffer)) //处理标识符和关键字
cbuffer = alphaprocess(cbuffer);
else if(isdigit(cbuffer)) //处理常数
cbuffer = digitprocess(cbuffer);
else if(isOperator(cbuffer)) //处理关系运算符
cbuffer = operatorProcess(cbuffer);
else if(isCalcu(cbuffer))//处理算术运算符
cbuffer = calcuProcess(cbuffer);
else //处理分隔符和其他符号
cbuffer = otherprocess(cbuffer);
}
}
fclose(fp);//
return 0;
}
//判断关键字,是返回1和i(i是key位置,从1开始),否则标识符则返回2
char alphaprocess(char buffer)
{ int atype; /*保留字数组中的位置*/
int i=-1;
char alphatp[20];
while ((isalpha(buffer))||(isdigit(buffer))||buffer=='_')//如果buffer是字母数字or下划线,则放入 alphatp字符数组
{
alphatp[++i]=buffer;
buffer = fgetc(fp); // 从指定的文件流中读取一个字符
}
alphatp[i+1]='\0';// alphatp字符数组结尾加空字符,确保单词在被正确识别。
atype=search(alphatp,1);/*对此单词调用search函数判断类型*/
if(atype!=0)
{ printf("(\"%s\", 1, %d)\n",alphatp,atype);
id=1; }
else
{ printf("(\"%s\", 2)\n",alphatp);
id=2; }
return buffer; //返回buffer值
}
//该函数的返回值为整型变量p,用于表示判断结果。
//关键字顺序key返回1,2,3...,否则返回0
int search(char searchchar[ ],int wordtype)
{
int i=0;
int p;
switch (wordtype)
{
case 1:for (i=0;i<=28;i++)
{
if (strcmp(key[i],searchchar)==0)
{ p=i+1; break; }
else p=0;
}
return(p);
}
}
//输出数字类 ,3
char digitprocess(char buffer) {
int i = -1, flag = 0;
char digittp[20];
if (buffer == '+' || buffer == '-') { // 6.判断正负数
digittp[++i] = buffer;
buffer = fgetc(fp);
}
while (isdigit(buffer) || buffer == '.' || buffer == 'e' || buffer == 'E' || buffer == '+' || buffer == '-') {//7. 科学计数法
if (buffer == '.' || buffer == 'e' || buffer == 'E') {//8.浮点数
flag = 1;
digittp[++i] = buffer;
} else if (buffer == '+' || buffer == '-') {
if (flag == 1) {
digittp[++i] = buffer;
}
} else {
digittp[++i] = buffer;
}
buffer = fgetc(fp);
}
digittp[i + 1] = '\0';
if (flag == 1) {
printf("(\"%s\", 3)\n", digittp);
id = 3;
} else {
printf("(\"%s\", 3)\n", digittp);
id = 3;
}
return buffer;
}
//输出标识符
char otherprocess(char buffer)
{
char ch[20];
ch[0]=buffer;
ch[1]='\0';
//9.限界符加入[],:,#
if(ch[0]==','||ch[0]==';'||ch[0]=='{'||ch[0]=='}'||ch[0]=='('||ch[0]==')'||ch[0]=='['||ch[0]==']'||ch[0]=='#'||ch[0]==':')
{ printf("(\"%s\", 5)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);}
//10.加入取余+-%|^& ch[0]=='+'||ch[0]=='-'||
if(ch[0]=='*'||ch[0]=='/'||ch[0]=='%'||ch[0]=='|'||ch[0]=='&'||ch[0]=='~'||ch[0]=='^')
{ printf("(\"%s\", 4)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(ch[0]=='='||ch[0]=='!'||ch[0]=='<'||ch[0]=='>')
{ buffer=fgetc(fp);
if(buffer=='=')//小于等于,大于等于
{ ch[1]=buffer;
ch[2]='\0';
printf("(\"%s\", 4)\n",ch);
}
else
{ printf("(\"%s\", 4)\n",ch);
id=4;
return(buffer);
}
buffer=fgetc(fp);
id=4;
return(buffer);
}
if(ch[0]=='+'||ch[0]=='-')
{ if(id==4) /*在当前符号以前是运算符,则此时为正负号*/
{ buffer=fgetc(fp);
ch[1]=buffer;
ch[2]='\0';
printf("(\"%s\", 3)\n",ch);
id=3;
buffer=fgetc(fp);
return(buffer);
}
ch[1]='\0';
printf("(\"%s\", 4)\n",ch);
buffer=fgetc(fp);
id=4;
return(buffer);
}
}//增加"}"
char operatorProcess(char buffer){
char operate[10];
for(int i = 0;i<10;i++){
operate[i] = '\0';
}
int j = 0;
while ((isOperator(buffer))){
//假如后面都是关系运算符,则一直加入,直到后面不是关系运算符为止
operate[j]=buffer;
j++;
buffer=fgetc(fp);
}
//检查该操作符是否在预设的符号之中
for (int i = 0;i<7;i++){
if(strcmp(operate,relation_calcu_table[i])==0){
printf("(\"%s\" ,关系运算符)\n",operate);//如果是关系符,就输出
return buffer;
}
}
return buffer;
}
bool isOperator(char buffer){
return buffer=='>' || buffer=='<' || buffer =='=';
}
bool isCalcu(char buffer){
return buffer=='+' || buffer=='-'|| buffer=='*'|| buffer=='/'|| buffer=='=';
}
char calcuProcess(char buffer){
//用来处理算术运算符
char calcu[5];
//首先清除数组的内容
for(int i = 0;i<5;i++){
calcu[i] = '\0';
}
int i = 0;
while ((isCalcu(buffer))){
//假如后面都是算术运算符,则一直加入,直到后面不是算术运算符为止
calcu[i]=buffer;
i++;
buffer=fgetc(fp);
}
//11.检查是否是注释
int flag = true;
for(int i = 0;i < 2;i++){
//如果calcu的前两位都是//,说明从buffer开头的字符到最近的一个换行符内,都是注释
if(calcu[i]!='/'){
flag = false;
}
}
if(flag){
//说明是注释
char note[50];//支持的最长长度为50
for(int i =0 ;i<50;i++){
//首先将note数组全部置为'\0'
note[i] = '\0';
}
int i = 0;
while(buffer!='\n'){
note[i]=buffer;
i++;
buffer=fgetc(fp);
}
printf("(\"%s\",注释) \n",note);
return buffer;
}
//检查该操作符是否在预设的符号之中
for (int i = 0;i<10;i++){
if(strcmp(calcu,maths_calcu_table[i])==0){
printf("(\"%s\" ,算术运算符)\n",calcu);//如果是算术符,就输出
return buffer;
}
}
return buffer;
}