编译原理语法分析程序设计(ll(1)分析法)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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
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 {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 {printf(" %s\n",G[i]);} printf("___________________________________________________________\n"); printf("\n该文法的SELECT集如下:\n"); for(i=0;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 { 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.程序测试结果: