实验二 基于预测方法的语法分析程序的设计(必修)
一、实验目的
了解预测分析器的基本构成及用自顶向下的预测法对表达式进行语法分析的方法,掌握预测语法分析程序的手工构造方法。
二、实验内容
1、了解编译程序的基于预测方法的语法分析过程。
2、根据预测分析原理设计一个基于预测方法的语法分析程序。
三、实验要求
对给定文法G[S]:
S->AT A->BU T->+AT|$ U->*BU|$ B->(S)|m
其中,$表示空串。
1、判断上述文法G[S]是否LL(1)文法,若不是,将其转变为LL(1)文法;
2、对转变后的LL(1)文法建立预测分析表;
3、根据清华大学出版编译原理教材教材第五章P94的图5.11手工构造预测分析程序;
4、用预测分析程序对任意给定的键盘输入串m+m*m#进行语法分析,并根据栈的变化状态输出给定串的具体分析过程。
四、运行结果
从任意给定的键盘输入串:
m+m*m#;
输出:
用预测分析法分析符号串m+m*m#的过程
Step |
Stack |
String |
Rule |
Step |
Stack |
String |
Rule |
1 |
#S |
m+m*m# |
S->AT |
10 |
#TUm |
m*m# |
M匹配 |
2 |
#TA |
m+m*m# |
A->BU |
11 |
#TU |
*m# |
U->*BU |
3 |
#TUB |
m+m*m# |
B->m |
12 |
#TUB* |
*m# |
*匹配 |
4 |
#TUm |
m+m*m# |
M匹配 |
13 |
#TUB |
m# |
B->m |
5 |
#TU |
+m*m# |
U->$ |
14 |
#TUm |
m# |
M匹配 |
6 |
#T |
+m*m# |
T->+AT |
15 |
#TU |
# |
U->$ |
7 |
#TA+ |
+m*m# |
+匹配 |
16 |
#T |
# |
T->$ |
8 |
#TA |
m*m# |
A->BU |
17 |
# |
# |
接受 |
9 |
#TUB |
m*m# |
B->m |
|
|
|
|
五、提示
本实验重点有两个:一是如何用适当的数据结构实现预测分析表存储和使用;二是如何实现各规则右部串的逆序入栈处理。
建议:使用结构体数组。
主函数:main.cpp
#include
#include
#include
#include "Stack.h"
using namespace std;
#define ROW_SIZE 10
#define COLUMN_SIZE 10
#define RULE_SIZE 10
char row[ROW_SIZE];
char column[COLUMN_SIZE];
char Rule[RULE_SIZE];
///定义一个结构体,存储规则右部的值
typedef struct
{
char rules[COLUMN_SIZE][RULE_SIZE];
}analyse;
///函数声明部分
int element_Search(char a[],char e,int length);
int rule_Search(analyse anal[],char e,char element,int m,int n);
int analyse_Process(Stack s,char str[],analyse anal[],int m,int n);
/**
样例:
5 6
m ( ) + * #
S ->AT ->AT 0 0 0 0
A ->BU ->BU 0 0 0 0
T 0 0 ->$ ->+AT 0 ->$
U 0 0 0 ->$ ->*BU ->$
B ->m ->(S) 0 0 0 0
m+m*m#
2 3
p q #
S ->pR ->qq 0
R ->p ->q 0
pqqppq#
2 3
a b #
S ->aM ->bb 0
M ->a ->b 0
abb#
**/
int main()
{
///将预测分析表输入进行存储
analyse anal[ROW_SIZE];
int m,n;
int i,j;
cout<<"请将预测分析表按下列要求进行输入"<>m;
cout<<"非终结符个数(包括‘#’):";
cin>>n;
cout<<"请输入终结符列:"<>column[i];
cout<<"请按非终结符行输入预测分析表中的内容(对于没有内容的单元用0表示):"<>row[i];
for(j=0;j>anal[i].rules[j];
}
}
while(1)
{
///输入待分析符号串
cout<>str;
cout<>want;
if(want=='Y' ||want=='y')
{
cmd=1;
break;
}
else if (want=='n' || want=='N')
{
break;
}
else
{
cout<<"输入指令有误,请重新输入"<1;j--)
{
e2=Rule[j];
if(e2!='$')
Push(s,e2);
}
}
}
///输出Rule
if(e=='#' && str[i-1]=='#')
cout<
头文件: Stack.h
#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED
#include
#include
#include
#define STACK_INT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量
typedef struct
{
char *base;
char *top;
int stacksize;
}Stack;
///创造一个空栈
int InitStack(Stack &S)
{
S.base=(char *)malloc(STACK_INT_SIZE*sizeof(char));
if(!S.base)
exit(-2);
S.top=S.base;
S.stacksize=STACK_INT_SIZE;
return 1;
};
///销毁栈S,栈S不再存在
int DestroyStack(Stack &S)
{
while(S.top!=S.base)
{
free(--S.top);
S.top--;
}
free(S.base);
return 1;
}
///把S置为空栈
int ClearStack(Stack &S)
{
while(S.top!=S.base)
{
free(--S.top);
S.top--;
}
return 1;
}
///返回S的元素个数,即栈的长度
int StackLength(Stack S)
{
return S.top-S.base;
}
///返回S的元素个数,即栈的长度
int StackEmpty(Stack S)
{
if(S.top==S.base)
return 1;
else
return 0;
}
///若栈不为空,则用e返回栈顶元素,并返回OK,否则返回ERROR
int GetTop(Stack S,char &e)
{
if(S.base==S.top)
return 0;
e=*(S.top-1);
return 1;
}
///插入元素e为新的栈顶元素
int Push(Stack &S,char e)
{
if(S.top-S.base>=S.stacksize)///栈满追加存储空间
{
S.base=(char *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));
if(!S.base)///存储分配失败
exit(-2);
S.top=S.base+S.stacksize;
S.stacksize+=STACKINCREMENT;
}
*S.top=e;
S.top++;
return 1;
}
///若栈不为空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR;
int Pop(Stack &S,char &e)
{
if(S.top==S.base)
return 0;
e=*--S.top;
return 1;
}
///遍历栈中的元素
int StackTraverse(Stack S)
{
if(S.base==NULL)
return -1;
if(S.base==S.top)
printf("栈中没有元素\n");
char *p;
p=S.top;
while(p-S.base>0)
{
p--;
printf("%c ",*p);
}
printf("\n");
return 1;
}
int reverseTraverse(Stack S)
{
if(S.base==NULL)
return -1;
if(S.base==S.top)
printf("栈中没有元素\n");
char *p,a[30];
int i=0;
p=S.base;
while(p
运行结果如下: