下面的代码是摸爬滚打出来的,不一定完全正确(不过确实可以找出test语言里的9处错误哈)。
Test语言:
{
int a;
int i;
int 2b;
int c
for (i=1; i <= 10 i=i+1)
{
;
a=a+i
b=b*i;
{
c=a+b;
}
while(x<=)
{
C=a+b+(x*y;
if (a>b)
{
read a;
}
else
{
write b+5;
}
write c
}
语法分析代码(包含词法分析):
#include<stdio.h>
#include<ctype.h>
#include <conio.h>
#include<string.h>
#include<iostream>
#define keywordSum 7
#include<stdlib.h>
using namespace std;
char *keyword[keywordSum] = {"if","else","for","while","int","write","read"};
char words1[50] = "+-*(){};,:";
char words2[10] = "><=!";
char Scanin[300],Scanout[300];
char buffer1[20], buffer2[40]; //存放每个单词的类型和内容
FILE *fin,*fout;
FILE *fp; //用于语法分析时进行单词的依次读取
//以下是各个函数的定义,包括词法分析函数,语法分析的入口,语法分析的每个产生式的函数。
int TESTparse();
int program();
int compound_stat();
int statement();
int arithmetic_exprerrsion();
int assignment_exprerrsion();
int assignment_stat();
int bool_exprerrsion();
int term();
int factor();
int if_stat();
int while_stat();
int for_stat();
int write_stat();
int read_stat();
int declaration_stat();
int declaration_list();
int statement_list();
int compound_stat();
int TESTscan();
int main(){
int err=0; //错误代码
err=TESTscan(); //词法分析
if(err>0)
{
cout<<"词法分析出现错误!"<<endl;;
}
else
{
cout<<"词法分析完成!"<<endl;
err = TESTparse(); //语法分析
if(err>0){
cout << "语法分析出错!"<<endl;
} else cout << "分析完成!"<<endl;
}
return 0;
}
declaration_stat(){
int err = 0;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "ID")) return(err = 3);
if (err > 0) return(err);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, ";")) return(err = 4);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
return(err);
}
declaration_list()
{
int err = 0;
while (strcmp(buffer1, "int") == 0)
{
err = declaration_stat();
if (err > 0) return(err);
}
return(err);
}
statement()
{
int err = 0;
if (err == 0 && strcmp(buffer1, "if") == 0)
err = if_stat();
if (err == 0 && strcmp(buffer1, "while") == 0)
err = while_stat();
if (err == 0 && strcmp(buffer1, "for") == 0)
err = for_stat();
if (err == 0 && strcmp(buffer1, "read") == 0)
err = read_stat();
if (err == 0 && strcmp(buffer1, "write") == 0)
err = write_stat();
if (err == 0 && strcmp(buffer1, "{") == 0)
err = compound_stat();
if (err == 0 && (strcmp(buffer1, "ID") == 0 || strcmp(buffer1, "NUM") == 0 || strcmp(buffer1, "(") == 0))
err = assignment_stat();
if (err == 0 && strcmp(buffer1,";")==0)
{
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
return err;
}
return(err);
}
statement_list()
{
int err = 0;
//cout << "statement_list"<<endl;
while(strcmp(buffer1, "}"))
{
err = statement();
if (err > 0) return(err);
}
// cout<<"statement_list:out"<<buffer1<<endl;
return(err);
}
if_stat(){
int err = 0; //if
// cout<<"if_stat"<<endl;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "("))
return(err = 5);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = bool_exprerrsion();
if (err > 0)
return(err);
if (strcmp(buffer1, ")"))
return(err = 6);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = statement();
if (err > 0) return(err);
if (strcmp(buffer1, "else") == 0)
{
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = statement();
if (err > 0) return(err);
}
return(err);
}
while_stat()
{
int err = 0;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "("))
return(err = 5);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = bool_exprerrsion();
if (err > 0)
return(err);
if (strcmp(buffer1, ")"))
return(err = 6);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = statement();
if (err > 0)
return(err);
return(err);
}
for_stat(){
int err = 0;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "("))
return(err = 5);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = assignment_exprerrsion();
if (err > 0)
return(err);
if (strcmp(buffer1, ";"))
return(err = 4);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = bool_exprerrsion();
if (err > 0)
return(err);
if (strcmp(buffer1, ";"))
return(err = 4);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = assignment_exprerrsion();
if (err > 0)
return(err);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = statement();
if (err > 0)
return(err);
return(err);
}
read_stat()
{
int err = 0, addrerrs;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "ID"))
return(err = 3);
if (err > 0)
return(err);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, ";"))
return(err = 4);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
return(err);
}
write_stat(){
int err = 0;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = arithmetic_exprerrsion();
if (err > 0)
return(err);
if (strcmp(buffer1, ";"))
return(err = 4);
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
return(err);
}
compound_stat(){
int err = 0;
// cout << "in"<<endl;
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
// cout << buffer2<<endl;
err = statement_list();
if(err>0)
return(err);
// fpp = fp;
// int chs = fgetc(fpp);
// if(chs == EOF)
// {
// return (2);
// }
if(fscanf(fp, "%s %s\n", &buffer1, &buffer2)>0){
printf("%s %s\n", buffer1, buffer2);
}
else{
return 2;
}
// cout << "out" <<endl;
return (err);
}
assignment_exprerrsion()
{
int err = 0;
if (strcmp(buffer1,"ID"))
return err=3;
if (err > 0)return err;
fscanf(fp,"%s %s\n",&buffer1,&buffer2);
printf("%s %s\n", buffer1, buffer2);
//cout << buffer1 << endl;
if (strcmp(buffer1,"="))
return err =11; //期待一个等号
fscanf(fp,"%s %s\n",&buffer1,&buffer2);
printf("%s %s\n", buffer1, buffer2);
//cout<<buffer2<<endl;
err = arithmetic_exprerrsion();
if (err > 0)return err;
return err;
}
assignment_stat(){
int err = 0;
err = assignment_exprerrsion();
// cout << buffer2<<endl;
// cout << err ;
if (err > 0)
return (err);
if (strcmp(buffer1,";"))
return err =4; //期待一个分号
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
return err;
}
bool_exprerrsion(){
int err=0;
err=arithmetic_exprerrsion();
if(err>0)
return(err);
if(strcmp(buffer1,">")==0 || strcmp(buffer1,">=")==0
|| strcmp(buffer1,"<")==0 || strcmp(buffer1,"<=")==0
|| strcmp(buffer1,"==")==0 || strcmp(buffer1,"!=")==0)
{
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
err=arithmetic_exprerrsion();
if(err>0)
return(err);
}
return(err);
}
arithmetic_exprerrsion(){
int err=0;
err=term();
if(err>0)
return(err);
while(strcmp(buffer1,"+")==0 || strcmp(buffer1,"-")==0)
{
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
err=term();
if(err>0)
return(err);
}
return(err);
}
term(){
int err=0;
err=factor();
if(err>0)
return(err);
while(strcmp(buffer1,"*")==0 || strcmp(buffer1,"/")==0)
{
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
err=factor();
if(err>0)
return(err);
}
return(err);
}
factor()
{
int err=0;
// cout<<buffer1<<endl;
if(strcmp(buffer1,"(")==0)
{
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
err=arithmetic_exprerrsion();
if(err>0)
return(err);
if(strcmp(buffer1,")"))
return(err=6);
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
}else
{
if(strcmp(buffer1,"ID")==0)
{
if(err>0)
return(err);
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
return(err);
}
if(strcmp(buffer1,"NUM")==0)
{
fscanf(fp,"%s %s\n",buffer1,&buffer2);
printf("%s %s\n",buffer1,buffer2);
return(err);
}else
{
err=7;
return(err);
}
}
return(err);
}
program(){
int err = 0, i;
fscanf(fp, "%s %s\n", buffer1, buffer2);
printf("%s %s\n", buffer1, buffer2);
if (strcmp(buffer1, "{")) //以读到{为入口 而且必须以{为起始
{
err = 1;
return(err);
}
fscanf(fp, "%s %s\n", &buffer1, &buffer2);
printf("%s %s\n", buffer1, buffer2);
err = declaration_list();
if (err > 0)
return(err);
err = statement_list();
if (err>0)
return(err);
if (strcmp(buffer1, "}")) //} 为结束
{
err = 2;
return(err);
}
int chs = fgetc(fp); //若结束后还有内容,则为冗余
if(chs != EOF)
{
return 9;
}
return(err);
}
TESTparse(){
int err = 0;
if ((fp = fopen(Scanout, "r")) == NULL) //读词法分析的结果用于语法分析
{
printf("\n打开%s错误!\n", Scanout);
err = 8;
return(err);
}
if (err == 0) err = program();
printf("==语法、语义分析及代码生成程序结果==\n");
switch (err)
{
case 0: printf("语法分析成功!\n"); break;
case 1: printf("缺少{!\n"); break;
case 2: printf("缺少}!\n"); break;
case 3: printf("缺少标识符!\n"); break;
case 4: printf("少分号!\n"); break;
case 5: printf("缺少(!\n"); break;
case 6: printf("缺少)!\n"); break;
case 7: printf("缺少操作数!\n"); break;
case 8: printf("打开文件 %s失败!\n", Scanout); break;
case 9:printf("尾部有多余!\n");break;
case 11:printf("期待一个=!\n");break;
}
fclose(fp);
fclose(fout);
return(err);
}
TESTscan(){
char ch, buffer1[40];
int err = 0, j, n;
printf("请输入源程序文件名(包括路径):");
scanf("%s", Scanin);
printf("请输入词法分析输出文件名(包括路径):");
scanf("%s", Scanout);
if ((fin = fopen(Scanin, "r")) == NULL)
{
printf("\n打开词法分析输入文件出错!\n");
return(1);
}
if ((fout = fopen(Scanout, "w")) == NULL)
{
printf("\n创建词法分析输出文件出错!\n");
return(2);
}
ch = getc(fin);
while (ch != EOF)
{
while (ch == ' ' || ch == '\n' || ch == '\t') ch = getc(fin);
if (ch == EOF) break;
if (isalpha(ch))
{
buffer1[0] = ch; j = 1;
ch = getc(fin);
while (isalnum(ch))
{
buffer1[j++] = ch;
ch = getc(fin);
}
buffer1[j] = '\0';
n = 0;
while ((n < keywordSum) && strcmp(buffer1, keyword[n])) n++;
if (n >= keywordSum)
fprintf(fout, "%s\t%s\n", "ID", buffer1);
else
fprintf(fout, "%s\t%s\n", buffer1, buffer1);
}
else if (isdigit(ch))
{
buffer1[0] = ch; j = 1;
ch = getc(fin);
while (isdigit(ch))
{
buffer1[j++] = ch;
ch = getc(fin);
}
buffer1[j] = '\0';
fprintf(fout, "%s\t%s\n", "NUM", buffer1);
}
else if (strchr(words1, ch) > 0)
{
buffer1[0] = ch; buffer1[1] = '\0';
ch = getc(fin);
fprintf(fout, "%s\t%s\n", buffer1, buffer1);
}
else if (strchr(words2, ch) > 0)
{
buffer1[0] = ch;
ch = getc(fin);
if (ch == '=')
{
buffer1[1] = ch; buffer1[2] = '\0';
ch = getc(fin);
}
else
buffer1[1] = '\0';
fprintf(fout, "%s\t%s\n", buffer1, buffer1);
}
else if (ch == '/')
{
ch = getc(fin);
if (ch == '*')
{
char ch1;
ch1 = getc(fin);
do
{
ch = ch1; ch1 = getc(fin);
}
while ((ch != '*' || ch1 != '/') && ch1 != EOF);
ch = getc(fin);
}
else
{
buffer1[0] = '/'; buffer1[1] = '\0';
fprintf(fout, "%s\t%s\n", buffer1, buffer1);
}
}
else
{
buffer1[0] = ch; buffer1[1] = '\0';
ch = getc(fin);
err = 3;
fprintf(fout, "%s\t%s\n", "ERROR", buffer1);
}
}
fclose(fin);
fclose(fout);
return(err);
}
修改好了后的test语言:
{
int a;
int i;
int b;
int c;
int x;
int y;
int C;
for (i=1; i <= 10; i=i+1)
{
;
a=a+i;
b=b*i;
{
c=a+b;
}
while(x<=y)
{
C=a+b+(x*y);
if (a>b)
{
read a;
}
else
{
write b+5;
}
write c;
}
}
}
貌似不太符合理论要求哈。
好了,祝各位学业顺利