一、程序要求
程序输入 / 输出示例:
对下列文法,用 SLR ( 1 )分析法对任意输入的符号串进行分析:
(0)S'—>E
( 1 ) E—> E+T
( 2 ) E —>E - T
(3)E—>T
( 3 ) T — >T*F
( 4 ) T —> T/F
(5)T—>F
( 6 ) F —> (E)
( 7 ) F —> i
输出的格式如下:
(1)SLR ( 1 )分析程序,编制人:姓名,学号,班级
(2) 输入一以 # 结束的符号串 ( 包括 + — */ () i#) :在此位置输入符号串
(3) 输出过程如下:
步骤 |
状态栈 |
符号栈 |
剩余输入串 |
动作 |
1 |
0 |
# |
i+i*i# |
移进 |
(4) 输入符号串为非法符号串 ( 或者为合法符号串 )
备注:
(1) 在“所用产生式”一列中如果对应有推导则写出所用产生式;如果为匹配终结符则写明匹配的终结符;如分析异常出错则写为“分析出错”;若成功结束则写为“分析成功”。
(2) 在此位置输入符号串为用户自行输入的符号串。
注意:
( 1 )表达式中允许使用运算符( +-*/ )、分隔符(括号)、字符 i ,结束符 # 。
( 2 )如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好)。
( 3 )对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照。
二、程序思路(仅供参考)
模块结构:
1. 定义部分:定义常量、变量、数据结构。
2. 初始化:设立 LR(1) 分析表、初始化变量空间(包括堆栈、结构体、数组、临时变量等)。
3. 控制部分:从键盘输入一个表达式符号串。
4. 利用 SLR(1) 分析算法进行表达式处理:根据 LR(1) 分析表对表达式符号串进行堆栈(或其他)操作,输出分析结果,如果遇到错误则显示错误信息。
****************************************************************************************************************************************************
该文法的LR(0)项目集规范族为:
I0: I1: I4: I5: I7: I9:
S'—>·E S'—>E· F —> (·E) F —> i· T — >T*·F E—> E+T·
E—>· E+T E—>E·+T E—>· E+T I6: T — >T/·F E—> E-T·
E —>·E - T E—>E·-T E —>·E - T E—>E+·T F —> ·(E) T — >T·*F
E—>·T I2: E—>·T E—>E-·T F —>· i T — >T·/F
T — >·T*F E—>T· T — >·T*F T — >·T*F I8: I10:
T —> ·T/F T — >T·*F T — >·T/F T — >·T/F F —> ·(E) T — >T*F·
T—>·F T — >T·/F T—>·F T—>·F E—>· E+T T — >T/F·
F —> ·(E) I3: F —> ·(E) F —> ·(E) E—>· E-T I11:
F —>· i T—>F· F —>· i F —>· i F —> (E)·
**********************************************************************************************************************************************
改进的SLR(1)分析表:
*******************************************************************************************************************************************
进行SLR(1)分析的c语言源代码:
#include
#include
#include
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://Users//wangquan//Desktop//文件//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])-3;j>=0;j--)
if(filestring[i][j]!='/n')
push(string,filestring[i][j]);
printf("此次分析的字符串为:%s /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;
}
*******************************************************************************************************************************************
实验结果如下:
***********************************************************************************************************************************************
对出错的处理: