编译原理实验报告一
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
洛阳理工学院实验报告
本次实验比较复杂,通过查阅网上资料并且修改完成了本次的实验,此次实验难度在于修改的问题,每一个字符都对应一个数字。
这次实验最大的收获就是掌握了词法分析器的实现。
也让我又熟悉了一遍C语言的相关内容。
对编译原理这门课有了
#include<conio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int i, row = 0, line = 0;
char a[1000]; //程序
int number[1000][100]; //常数表
char mark[100][5]; //标识符表
char buffer[100];
//保存文件
void savefile(FILE *fp1,char outfile[15])
{
fp1 = fopen(outfile, "a+");
fseek(fp1, 0, SEEK_END);
fwrite(buffer, strlen(buffer), 1, fp1);
fclose(fp1);
}
//词法分析
int wordanalysis(FILE *fp1,char outfile[15])
{
if ((a[i] >= 'A'&&a[i] <= 'Z')||(a[i]>='a'&&a[i]<='z')) //分析标识符和关键字
{
char word[10];
char pro[100][100] = {"if","else","int","char","for","while","do",
"return","break","continue","double","float"}; //13个关键字表
int n = 0;
word[n++] = a[i++];
//若字符为A~Z或0~9,则继续读取
while ((a[i] >= 'A'&&a[i] <= 'Z') ||(a[i]>='a'&&a[i]<='z')|| (a[i] >= '0' && a[i] <= '9'))
{
word[n++] = a[i++];
}
word[n] = '\0';
i--;
//判断该标识符是否为关键字
for (n = 0; n < 100; n++)
{
if (strcmp(word, pro[n]) == 0)
{
sprintf(buffer,"(%d,%s) 关键字\n",n+1,pro[n]);
savefile(fp1,outfile);
printf("(%d,%s) 关键字\n", n + 1,pro[n]);
return 3;
}
}
//判断标识符长度是否超出规定
if (strlen(word)>10)
{
sprintf(buffer,"%s\tERROR\n",word);
savefile(fp1,outfile);
printf("%s\tERROR\n",word);
return 0;
}
//判断该标识符是否存在标识符表中
int m = 0;
if (line != 0)
{
int q = 0; //标识符编号
while (q<line)
{
if (strcmp(word, mark[q++]) == 0)
{
sprintf(buffer,"(14,%s) 标识符\n", word);
savefile(fp1,outfile);
printf("(14,%s) 标识符\n", word);
return 3;
}
}
}
//将该标识符保存到标识符表中
strcpy(mark[line], word);
sprintf(buffer,"(14,%s) 标识符\n", word);
savefile(fp1,outfile);
printf("(14, %s) 标识符\n", word);
line++;
return 3;
}
else if (a[i] >= '0' && a[i] <= '9') //分析常数,单词种别码是14 {
char x[100];
int n = 0;
double sum;
x[n++] = a[i++];
//判断字符是否是0~9
while (a[i] >= '0' && a[i] <= '9')
{
x[n++] = a[i++];
}
x[n] = '\0';
i--;
int num = atoi(x); //将字符串转换成int型
//判断该常数是否存在于常数表中
if (row != 0)
{
int y; //常数编号
for (y = 0; y < 1000; y++)
{
int w = number[y][0];
sum = 0;
int d;
for (d = 1; d <= number[y][0]; d++)
{
w = w - 1;
sum = sum + number[y][d] * pow(2, w);
}
if (num == sum)
{
sprintf(buffer,"(15,%d) 常数\n", num);
savefile(fp1,outfile);
printf("(15,%d) 常数\n", num);
return 3;
}
}
}
int z = num, c = num;
int m = 0;
do //计算是几位二进制数
{
z = z / 2;
m++;
} while (z != 0);
for (n = m; n > 0; n--) //将二进制保存于常数表中
{
number[row][n] = c % 2;
c = c / 2;
}
number[row][0] = m;
int line = row;
sprintf(buffer,"(15,%d) 常数\n", num);
savefile(fp1,outfile);
printf("(15,%d) 常数\n", num, line + 1);
row++;
return 3;
}
else //分析符号
switch (a[i])
{
case ' ':
case '\n': return -1;
case '#': return 0;
//分析运算符+:16; -:17; *:18; /:19; =:20; <:21; >:22; <=:23; >=:24; !=:25 case '+':if(1==1){
sprintf(buffer,"(16,+) 运算符\n");
savefile(fp1,outfile);
printf("(16,+)\t运算符\n"); return 3;}
case '-':if(1==1){
sprintf(buffer,"(17,-) 运算符\n");
savefile(fp1,outfile);
printf("(17,-)\t运算符\n"); return 3;}
case '*':if(1==1){
sprintf(buffer,"(18,-) 运算符\n");
savefile(fp1,outfile);
printf("(18,*)\t运算符\n"); return 3;}
case '=':if(1==1){
sprintf(buffer,"(20,=) 运算符\n");
savefile(fp1,outfile);
printf("(20,=)\t运算符\n"); return 3;}
case '/':
i++;
if(a[i]!='/'){
i--;
if(1==1){
sprintf(buffer,"(19,/) 运算符\n");
savefile(fp1,outfile);
printf("(19,/)\t运算符\n"); return 3;}
}
else{
while(1){
if(a[i++]=='\n')
return -1;
}
if(1==1){
sprintf(buffer,"(41,//)\n");
savefile(fp1,outfile);
printf ("(41,//)\t界符\n");return 3;}
}
case '<':
case '>':
case '<=':
case '>=':
case '!=':
i++;
if(a[i] == '<')
{
if(1==1){
sprintf(buffer,"(21,<) 运算符\n");
savefile(fp1,outfile);
printf("<>(21,<)\t运算符\n");
return 3;}
}
else if (a[i] == '>')
{
if(1==1){
sprintf(buffer,"(22,>) 运算符\n");
savefile(fp1,outfile);
printf("<>(22,>)\t运算符\n");
return 3;}
}
else if (a[i] == '<=')
{
if(1==1){
sprintf(buffer,"(23,<=) 运算符\n");
savefile(fp1,outfile);
printf("<>(23,<=)\t运算符\n");
return 3;}
}
else if (a[i] == '>=')
{
if(1==1){
sprintf(buffer,"(24,>=) 运算符\n");
savefile(fp1,outfile);
printf("<>(24,>=)\t运算符\n");
return 3;}
}
else if (a[i] == '!=')
{
if(1==1){
sprintf(buffer,"(25,!=) 运算符\n");
savefile(fp1,outfile);
printf("<>(25,!=)\t运算符\n");
return 3;}
}
else
{
printf("<>(ERROR)\n");
return 0;
}
//分析界符
case '(':if(1==1){
sprintf(buffer,"(26,() 界符\n");
savefile(fp1,outfile);
printf("(26,()\t界符\n"); return 3;} case ')':if(1==1){
sprintf(buffer,"(27,)) 界符\n");
savefile(fp1,outfile);
printf("(27,))\t界符\n"); return 3;} case '{':if(1==1){
sprintf(buffer,"(28,{) 界符\n");
savefile(fp1,outfile);
printf("(28,{)\t界符\n"); return 3;} case '}':if(1==1){
sprintf(buffer,"(29,}) 界符\n");
savefile(fp1,outfile);
printf("(29,})\t界符\n"); return 3;} case '[':if(1==1){
sprintf(buffer,"(30,[) 界符\n");
savefile(fp1,outfile);
printf("(30,[)\t界符\n"); return 3;} case ']':if(1==1){
sprintf(buffer,"(31,]) 界符\n");
savefile(fp1,outfile);
printf("(31,])\t界符\n"); return 3;} case '|':if(1==1){
sprintf(buffer,"(32,|) 界符\n");
savefile(fp1,outfile);
printf("(32,|)\t界符\n"); return 3;} case '"':if(1==1){
sprintf(buffer,"(33,\") 界符\n");
savefile(fp1,outfile);
printf("(33,\")\t界符\n"); return 3;} case ',':if(1==1){
sprintf(buffer,"(34,,) 界符\n");
savefile(fp1,outfile);
printf("(34,,)\t界符\n"); return 3;} case '\'':if(1==1){
sprintf(buffer,"(35,') 界符\n");
savefile(fp1,outfile);
printf("(35,')\t界符\n"); return 3;}
case ';':if(1==1){
sprintf(buffer,"(36,;) 界符\n");
savefile(fp1,outfile);
printf("(36,;)\t界符\n"); return 3;}
case ':':if(1==1){
sprintf(buffer,"(37,:) 界符\n");
savefile(fp1,outfile);
printf("(37,:)\t界符\n"); return 3;}
case '&':
i++;
if(a[i]!='&'){
i--;
if(1==1){
sprintf(buffer,"(38,&) 界符\n");
savefile(fp1,outfile);
printf("(38,&)\t分隔符\n"); return 3;}
}
else{
if(1==1){
sprintf(buffer,"(39,&&) 界符\n");
savefile(fp1,outfile);
printf("(39,&&)\t分隔符\n");return 3;} }
case '\\':if(1==1){
sprintf(buffer,"(40,\\) 界符\n");
savefile(fp1,outfile);
printf("(40,\\)\t界符\n"); return 3;} }
return 0;
}
int main()
{
int l = 0;
int m;
i = 0;
FILE *fp,*fp1;
char infile[15],outfile[15]; //定义输入和输出文件名printf("输入需要扫描的文件名\n");
scanf("%s",infile);
printf("输入需要另存为的文件名\n");
scanf("%s",outfile);
if((fp = fopen(infile,"r")) == NULL) //打开需要扫描的文件
{
printf("cannot open file\n");
exit(0);
}
if((fp1 = fopen(outfile,"w")) == NULL) //打开需要存入的文件{
printf("cannot open file\n");
exit(0);
}
printf ("\n");
while (!feof(fp))
{
a[l++] = fgetc(fp);
}
a[l] = '#';
do
{
m = wordanalysis(fp1,outfile);
switch (m)
{
case -1:i++; break;
case 0: i++; break;
case 3: i++; break;
}
} while (m != 0);
_getch();
return 0;
}。