📄 1.cpp
字号:
/*
PLX词法分析程序
2007.11.4
*/
#include<stdio.h>
#include "2.h"
#define SYMBOLNUM 12//单个运算符个数
#define KEYNUM 18 //关键字个数
#define MAXNOBIT 50 //数字的最大位数
/**************************************************************************************/
//关键字表
char keywords[KEYNUM][KEYNUM]={
"and",
"begin",
"do",
"else",
"end",
"false",
"if",
"integer",
"logical",
"not",
"or",
"program",
"repeat",
"then",
"true",
"until",
"while",
"write",
};
//符号表(单个)
char symbol1[SYMBOLNUM]={'*' , '/' , '(' , ')' ,
'+' , '-' , '=' , ',' ,
'<' , '>' , '.' , ';' ,
};
//符号表(组合)
char symbol2[10][3]={ "<=" , ">=" , "/=" ,":=" };
//输出格式
struct out
{
int type1;//关键字1 数字2 标识符3 运算符4
int type2;//小类 只能用int 可能会超过9
char name[12];//数字以外的(字符串形式)
int value;//数字的值
int lineno;//行号
//int column;
};
/**************************************************************************************/
void fengxi(char *buf,//保存读入的一行
char* symbol,//符号表
int num,//该行的字符数
int lineno,//行号
FILE *fp//输出文件
);
int isakey(char *token);
int isasymbol2(char *token);
void output(int type1,int type2,char *name,int value,int lineno,FILE *fp);
int chartonum(char *number,int len);
/**************************************************************************************/
int main()
{
FILE *fp1;//源程序
FILE *fp2;//生成程序
int lineno=0;
int num=0;
if((fp1=fopen("源代码.txt","r"))==NULL)
{
printf("不能打开源文件\n");
return 0;
}//if
if((fp2=fopen("词法分析结果.txt","w"))==NULL)
{
printf("不能打开文件\n");
return 0;
}//if
while(num!=-1)
{
char buf[50];//保存读入的一行
num=getline(buf,fp1,'\n');
if(num>0)
{
//printf("L%d ",lineno);//打印行号
putline(buf,num);
lineno++;
fengxi(buf,symbol1,num,lineno,fp2);
printf("\n");
}//if
}//while
fclose(fp1);
fclose(fp2);
return 0;
}//main
void fengxi(char *buf,char* symbol,int num,int lineno,FILE *fp)
{
char c=' ';//保存取道的字符
char NULLL[32]=" ";//表示数字的name属性
int value=0;//数字的值
int tn=0;//数字的位数(字符串形式)
char token[32];//保存token
int ti=0;//token count
char number[MAXNOBIT];//数字的最大位数
int state=-1;// 0 标识符 1 常数 2运算符 -1非法字符 4字符
int type2;//保存关键字,运算符的编号
for(int i=0;i<num;)
{
ti=0;
value=0;
int j;//临时变量
char m[2]=" ";//保存单个运算符
state=-1;
c=buf[i];
tn=0;
type2=-1;
//token初始化
for(j=0;j<32;j++)
token[j]=' ';
//number初始化
for(j=0;j<50;j++)
number[j]=' ';
//挑砖部分
if(c=='\'') state=4;
else if(isaletter(c)||c=='_') state=0;
else if(isanumber(c)) state=1;
else if(c==' '||c==9){i++;continue;}//9是TAB
else state=2;
//else if(isasymbol(c,symbol)) state=2;
//跳转后的处理部分
switch(state)
{
case 0://标识符
while(isaletter(c)||isanumber(c)||c=='_')
{
if(i==num)break;
token[ti++]=c;
c=buf[++i];
}//while
token[ti]='\0';
if(isakey(token)!=-1)
{
type2=isakey(token);
output(1,type2,token,0,lineno,fp);//关键字
}//if
else
{
output(3,1,token,0,lineno,fp);//标识符
}//else
break;//case 0
case 1://常数
{
tn=0;
while(isanumber(c))
{
if(i==num)break;
number[tn++]=c;
c=buf[++i];
}
number[tn]='\0';
value=chartonum(number,tn);
output(2,1,NULLL,value,lineno,fp);
break;//case 1
}
case 2://运算符
//二元运算符
{
char local[3];
local[0]=c;
local[1]=buf[i+1];
if(isasymbol2(local)!=-1)
{
type2=isasymbol2(local);
local[2]='\0';
output(4,type2,local,0,lineno,fp);
i=i+2;
break;
}
}
i++;
m[0]=c;
m[1]='\0';
if(isasymbol(c,symbol)!=-1)
{
output(5,isasymbol(c,symbol),m,0,lineno,fp);
}
else
{
output(6,1,m,value,lineno,fp);//非法字符
}
break;
case -1://非法字符
i++;
output(5,1,NULLL,value,lineno,fp);
break;
}//switch
}//for
}
/**************************************************************************************/
int isakey(char *token)
{
for(int i=0;i<KEYNUM;i++)
if(strncmp(keywords[i],token,strlen(keywords[i]))==0)return i;
return -1;
}
int isasymbol2(char *token)
{ for(int i=0;i<4;i++)
if(strncmp(symbol2[i],token,strlen(symbol2[i]))==0)return i;
return -1;
}
void output(int type1,int type2,char *name,int value,int lineno,FILE *fp)
{
out output1;
output1.type1=type1;
output1.type2=type2;
//strcmp(output1.name,name);
for(int i=0;i<strlen(name);i++)
output1.name[i]=name[i];
for(;i<11;i++)
output1.name[i]=' ';
output1.name[11]='\0';
output1.value=value;
output1.lineno=lineno;
fwrite(&output1,sizeof(output1),1,fp);
fprintf(fp,"\n");
printf("%d %d %s %d %d",output1.type1,output1.type2,output1.name,output1.value,output1.lineno);
printf("\n");
// printf(" 关键字 行%d\n",lineno);
// fprintf(fp," 关键字 行%d\n",lineno);
}
int chartonum(char *number,int len)
{
int value=number[0]-'0';
for(int i=1;i<len;i++)
value=value*10+(number[i]-'0');
return value;
}
/*
思路
关键字P187
数字
标识符 (变量,过程名)
其他符号 (组合 单个)
输出格式
大类 小类 名称 值
int int char[12] int
*/
/*
2008.11.4
改进 输出的统一格式 写成函数 不再是分散到各处
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -