当前位置:文档之家› 编译原理语法分析程序设计分析法

编译原理语法分析程序设计分析法

1.实验目的:掌握LL(1)分析法的基本原理,掌握LL(1)分析表的构造方法,掌握LL(1) 驱动程序的构造方法。

2.实验要求:实现LR分析法(P147,例)或预测分析法(P121,例)。

3.实验环境:一台配置为1G的XP操作系统的PC机;Visual C++.
4.实验原理:编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语
法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程序,按该
语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程序是最终的一个语法单
位。

编译程序的语法规则可用上下文无关文法来刻画。

语法分析的方法分为两种:自上而下分析法和自下而上分析法。

自上而下就是从文法
的开始符号出发,向下推导,推出句子。

而自下而上分析法采用的是移进归约法,基本思想
是:用一个寄存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生
式的一个候选式时,即把栈顶的这一部分归约成该产生式的左邻符号。

自顶向下带递归语法分析:1、首先对所以的生成式消除左递归、提取公共左因子
2、在源程序里建立一个字符串数组,将所有的生成式都存在这个数组中。

3、给每个非终结符写一个带递归的匹配函数,其中起始符的函数写在main函数里。

这些函数对生成式右边从左向右扫描,若是终结符直接进行匹配,匹配失败,则调用出错函
数。

如果是非终结符则调用相应的非终结符函数。

4、对输入的符号串进行扫描,从起始符的生成式开始。

如果匹配成功某个非终结符
生成式右边的首个终结符,则将这个生成式输出。

匹配过程中,应该出现的非终结符没有出
现,则出错处理。

5.软件设计与编程:对应源程序代码:
#include <>
#include <>
#include <stack>
using namespace std;
struct Node1
{ char vn;
char vt;
char s[10];
}MAP[20]; n==vn && MAP[i].vt==vt)
{return MAP[i].s;} } return "error";}
char * Analyse(char * word)
{ char p,action[10],output[10];
int i=1,j,l=strlen(word),k=0,l_act,m;
while(!())
{();}
('#');
(start);
printf("___________________________________________________________\n");
printf("\n 对符号串%s的分析过程\n",word);
printf("
-----------------------------------------------------------------------\n
");
printf("\n");
printf(" 步骤栈顶元素剩余输入串动作\n");
printf("
-----------------------------------------------------------------------\n ");
p=();
while(p!='#')
{ printf("%7d ",i++);
p=();
();
printf("%6c ",p);
for(j=k,m=0;j<l;j++)
{output[m++]=word[j];}
output[m]='\0';
printf("%10s",output);
if(p==word[k])
{ if(p=='#')
{ printf(" 分析成功 \n");
return "SUCCESS";}
printf(" 匹配终结符%c\n",p);
k++;}
else{ strcpy(action,Find(p,word[k]));
if(strcmp(action,"error")==0)
{ printf(" 没有可用的产生式\n");
return "ERROR"; }
printf(" 展开非终结符%c%s\n",p,action);
int l_act=strlen(action);
if(action[l_act-1]=='e')
{continue;}
for(j=l_act-1;j>1;j--)
{(action[j]);}}}
if(strcmp(output,"#")!=0)return "ERROR";}
int main ()
{ freopen("","r",stdin);
char source[100];
int i,j,flag,l,m;
printf("\n***为了方便编写程序,用R代表E',W代表T',e代表空*****\n\n"); printf("该文法的产生式如下:\n");
for(i=0;i<len;i++)
{printf(" %s\n",G[i]);}
printf("___________________________________________________________\n");
printf("\n该文法的SELECT集如下:\n");
for(i=0;i<len;i++)
{ printf(" SELECT(%s) = { %s }\n",G[i],SELECT[i]); }
printf("___________________________________________________________\n");
n=G[i][0];
MAP[k].vt=SELECT[i][j];
strcpy(MAP[k].s,Right[i]);
k++;} }
printf("\n表达式文法的预测分析表如下:\n\n");
printf(" ");
for(i=0;i<6;i++)
{printf("%10c",VT[i]);}
printf("\n");
for(i=0;i<5;i++)
{ printf("
---------------------------------------------------------------\n");
printf("%10c",VN[i]);
for(j=0;j<6;j++)
{ for(m=0;m<k;m++)
{ if(VN[i]==MAP[m].vn && VT[j]==MAP[m].vt)
{ printf("%10s",MAP[m].s);
break;} }
if(m==k)
{printf(" ");} }
printf("\n");}
//预测分析程序Analyse函数
//输入源文件串
while(cin>>source)
{ printf("\n分析结果:%s\n\n",Analyse(source));}
return 0;}
6.程序测试结果:。

相关主题