📄 c语言词法分析.cpp
字号:
//源代码文件: test.txt;
//分析结果存放文件: output.txt
#ifndef _GLOBAL_H
#define _GLOBAL_H
#include <stdio.h>
#include <ctype.h>
#include <string>
using namespace std;
#define MAX 6 //分析表的最大容量
#define MAXBUF 255
char ch =' ';// 存放读入当前的输入字符
int lineno = 1;//程序行数
struct entry{
const char *lexptr; //关键字表中的结构
int token;
};
struct entry symtable[MAX];//分析表
static string str[] = {"main","if","else","for","void","int","printf"};//关键字
#endif
void init()//初始化符号表
{
struct entry* p = symtable;
int j=0;
for(j=0;j<6;j++)
{
p->lexptr=str[j].c_str();
p->token=j+3;
p++;
}
}
//判断一个字符是否为数字
bool IsDigit(char ch)
{
return(ch>='0'&&ch<='9');
}
//判断一个字符是否确为字母
bool IsAlpha(char ch)
{
return (ch>='a'&&ch<='z'||ch>'A'&&ch<'Z');
}
/******************************************************************
功能:在关键字表中查找与arr相同的关键字
找到就返回类别编码,否则返回0
*******************************************************************/
int FindOK(char* arr)
{
for(int i=0;i<sizeof(symtable)/sizeof(symtable[0]);++i)
{
if(!strcmp(symtable[i].lexptr,arr))
{
return symtable[i].token;
}
}
return 0;
}
/********************************************************************
以下为主分析函数
从输入文件里面读,把分析结果写到输出文件中
参数 fpin : 输入文件指针
fpout: 输出文件指针
********************************************************************/
void parse(FILE* fpin,FILE* fpout)
{
char arr[MAXBUF];
char line[MAXBUF];
int position = 0;
int i=0;
int j=0;
bool begin = true;
bool finished = false;
while(!feof(fpin))
{
if(finished)
break;
if(begin)
{
fgets(line, MAXBUF-1, fpin); //从程序中读入一行代码
fprintf(fpout,"line %d:\n", lineno);
begin = false;
position = 0;
}
ch = line[position++];//把这行的一个字符赋给ch
if( ch==' '||ch=='\t')//消去空格
;
else if(ch=='\n')//消去Enter
{
lineno++;
begin = true;
}
else if(IsDigit(ch))//检查字符是否为数字
{
while(IsDigit(ch)) //区分数字由单个字符还是多个字符构成
{
arr[j] = ch;
j++;
ch = line[position++];
}
position--; //文件指针后退一步
char* temp1 =(char*)malloc(j+1);
memcpy(temp1,arr,j);
temp1[j] ='\0';//把数组里面的内容拷贝到外一个数组里面,因为定义的arr为255个字节,
j=0; //实际上写不到那么多,所以只拷贝实际上有数据的
//fprintf(fpout,"%s\t\t%d\n",temp1,2);//恢复初始状态,以备下次使用
free(temp1);//释放内存
}
else if(IsAlpha(ch))//是字母开头的
{
while(IsAlpha(ch)||IsDigit(ch))
{
arr[i] = ch;
i++;
//fscanf(fpin,"%c",&ch);
ch = line[position++];
}
//fseek(fpin,-1L,SEEK_CUR);
position--; //文件指针后退一步
char* temp = (char*)malloc(i+1);
memcpy(temp,arr,i);
temp[i] ='\0';
i=0;
/*基本思想同处理数字的*/
if(FindOK(temp))//查表
{
fprintf(fpout,"%s\t%d\n",temp,FindOK(temp));
}
else
{ continue;
//fprintf(fpout,"%s\t%d\n",temp,1);//标示符号
}
free(temp);
}
//以下为2字节的运算符号
else if( ch==':')
{
//fscanf(fpin,"%c",&ch);
ch = line[position++];
if(ch=='=')
fprintf(fpout,"%s\t%d\n",":=",20);
else
fprintf(fpout,"error in compileing %d lines unknown character %c \n",lineno,ch);//出错处理
}
else if(ch=='>')
{
//fscanf(fpin,"%c",&ch);
ch = line[position++];
if(ch=='=')
fprintf(fpout,"%s\t%d\n",">=",16);
else
fprintf(fpout,">\t15\n");
}
else if(ch=='<')
{
//fscanf(fpin,"%c",&ch);
ch = line[position++];
if(ch=='=')
{fprintf(fpout,"<=\t18\n");}
else if(ch=='>')
{fprintf(fpout,"<>\t19");}
else
{fprintf(fpout,"<\t19\n");}
}
else {
//以下为一个字节的运算符号
if(ch=='{') {fprintf(fpout,"{\t\t24\n");continue;}
if(ch=='}') {fprintf(fpout,"}\t\t25\n");continue;}
if(ch=='-') {fprintf(fpout,"-\t\t10\n");continue;}
if(ch==';') {fprintf(fpout,";\t\t21\n");continue;}
if(ch=='+') {fprintf(fpout,"+\t\t9\n");continue;}
if(ch=='*') {fprintf(fpout,"*\t\t11\n");continue;}
if(ch=='/') {fprintf(fpout,"/\t\t12\n");continue;}
if(ch=='(') {fprintf(fpout,"(\t\t13\n");continue;}
if(ch==')') {fprintf(fpout,")\t\t14\n");continue;}
if(ch=='.') {fprintf(fpout,".\t\t22\n");continue;}
if(ch==',') {fprintf(fpout,",\t\t23\n");continue;}
if(ch=='#') break;//分析结束
else continue;
}
}
}
//主函数
int main()
{
char filenamein[50],filenameout[50];
printf("************************************************\n");
printf("* C 语言子集词法分析程序 *\n");
printf("************************************************\n");
printf("请输入测试代码文件地址(例:c:\\test.txt): \n"); //注意代码中必须为双斜杠,而在输入时是单斜杠
scanf("%s",filenamein);
printf("请输入输出目标文件地址(例:c:\\output.txt): \n");
scanf("%s",filenameout);
FILE* fpin = fopen(filenamein,"r"); //定义源代码文件为只读
if(fpin==NULL)
{
printf("不能打开代码文件!");//出错操作
getchar();
return 0;
}
FILE* fpout = fopen(filenameout,"w");
if(fpout==NULL)
{
printf("不能打开结果文件!");
getchar();
return 0;
}
init();
parse(fpin,fpout);//扫描需分析文件并输出分析结果
fclose(fpin);//关闭源代码
fclose(fpout); //关闭结果文件
printf("OK..........\n");
getchar();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -