实验三自下而上语法分析及语义分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三自下而上语法分析及语义分析
一、实验目的:
通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。
二、实验学时:
4学时。
三、实验内容
根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。
对于正确的表达式,给出表达式的值。
对于错误的表达式,给出出错位置。
四、实验方法
采用LR分析法。
首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。属性文法的定义可参照书137页表),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表)。
接下来给出LR分析表。
然后程序的具体实现:
LR分析表可用二维数组(或其他)实现。
添加一个val栈作为语义分析实现的工具。
编写总控程序,实现语法分析和语义分析的过程。
注:对于整数的识别可以借助实验1。
五、文法定义
简单的表达式文法如下:
E->E+T|E-T|T
T->T*F|T/F|F
F->(E)|i
上式中, i 为整数。
六、处理程序例
例1: 正确源程序例:
23+(45+4)* 40分析结果应为:正确的表达式。其值为:1983
例2: 错误源程序例:
5+(56+)-24
分析结果应为:错误的表达式:出错位置为)
附录:源程序
#include <>
#include""
#include
using namespace std;
#define R 30
#define C 20
typedef struct elem
{
char e[4];
}Elem; ;
for(i=0;i { printf("请输入%d号状态所对应的各列的元素,空白的地方用s代替\n",i); for(j=0;j { scanf("%s",mid); if(strcmp(mid,"s")==0||strcmp(mid,"S")==0) strcpy(LR[i+1][j].e," "); else strcpy(LR[i+1][j].e,mid); } } } void output_LR(int row,int colno) { int i,j; printf("**********************************************************\n"); printf("* LR分析表如下: *\n"); printf("**********************************************************\n"); printf("\n"); printf(" "); for(j=0;j printf("%s ",LR[0][j].e); printf("\n"); for(i=1;i<=row;i++) { printf("%d ",i-1); for(j=0;j printf("%s ",LR[i][j].e); printf("\n"); } printf("\n"); } int SignNum(char ch)==0) return i; return -1; } int CharChangeNum(char* ch); if(strcmp(mid," ")==0) { printf("不能规约\n"); return -2; } if(strcmp(mid,"acc")==0||strcmp(mid,"ACC")==0) { printf("规约成功\n"); return -1; } out[i+1].order=i+2; if(mid[0]=='s'||mid[0]=='S') { s_num=CharChangeNum(mid+1);tate[j]=out[i].state[j]; out[i+1].state[stateTop]=s_num; out[i+1].state[++stateTop]=-1; ign,out[i].sign); out[i+1].sign[signTop]=out[i].input[0]; out[i+1].sign[++signTop]='\0'; rasen," "); nput,out[i].input+1); tate[j]=out[i].state[j]; j=SignNum(gra[0]); out[i+1].state[stateTop]=CharChangeNum(LR[out[i+1].state[stateTop-1]+1][ j].e); out[i+1].state[++stateTop]=-1; ign,out[i].sign); out[i+1].sign[signTop]=gra[0]; out[i+1].sign[++signTop]='\0'; rasen,gra); nput,out[i].input); rder); while(out[i].state[j]!=-1) printf("%d",out[i].state[j++]); printf(" %s %s %s\n",out[i].sign,out[i].grasen,out[i].input) ; } } int OutControl()rder=1; tate[0]=0; stateTop=1; out[0].state[stateTop]=-1; ign,"#"); signTop=1; rasen," "); nput,Sentence); nput,"#"); strcpy(out[0].explen,"0和#进栈"); nput[0]); tate[stateTop-1],s_num,i)!=1) break; i++; } return i; } main() { int r; printf("**********************************************************\n"); printf("* 函数的输入: 文法的产生式,文法句型的一个句子,LR分析 表 *\n"); printf("* 函数的输出: LR分析器的工作过程与说明 *\n"); printf("**********************************************************\n"); printf("请输入LR分析表中终结符与非终结符的总个数\n"); scanf("%d",&colno); printf("请输入LR分析表中状态的总个数\n"); scanf("%d",&row); input_LR(row,colno); output_LR(row,colno); input_GramSent();