📄 sentenceanalyse.cpp
字号:
//all i wish is to dream again
#include "stdio.h"
#include"conio.h"
#include"stdlib.h"
#include"string.h"
#include"malloc.h"
FILE *fp,*out;
char ch,*token;
int alreadyread=0;
typedef struct word{
char name[10];
int id;
char value[10];
//word * next;
}wordnode;
wordnode *wordNode;
const int maxIndex=50;
/*
{0,0,0,0,0,0,0,1,0},
{0,0,0,0,0,0,0,1,0},
{2,2,0,0,2,2,2,1,0},
{2,2,0,0,2,2,2,1,0},
{2,2,0,0,0,0,2,1,0},
{2,2,0,0,0,0,2,1,0},
{2,2,2,2,2,2,2,2,3},
{0,0,0,0,0,0,0,0,1},
{2,2,2,2,2,2,2,2,0},
*/
int table[maxIndex][maxIndex];//0:error ,1:< ,2:> 3:=
void tableInit(){
int i,j;
for(i=0;i<maxIndex;i++)
for(j=0;j<maxIndex;j++)
table[i][j]=0;
//a
table[5][11]=2;table[5][14]=2;table[5][31]=2;table[5][32]=2;table[5][22]=2;table[5][33]=2;table[5][38]=3;
//b
table[6][11]=2;table[6][14]=2;table[6][31]=2;table[6][32]=2;table[6][22]=2;table[6][33]=2;
//+
table[31][5]=1;table[31][6]=1;table[31][22]=1;table[31][33]=1;table[31][10]=1;table[31][11]=2; table[31][14]=2;table[31][31]=2;table[31][31]=2;
//-
table[32][5]=1;table[32][6]=1;table[32][22]=1;table[32][33]=1;table[32][10]=1;table[32][11]=2; table[32][14]=2;table[31][31]=2;table[31][32]=2;
//*
table[22][5]=1;table[22][6]=1;table[22][10]=1;table[22][11]=2; table[22][14]=2;table[22][31]=2;table[22][32]=2;table[22][22]=2;table[22][33]=2;
///
table[33][5]=1;table[33][6]=1;table[33][10]=1;table[33][11]=2; table[33][14]=2;table[33][31]=2;table[33][32]=2;table[33][33]=2;table[33][22]=2;
//(
table[10][5]=1;table[10][6]=1;table[10][31]=1;table[10][32]=1;table[10][22]=1;table[10][33]=1;table[10][10]=1;table[10][11]=3;
//)
table[11][11]=2;table[11][14]=2;table[11][31]=2;table[11][32]=2;table[11][22]=2;table[11][33]=2;
//;
table[14][47]=2;
//=
table[38][5]=1;table[38][6]=1;table[38][31]=1;table[38][32]=1;table[38][22]=1;table[38][33]=1;table[38][10]=1;table[38][14]=3;
//$
table[47][5]=1;table[47][47]=3;
}
//退出程序
void exitPrograme(){
getch();
fclose(fp);
//fclose(out);
exit(0);
}
/**
初始化程序
获得输入文件指针和输出文件指针
*/
void Init(){
char filename[10];
printf("输入文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"r"))==NULL){
printf("canot open file\n");
exitPrograme();
}
/*
if((out=fopen("out.txt","a+"))==NULL){
printf("canot open file\n");
exitPrograme();
}
*/
}
//从文件中读一个字符
void getcharfromfile(){
if(!feof(fp)){//feof(fp)不移动指针 ;fgetc移动指针
if(alreadyread==1)alreadyread=0;
else ch=fgetc(fp);
}
else{
printf("no more input");
}
}
//把读出的字符与之前的相连接
void connect(){
int len=strlen(token);
realloc(token,len+2);
token[len]=ch;
token[len+1]='\0';
}
//获得一个单词
void getWord(){
token=(char *)malloc(sizeof(char));
do{
getcharfromfile();
if(feof(fp))return;
}while(ch==' ');
wordNode=(wordnode *)malloc(sizeof(wordnode));
wordNode->value[0]='\0';
//构造标示符 、关键字
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')){
while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')){
connect();
getcharfromfile();
}
alreadyread=1;
//关键字
if(!strcmp(token,"include")){wordNode->id=2;strcpy(wordNode->name,token);}
else if(!strcmp(token,"void")){wordNode->id=7;strcpy(wordNode->name,token);}
else if(!strcmp(token,"int")){wordNode->id=12;strcpy(wordNode->name,token);}
else if(!strcmp(token,"if")){wordNode->id=17;strcpy(wordNode->name,token);}
else if(!strcmp(token,"else")){wordNode->id=18;strcpy(wordNode->name,token);}
else if(!strcmp(token,"for")){wordNode->id=19;strcpy(wordNode->name,token);}
else if(!strcmp(token,"printf")){wordNode->id=20;strcpy(wordNode->name,token);}
else if(!strcmp(token,"scanf")){wordNode->id=21;strcpy(wordNode->name,token);}
else if(!strcmp(token,"sizeof")){wordNode->id=23;strcpy(wordNode->name,token);}
else if(!strcmp(token,"while")){wordNode->id=28;strcpy(wordNode->name,token);}
else if(!strcmp(token,"do")){wordNode->id=29;strcpy(wordNode->name,token);}
else if(!strcmp(token,"getch")){wordNode->id=30;strcpy(wordNode->name,token);}
else if(!strcmp(token,"main")){wordNode->id=37;strcpy(wordNode->name,token);}
else if(!strcmp(token,"char")){wordNode->id=45;strcpy(wordNode->name,token);}
//标示符
else{wordNode->id=5;strcpy(wordNode->name,"标示符");strcpy(wordNode->value,token);}
}
//构造整数
else if(ch>='0'&&ch<='9'){
while(ch>='0'&&ch<='9'){
connect();
getcharfromfile();
}
alreadyread=1;
wordNode->id=6;strcpy(wordNode->name,token);
}
//构造运算符、界符
else{
connect();
switch(ch){
case '+':
getcharfromfile();
if(ch=='+'){connect();wordNode->id=34;strcpy(wordNode->name,token);break;}
else{alreadyread=1;wordNode->id=31;strcpy(wordNode->name,token);break;}
case '-':
getcharfromfile();
if(ch=='-'){connect();wordNode->id=35;strcpy(wordNode->name,token);break;}
else{alreadyread=1;wordNode->id=32;strcpy(wordNode->name,token);break;}
case '#':wordNode->id=1;strcpy(wordNode->name,token);break;
case '"':wordNode->id=3;strcpy(wordNode->name,token);break;
case '%':wordNode->id=4;strcpy(wordNode->name,token);break;
case '{': wordNode->id=8;strcpy(wordNode->name,token);break;
case '}': wordNode->id=9;strcpy(wordNode->name,token);break;
case '(': wordNode->id=10;strcpy(wordNode->name,token);break;
case ')': wordNode->id=11;strcpy(wordNode->name,token);break;
case '&': wordNode->id=13;strcpy(wordNode->name,token);break;
case ';': wordNode->id=14;strcpy(wordNode->name,token);break;
case '[': wordNode->id=15;strcpy(wordNode->name,token);break;
case ']': wordNode->id=16;strcpy(wordNode->name,token);break;
case '*': wordNode->id=22;strcpy(wordNode->name,token);break;
case '<':
getcharfromfile();
if(ch=='='){connect();wordNode->id=25;strcpy(wordNode->name,token);break;}
else{alreadyread=1;wordNode->id=24;strcpy(wordNode->name,token);break;}
case '>':
getcharfromfile();
if(ch=='='){connect();wordNode->id=27;strcpy(wordNode->name,token);break;}
else{alreadyread=1;wordNode->id=26;strcpy(wordNode->name,token);break;}
case '/':
getcharfromfile();
if(ch=='*'){
char ch1,ch2;
do{
ch1=ch2;
getcharfromfile();
ch2=ch;
if(feof(fp))return;
}while(ch1!='*'||ch2!='/');
ch='\n';//for exit
break;
}
else{alreadyread=1;wordNode->id=33;strcpy(wordNode->name,token);break;}
case '.': wordNode->id=39;strcpy(wordNode->name,token);break;
case '\'': wordNode->id=40;strcpy(wordNode->name,token);break;
case '\\': wordNode->id=46;strcpy(wordNode->name,token);break;
case ':': wordNode->id=41;strcpy(wordNode->name,token);break;
case '|': wordNode->id=43;strcpy(wordNode->name,token);break;
case ',': wordNode->id=44;strcpy(wordNode->name,token);break;
case '!':
getcharfromfile();
if(ch=='='){connect();wordNode->id=36;strcpy(wordNode->name,token);break;}
else{alreadyread=1;wordNode->id=42;strcpy(wordNode->name,token);break;}
case '=': wordNode->id=38;strcpy(wordNode->name,token);break;
case '$': wordNode->id=47;strcpy(wordNode->name,token);break;//new~~~~~
case '\n':break;
case '\t':break;
default:printf("\n an error has been found:\n");break;
}
}
}
//输出规约结果
void printfGY(wordnode * Stack,int j,int k){
int i;
printf("归约:");
for(i=j;i<=k;i++)printf("%s ",Stack[i].name);
printf("\n");
}
//输出移进的结果
void printfYJ(wordnode * Stack,int i){
printf("移进:");
printf("%s%s",Stack[i].name,Stack[i].value);
printf("\n");
}
/**
语法分析器
*/
void SentenceAnalyse(){
//int Stack[1000];
wordnode *Stack=(wordnode*)malloc(1000*sizeof(wordnode));
int k=0;
int j;
Stack[k].id=47;//$
tableInit();
while(!feof(fp)){
getWord();
if(ch!='\n'&&ch!='\t'){
if(Stack[k].id==-1)j=k-1;
else j=k;
//printf("%d %d ",j,wordNode->id);
if(table[Stack[j].id][wordNode->id]==1||table[Stack[j].id][wordNode->id]==3){//(a<·b) or (a=·b) push in b
k++;
Stack[k].id=wordNode->id;
strcpy(Stack[k].name,wordNode->name);
strcpy(Stack[k].value,wordNode->value);
printfYJ(Stack,k);
}
else if(table[Stack[j].id][wordNode->id]==2){ //a·>b stack out while Pj-1>·Pj
//int i;
while(table[Stack[j].id][wordNode->id]==2){
int pervious;
do{
//if(Stack[j].id==-1)j--; //in case
pervious=Stack[j].id; //save the top-ermination
j--;
if(Stack[j].id==-1)j--; //find the near ermination in stack
}while(table[Stack[j].id][pervious]!=1);
printfGY(Stack,j+1,k);
//move in a 'N'
Stack[j+1].id=-1;
strcpy(Stack[j+1].name,"N");
//clear the old ones
strcpy(Stack[j+2].name,"");
strcpy(Stack[j+3].name,"");
//strcpy(Stack[j+4].name,"");
//strcpy(Stack[j+5].name,"");
}
//push in
k=j+2;
Stack[k].id=wordNode->id;
strcpy(Stack[k].name,wordNode->name);
strcpy(Stack[k].value,wordNode->value);
printfYJ(Stack,k);
}
else{//error
printf("\nerror right after:");
int i;
for(i=1;i<=j;i++)printf("%s",Stack[i].name);
printf("\n");
break;
}
}
free(token);
}
if(Stack[0].id==47&&Stack[1].id==-1&&Stack[2].id==47)printf("Nice sentense!");
else printf("Bad sentense!");
}
main(){
//加载文件
Init();
//分析文件
SentenceAnalyse();
//exit程序
exitPrograme();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -