对于文法
E E + T | E – T | T
T T * F | T / F | F
F (E) | i
使用自下而上分析法的一种来进行构造算法
目前学过的自下而上分析法有
1、算符优先分析法(需要先来判断文法是否为算符优先文法)
2、LR(0)分析法
3、SLR(1)分析法
该程序的功能为,给定输入,程序按照先后顺序将使用的产生式输出。
如,输入25.6 * 14.5 + 2(首先经过词法分析,将其转化为 i * i + i),将在规约过程中使用到的产生式依次输出出来。
#include "stdafx.h"
#include <stdio.h>
#include <malloc.h>
#include <string>
struct stack
{
stack *top;
char value;
};
char pop(stack *pst)
{ char e;
if(pst->top==pst)
{
printf("The stack is null.");
return 0;
}
else
{
e=pst->top->value;
pst->top--;
return e;
}
}
void push(stack *pst,char e)
{
pst->top++;
pst->top->value=e;
}
void printstack(stack *pst)
{ stack *printtemp=pst;
while(printtemp<=(pst->top))
{
printf("%c",printtemp->value);
printtemp++;
}
}
void printstring(stack *pst)
{
stack *printtemp=(pst->top);
while(printtemp>=pst)
{
printf("%c",printtemp->value);
printtemp--;
}
}
void printSLR(int &number,stack *status,stack *grammar,stack *string)
{
printf("%d ",number);
printstack(status);printf(" ");
printstack(grammar);printf(" ");
printstring(string);printf(" ");
number++;
}
int main()
{
stack *string=(stack *)malloc(40);
string->top=string;
string->top->value='#';
stack *status=(stack *)malloc(40);
status->top=status;
status->top->value='0';
stack *grammar=(stack *)malloc(40);
grammar->top=grammar;
grammar->top->value='#';
FILE *fp;
fp=fopen("C:\\Documents and Settings\\zzu\\桌面\\c.txt","a+");
char filestring[10][20]={'\0'};
char str[10]={'\0'};
int stringnumber=0;
int number=0;
while(!feof(fp))
{
fgets(filestring[stringnumber],23, fp);
if(filestring[stringnumber][0]!='\n')
stringnumber++;
}
for(int i=0;i<=(stringnumber-1);i++)
{
for(int j=strlen(filestring[i])-1;j>=0;j--)
if(filestring[i][j]!='/n')
push(string,filestring[i][j]);
printf("此次分析的字符串为 \n",filestring[i]);
printf("步骤 状态栈 符号栈 输入串 ACTION \n");
printSLR(number,status,grammar,string);
printf(" 移进\n");
while(string->top->value!='#')
{
char ch=pop(string);
if(ch=='i')
{
push(grammar,ch);
if(status->top->value=='0')
{ push(status,'5');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(grammar);
push(status,'3');
push(grammar,'F');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(grammar);
push(status,'2');
push(grammar,'T');
printSLR(number,status,grammar,string);
printf(" 归约\n");
if(string->top->value=='+'||string->top->value=='-')
{
pop(status);
pop(grammar);
push(status,'1');
push(grammar,'E');
printSLR(number,status,grammar,string);
printf(" 移进\n");
}
}
else if(status->top->value=='6')
{
push(status,'5');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(grammar);
push(status,'3');
push(grammar,'F');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(grammar);
push(status,'9');
push(grammar,'T');
printSLR(number,status,grammar,string);
printf(" 归约\n");
if(string->top->value=='+'||string->top->value=='-')
{
pop(status);
pop(status);
pop(grammar);
pop(grammar);
printSLR(number,status,grammar,string);
printf(" 移进\n");
}
}
else if(status->top->value=='7')
{
push(status,'5');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(grammar);
push(status,'(');
push(status,'1');
push(status,'0');
push(status,')');
push(grammar,'F');
printSLR(number,status,grammar,string);
printf(" 归约\n");
pop(status);
pop(status);
pop(status);
pop(status);
pop(status);
pop(grammar);
pop(grammar);
printSLR(number,status,grammar,string);
printf(" 移进\n");
if(string->top->value=='+'||string->top->value=='-')
{
pop(status);
pop(grammar);
push(status,'1');
push(grammar,'E');
printSLR(number,status,grammar,string);
printf(" 移进\n");
}
}
else printf("There is something wrong near i .");
}
else if(ch=='+'||ch=='-')
{
if(status->top->value=='1'||status->top->value=='8')
push(status,'6');
else printf("There is something wrong near + or - \n");
push(grammar,ch);
printSLR(number,status,grammar,string);
printf(" 移进\n");
}
else if(ch=='*'||ch=='/')
{
push(grammar,ch);
if(status->top->value=='2'||status->top->value=='9')
push(status,'7');
else printf("There is something wrong near * or / \n");
printSLR(number,status,grammar,string);
printf(" 移进\n");
}
}
pop(status);
pop(status);
pop(grammar);
pop(grammar);
printSLR(number,status,grammar,string);
printf(" acc\n");
number=0;
status->top=status;
grammar->top=grammar;
string->top=string;
printf("SLR(1)分析结束 \n******************************************************************\n");
}
//return 0;
system("pause");
}
请在“C:\Documents and Settings\zzu\桌面”创建c.txt文件,在里面输入此次分析的字符串。
结果
此次分析的字符串为:i*i-i
步骤 状态栈 符号栈 输入串 ACTION
0 0 # i*i-i# 移进
1 05 #i *i-i# 归约
2 03 #F *i-i# 归约
3 02 #T *i-i# 归约
4 027 #T* i-i# 移进
5 0275 #T*i -i# 归约
6 027(10) #T*F -i# 归约
7 02 #T -i# 移进
8 01 #E -i# 移进
9 016 #E- i# 移进
10 0165 #E-i # 归约
11 0163 #E-F # 归约
12 0169 #E-T # 归约
13 01 #E # acc
SLR(1)分析结束
请按任意键继续…