G: V -> N|N[E]
E -> V|V+E
N -> i
该文法无左递归,经提左公因子得
G:V->NV'
V'->[E]|ε
E->VE'
E'->+E|ε
N->i
/*递归下降分析D5*/
/*LL(1)文法
**V->NV'
**V'->[E]|ε
**E->VE'
**E'->+E|ε
**N->i
*/
/*匹配字符串以#结尾*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_LINE 1024
struct record
{
char *data;
int lay;
int in;//标记函数的结尾
}Record[500];
char str[1000];
int strNum=0;
char sym;//ip当前所指的输入符号
int i=0;//记录深度
int num=0;//记录Record
char fileName[100];
void start();
void readFile();
void advance();
void output();
void error();
void assignRecord();//结构体赋值
void N();
void V();
void V_();
void E();
void E_();
int main(){
int inKind;//switch选择的变量
int key=1;
while(key){
system("cls");
printf("**********************\n");
printf("* 0.exit *\n");
printf("* 1.keyboard *\n");
printf("* 2.file *\n");
printf("**********************\n");
scanf("%d",&inKind);
switch(inKind){
case 0:
key=0;
break;
case 1:
scanf("%s",str);
start();
system("pause");
break;
case 2:
scanf("%s",fileName);
readFile();
system("pause");
break;
default:
printf("Please input correct key.\n");
}
}
return 0;
}
void readFile(){
//char szTest[1000] = {0};
int len = 0;
FILE *fp = fopen(fileName, "r");
if(NULL == fp)
{
printf("failed open error\n");
return;
}
while(!feof(fp))
{
memset(str, 0, sizeof(str));
fgets(str, sizeof(str) - 1, fp); // 包含了换行符
printf("%s", str);
start();
}
fclose(fp);
printf("\n");
}
/*程序执行入口*/
void start(){
strNum=0;
i=0;
num=0;//记录Record
advance();
V();
if(sym!='#')
error();
else
{
output();
printf("%s Matched Success\n",str);
}
}
/*每个非终结符对应的子程序
*v_代表V' E_代表E'
*/
void V(){//V->NV'
assignRecord("V",i+1,1);
int type=num-1;
i++;
assignRecord("N",i+1,1);
N();
i=Record[type].lay;
assignRecord("V\'",i+1,0);
V_();
}
void V_(){//V'->[E]|ε
int type=num-1;
i++;
if(sym=='[')
{
assignRecord("[",Record[type].lay+1,1);
advance();
assignRecord("E",i+1,1);
E();
if(sym==']')
{
assignRecord("]",Record[type].lay+1,0);
advance();
}
else{
return;
}
}
else
{
assignRecord("ε",Record[type].lay+1,0);
}
}
void E(){//E->VE'
int type=num-1;
i++;
assignRecord("V",i+1,1);
V();
i=Record[type].lay;
assignRecord("E\'",i+1,0);
E_();
}
void E_(){//E'->+E|ε
int type=num-1;
i++;
if(sym=='+')
{
assignRecord("+",Record[type].lay+1,1);
advance();
assignRecord("E",i+1,0);
E();
}
else
{
assignRecord("ε",Record[type].lay+1,0);
}
}
void N(){//N->i
int type=num;
i++;
if(sym=='i')
{
assignRecord("i",i+1,0);
advance();
}
}
/*输入下一个单词符号,待匹配的字符*/
void advance(){
sym=str[strNum];
strNum++;
}
/*出错处理*/
void error(){
printf("Unmatched Error\n");
}
/*树的输出*/
void output(){
int j,k;
int space[20];
for(j=0;j<num;j++)
{
if(Record[j].lay==1)
{
printf(" %s\n",Record[j].data);
}
else
{
for(k=1;k<Record[j].lay-1;k++)
{
if(space[k+1]==1)
printf("│ ");
else
printf(" ");
}
if(Record[j].in==1)
{
space[Record[j].lay]=1;
printf("├─── %s\n",Record[j].data);
}
if(Record[j].in==0)
{
space[Record[j].lay]=0;
printf("└─── %s\n",Record[j].data);
}
}
}
}
/*结构体赋值*/
void assignRecord(char *sym,int lay,int in){
Record[num].data=sym;
Record[num].lay=lay;
Record[num].in=in;
num++;
}