语义分析实验报告

合集下载

语义分析

语义分析

三、词法、语法、语义分析结合一、实验目的与要求在实现词法、语法分析程序的基础上,编写相应的语义子程序,进行语义处理,加深对语法制导翻译原理的理解,进一步掌握将语法分析所识别的语法范畴变换为某种中间代码(四元式)的语义分析方法,并完成相关语义分析器的代码开发。

二、实验内容语法制导翻译模式是在语法分析的基础上,增加语义操作来实现的。

对于给定文法中的每一产生式,编写相应的语义子程序。

在语法分析过程中,每当用一个产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作之外,还要调用相应的语义子程序,以便完成生成中间代码、查填有关表格、检查并报告源程序中的语义错误等工作。

每个语义子程序需指明相应产生式中各个符号的具体含义,并规定使用该产生式进行分析时所应采取的语义动作。

这样,语法制导翻译程序在对源程序从左到右进行的一遍扫描中,既完成语法分析任务,又完成语义分析和中间代码生成方面的工作。

输入:包含测试用例,如由无符号数和+、−、*、/、(、)构成的算术表达式的源程序文件。

输出:将源程序转换为中间代码形式表示,并将中间代码序列输出到文件中。

若源程序中有错误,应指出错误信息。

三、实验设计语法制导翻译模式实际上是对前后文无关文法的一种扩展。

一般而言,首先需要根据进行的语义工作,完成对文法的必要拆分和语义动作的编写,从而为每个产生式都配备相应的语义子程序,以便在进行语法分析的同时进行语义解释。

要求从编译器的整体设计出发,重点通过对实验二中语法分析程序的扩展,完成一个编译器前端程序的编写、调试和测试工作,形成一个将源程序翻译为中间代码序列的编译系统。

对文法G3[<算术表达式>]中的产生式添加语义处理子程序,完成无符号数的四则运算的计值处理,将输入的四则运算转换为四元式形式的中间代码。

本实验只进行了算术表达式四元式的翻译。

四、源代码1、在.h文件中添加了//语义分析部分#define PMAX 5//define 后面不加括号,定义产生式符号属性字符串的长度int NXQ=0; /*全局变量NXQ用于指示所要产生的下一个四元式的编号*/int NXTemp=1;//整型变量NXTemp指示临时变量的编号int SentenceCount=1;//存放文件中句子的个数struct QUATERNION /*四元式表的结构*/{char op[PMAX]; /*操作符*/char arg1[PMAX]; /*第一个操作数*/char arg2[PMAX]; /*第二个操作数*/char result[PMAX]; /*运算结果*/}pQuad[256]; /*存放四元式的数组*/char EBracket_Place[PMAX];//(E)的语义属性char i_Place[PMAX];char E_Place[PMAX];char T_Place[PMAX];char F_Place[PMAX];//char JudgeStr[100];int EXCUTE (int state, int symbol,FILE *fp,char JudgeStr[],int row,int index);int GetChar (char ch);int HandleError (char StrJudge[],int row);int Push( int State );int Pop(int count);int SLRControl(FILE* fp);void GEN(char *Op, char *Arg1, char *Arg2, char *Result);char *NewTemp(void);void NextSentence(FILE* fp);//当语法或者词法产生错误的时候,跳过当前错误的句子,将文件指针指向下一个句子的开始#define MAXLENGTH 10;void GEN(char *Op, char *Arg1, char *Arg2, char *Result){strcpy (pQuad[NXQ].op, Op); /*pQuad为全局变量,是用于存放四元式的数组*/strcpy (pQuad[NXQ].arg1, Arg1);strcpy (pQuad[NXQ].arg2, Arg2);strcpy (pQuad[NXQ].result, Result);NXQ++; /*全局变量NXQ用于指示所要产生的下一个四元式的编号*/}char *NewTemp(void) /*产生一个临时变量*/{char *TempID=(char*)malloc(PMAX);sprintf (TempID, "T%d", NXTemp++);return TempID;}2、在.cpp文件中修改的部分int SLRControl(FILE* fp){while(Action[TopState][InputWordType][0] != 'A'){if (UNKNOWN==InputWordType){printf("**********************分析语句%i 时词法分析出错******************\n",SentenceCount);return 0;}printf("栈顶状态:%i\n",TopState);printf("扫描的单词类型:%i\n",InputWordType);/*if ('A'==Action[State][WordType][0]){TopState=0;//正确后把栈顶状态置为初始化StackPoint=0;//同理上面memset(StateStack,-1,sizeof(StateStack));printf("Right!");return 1;}*/if (-1==TopState){printf("分析语句%i 时状态栈栈顶指针错误!分析结束\n",SentenceCount);return 0;}if (' ' == Action[TopState][InputWordType][0]){printf("分析语句%i 时语法分析出错!分析结束\n",SentenceCount);return 0;}else if('s'==Action[TopState][InputWordType][0]){//TopState=atoi(&Action[TopState][InputWordType][1]);Push(atoi(&Action[TopState][InputWordType][1]));printf("执行压栈操作\n");if (EOF!=fgetc(fp)){scanner(fp);}else{printf("语句%i 不完整!分析结束\n",SentenceCount);return 0;}}else if('r'==Action[TopState][InputWordType][0]){//do//用一个while循环为了可能遇到连续规约的情况,即从文件中扫描一个单词之后,可能连续规约多次//{int ProductionNum=atoi(&Action[TopState][InputWordType][1]);int ProdutionLeft=0;if (1==ProductionNum){ProdutionLeft=E;//为下面差goto表提供列坐标Pop(3);printf("用产生式1 归约\n");char* Temp=NewTemp();GEN("+",E_Place,T_Place,Temp);strcpy(E_Place,Temp);printf("生成四元式:(“+”,E_Place,T_Place,E_Place)\n"); }else if(2==ProductionNum){ProdutionLeft=E;Pop(3);printf("用产生式2 归约\n");char* Temp=NewTemp();GEN("-",E_Place,T_Place,Temp);strcpy(E_Place,Temp);printf("生成四元式:(“-”,E_Place,T_Place,E_Place)\n"); }else if(3==ProductionNum){ProdutionLeft=E;Pop(1);printf("用产生式3 归约\n");char* Temp=NewTemp();GEN("",T_Place,"",Temp);strcpy(E_Place,Temp);printf("生成四元式:(-,-,T_Place,E_Place)\n");}else if(4==ProductionNum){ProdutionLeft=T;Pop(3);printf("用产生式4 归约\n");char* Temp=NewTemp();GEN("*",T_Place,F_Place,Temp);strcpy(T_Place,Temp);printf("生成四元式:(“*”,T_Place,F_Place,T_Place)\n"); }else if(5==ProductionNum){ProdutionLeft=T;Pop(3);printf("用产生式5 归约\n");char* Temp=NewTemp();GEN("/",T_Place,F_Place,Temp);strcpy(T_Place,Temp);printf("生成四元式:(“/”,T_Place,F_Place,T_Place)\n");}else if(6==ProductionNum){ProdutionLeft=T;Pop(1);printf("用产生式6 归约\n");char* Temp=NewTemp();GEN("+",F_Place,"",Temp);strcpy(T_Place,Temp);printf("生成四元式:(-,-,F_Place,T_Place)\n");}else if(7==ProductionNum){ProdutionLeft=F;Pop(3);printf("用产生式7 归约\n");char* Temp=NewTemp();GEN("+",EBracket_Place,"",Temp);strcpy(F_Place,Temp);printf("生成四元式:(-,-,(E)_Place,F_Place)\n");}else if(8==ProductionNum){ProdutionLeft=F;Pop(1);printf("用产生式8 归约\n");char* Temp=NewTemp();GEN("+",i_Place,"",Temp);strcpy(F_Place,Temp);printf("生成四元式:(-,-,i_Place,F_Place)\n");}else{printf("分析语句%i 时产生式编号超出范围!分析结束\n",SentenceCount);return 0;}Push(Goto[TopState][ProdutionLeft]);//}while('r' == Action[TopState][InputWordType][0])}}printf("栈顶状态:%i\n",TopState);printf("扫描的单词类型:%i\n",InputWordType);printf("*********************************语句%i 正确*********************************\n",SentenceCount);return 1;}void NextSentence(FILE* fp){while ('#'!= ch){ch=fgetc(fp);}if('\n'==fgetc(fp)){return;}SentenceCount++;return;}/////////////////////////////////主程序int main(int argc, char* argv[]){extern char ch;FILE *fp;if((fp=fopen("date.txt","r"))==NULL){printf("\nfile open error!\n");exit(0);}if(ch=fgetc(fp)=='EOF')//不管小括号内的判断是否成功,p指针都会向后移一个位置,判断不成功,ch中存的字符不变{printf("The file is null.\n");return 0;}while ('\n'!=fgetc(fp)){TopState=0;StackPoint=0;memset(StateStack,-1,sizeof(StateStack));printf("***********************语句%i 分析开始**************************\n",SentenceCount);scanner(fp);SLRControl(fp);NextSentence(fp);}//printf("第一个字母是:%c\n",ch);//fseek(p,-1,1);/*do{scanner(p);}while(ch=fgetc(p)!=EOF);*/fclose(fp);return 0;}五、测试用例和结果分析运行结果:结果分析:虽然能分开语句,但仍用“#”做结束标识符。

编译原理实验报告语义分析

编译原理实验报告语义分析

编译原理实验报告语义分析实验名称:语义分析实验目的:1.掌握词法分析器生成的词法单元序列的构造;2.学会设计语法分析器,实现对程序的基本语法结构检查,并生成抽象语法树;3.学习语义规约的实现,实现对程序的语义分析和错误检查;4.熟悉语义分析向语法分析的接口。

实验原理:语义分析是编译过程的一个重要环节,它的主要任务是对生成的抽象语法树进行遍历,并验证程序的类型一致性、语义规则的正确性、错误的检查和恢复等。

语义分析的输入是由语法分析生成的抽象语法树,输出是继续优化的抽象语法树或中间代码,以供后续的中间代码生成等工作使用。

实验步骤:1.设计语法分析器,包括语法规则、优先级关系等;2.生成词法单元序列;3.构建语法分析器,进行语法分析,并生成抽象语法树;4.针对不同的语义规约,设计语义动作,实现对程序的语义分析和错误检查;5.完成语义分析器的构建和测试。

实验设备:1.计算机;2. 编程语言:C++/Java/Python等;3. 开发环境:Visual Studio/ Eclipse/PyCharm等。

实验结果:通过对语法分析生成的抽象语法树进行遍历,实现了对程序的语义分析和错误检查。

具体实现包括:1.类型检查:根据语义规约,对程序中的类型进行检查,包括变量的声明及使用、函数的调用、赋值语句的一致性等;2.作用域检查:检查变量的作用域和可见性等;3.错误检查:检测语义错误,如变量未声明、函数重复定义等;4.错误恢复:当检测到错误时,采取适当的错误恢复措施,如跳过错误的部分继续分析、提示错误信息等。

实验心得:本次实验主要学习了语义分析的原理和实现方法,深入了解了编译过程中各个环节的作用和关系。

通过实践操作,加深了对语法分析和语义分析的理解,提高了编程能力和解决问题的能力。

同时,实验过程中也遇到了一些挑战和困难,例如语义规约的设计和实现、错误检查和恢复等,但通过查阅资料和与同学讨论,最终解决了这些问题。

通过本次实验,我对编译原理和语义分析有了更深入的了解,并且对以后的学习和工作有了更好的准备。

语义分析——精选推荐

语义分析——精选推荐

语义分析实验四、语法分析实验⼀、实验⽬的(1)编制⼀个语义分析程序(2)语义分析程序是在语法分析程序的基础上进⾏编写的,主要任务是根据语法分析来插⼊中间代码、语义规则以及⽣成四元式。

(3)通过语义分析的练习,能够进⼀步了解编译原理。

(4)通过了解语义分析程序的设计原则、语义规则的描述技术、识别机制及语义分析程序的⾃动构造原理。

⼆、实验内容和要求(1)根据语法分析程序进⾏改写语义分析程序(2)根据语⾔的语义规则,插⼊中间代码、语义规则以及⽣成四元式等(3)并在分析过程中进⾏语义检查,四元式作为输出或以某种形式的语法树作报告错误三、实验⽅法、步骤及结果测试1、实验⽅法、步骤:完成静态语义审查和处理a) 上下⽂相关性审查b) 类型匹配审查c) 类型转换d) 如:s:=2*3.1416*r*(h+r);i. 赋值语句的语义:计算赋值符号右边表达式的值,送到赋值号左边的变量中。

ii. 检查赋值号左右两边的类型是否匹配iii. 根据赋值语句的语义,将它翻译成四元式中间代码2、原理分析:我是在语法分析程序的基础上进⾏修改的,是根据语法分析来插⼊中间代码、制定语义规则以及⽣成四元式。

void S(){char y=str[t-1];int x;if(syn==10){scaner();if(syn==18){scaner(); x=E();printf("\n(':=',%d, ,%c)\n",x,y);}}}int E(){int x;printf("E ");x=T();return E1(x);}int E1(int x){int y;printf("E1 ");if (syn==13) {scaner();y=T();gen4('+',x,y);return E1(x+y);}else if (syn==14) {scaner();y=T();gen4('-',x,y);return E1(x-y);}else {if (syn==28 || syn==25)return(x);}}int T(){int x;printf("T ");x=F();return T1(x);}int T1(int x){int y;printf("T1 ");if (syn==15) {scaner();y=F();gen4('*',x,y);return T1(x*y);}else if (syn==16) {scaner();y=F();gen4('/',x,y);return T1(x/y);}else {if (syn==28 ||syn==25 || syn==13||syn==14)return (x);else error();}}int F(){int y; printf("F ");if (syn==27) {scaner();y=E();if(syn==28) {scaner();return (y);}else error();}else if (syn==11 || syn==10){ y=sum; scaner();return (y);}}四、实验总结由于时间的关系,这次实验我暂且做了语义分析的算术表达式与赋值语句,虽然做的不多,但也算把算术表达式做的不错,是有优先级的,我做的实验是以’#’为结束语,输出的四元式是⽤(‘运算符’,操作数1,操作数2,运算结果);还有就是赋值语句是S:=E;这次实验,我学会了语法分析和语义分析程序,利⽤⾃上⽽下的递归下降分析法来分析语法,然后进⾏赋予语义规则,再⽣产中间代码,最后输出四元式。

词法分析、语法分析、语义分析实例解析及实验报告

词法分析、语法分析、语义分析实例解析及实验报告

词法分析一、实验目的设计、编制并调试一个词法分析程序,加深对词法分析原理的理解。

二、实验要求2.1 待分析的简单的词法(1)关键字:begin if then while do end所有的关键字都是小写。

(2)运算符和界符:= + - * / < <= <> > >= = ; ( ) #(3)其他单词是标识符(ID)和整型常数(SUM),通过以下正规式定义:ID = letter (letter | digit)*NUM = digit digit*(4)空格有空白、制表符和换行符组成。

空格一般用来分隔ID、SUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2.2 各种单词符号对应的种别码:输入:所给文法的源程序字符串。

输出:二元组(syn,token或sum)构成的序列。

其中:syn为单词种别码;token为存放的单词自身字符串;sum为整型常数。

例如:对源程序begin x:=9: if x>9 then x:=2*x+1/3; end #的源文件,经过词法分析后输出如下序列:(1,begin)(10,x)(18,:=)(11,9)(26,;)(2,if)……标识符(需进一步判断是否为关键字)数字+=+-=-词法分析状态转换图(终结状态右上角*表示多读一个符号)三、词法分析程序的算法思想:算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

3.1 主程序示意图:主程序示意图如图3-1所示。

其中初始包括以下两个方面: ⑴ 关键字表的初值。

关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识别出标识符时,查关键字表。

如能查到匹配的单词,则该单词为关键字,否则为一般标识符。

关键字表为一个字符串数组,其描述如下:Char *rwtab[6] = {“begin ”, “if ”, “then ”, “while ”, “do ”, “end ”,};图3-1(2)程序中需要用到的主要变量为syn,token 和sum 3.2 扫描子程序的算法思想:首先设置3个变量:①token 用来存放构成单词符号的字符串;②sum 用来存放整型单词;③syn 用来存放单词符号的种别码。

实验三语义分析报告

实验三语义分析报告

编译原理实验报告实验名称:分析调试语义分析程序实验类型:验证型指导教师:专业班级:姓名:学号:实验地点:实验成绩:日期:2016 年 6 月 3 日实验三分析调试语义分析程序一、实验目的通过分析调试TEST语言的语义分析和中间代码生成程序,加深对语法制导翻译思想的理解,掌握将语法分析所识别的语法范畴变换为中间代码的语义翻译方法。

二、实验知识1.语法制导基本思想语法制导就是对文法中的每个产生式都附加一个语义动作或语义子程序,且在语法分析过程中,每当需要使用一个产生式进行推导或归约时,语法分析程序除执行相应的语法分析动作外,还要执行相应的语义动作或调用相应的语义子程序。

基本思想是,根据翻译的需要设置文法符号的属性,以描述语法结构的语义。

例如,一个变量的属性有类型,层次,存储地址等。

表达式的属性有类型,值等。

属性值的计算和产生式相联系。

随着语法分析的进行,执行属性值的计算,完成语义分析和翻译的任务。

2.翻译方案设计1)设计原理:在实验二的基础上为文法符号引进一组属性及相应求值规则和动作,得到属性翻译文法,并引进一个符号表(包括变量名,变量数据是否有效,变量地址,变量的具体数据,数据类型等),在进行语法分析的同时,结合符号表完成语义分析与检测,同时根据属性翻译文法的属性及相关动作得到中间代码(抽象机式汇编指令),最后通过模拟的抽象机运行出结果。

2)设计方法:(@为动作标志,↓为继承属性,↑为综合属性)结合课本语法制导相关内容对文法增加属性和动作如下:以下列出有修改的属性翻译文法:①<declaration_stat>↓vartablep,datap,codep →int ID↑n@name-def↓n,t;其中动作符号的含义如下@name-def↓n,t:插入符号表;②<if_stat>→if (<expr>)@BRF↑label1<statement>@BR↑label2 @SETlabel↓label1| if (<expr>) @BRF↑label1<statement >@BR↑label2 @SETlabel↓label1else < statement > @SETlabel↓label2其中动作符号的含义如下@BRF↑label1 :输出BRF label1;@BR↑label2:输出BR label2;@SETlabel↓label1:设置标号label1;@SETlabel↓label2:设置标号label2;③<while_stat>→while@SETlabel↑label1(<expression>) @BRF↑label2<statement >@BR↓label1 @SETlabel↓label2其中动作符号的含义如下@SETlabel↑label1:设置标号label1;@BRF↑label2 :输出BRF label2;@BR↓label1:输出BR label1;@SETlabel↓label2:设置标号label2;④<for_stat>→for (<expression>@POP;@SETlabel↑label1< expression >@BRF↑label2@BR↑label3;@SETlabel↑label4 < expression >@POP@BR↓label1) @SETlabel↓label3 < statement >@BR↓label4@SETlabel↓label2其中动作符号的含义如下@SETlabel↓label1:设置标号label1;@BRF↑label2 :输出BRF label2;@BR↑label3:输出BR label3;@SETlabel↓label4:设置标号label4;@BR↑label1:输出BR label1;@SETlabel↓label3:设置标号label3;@BR↑label4:输出BR label4;@SETlabel↓label2:设置标号label2;⑤<write_stat>→write <expression>@OUT;其中动作符号的含义如下@ OUT:输出OUT⑥<read_stat>→read ID↑n LOOK↓n↑d @IN@STO↓d@POP;其中动作符号的含义如下@LOOK↓n↑d:查符号表n,给出变量地址d;没有,变量没定义;@IN:输出IN;@STO↓d:输出指令代码STO d;@POP:将栈顶元素出栈⑦<expression>→ID↑n@LOOK↓n↑d@ASSIGN=<bool_expr>@STO↓d@POP |<bool_expr>其中动作符号的含义如下@LOOK↓n↑d:查符号表n,给出变量地址d;没有,变量没定义;@ASSIGN:记住当前文件位置;@STO↓d:输出指令代码STO d;⑧<bool_expr>→<additive_expr>|< additive_expr >><additive_expr>@GT|< additive_expr ><<additive_expr>@LES|< additive_expr >>=<additive_expr >@GE|< additive_expr ><=< additive_expr >@LE|< additive_expr >==< additive_expr >@EQ|< additive_expr >!=< additive_expr >@NOTEQ其中动作符号的含义如下@GT:次栈顶与栈顶作大于比较;@LES:次栈顶与栈顶作小于比较;@GE:次栈顶与栈顶作大于等于比较;@LE:次栈顶与栈顶作小于等于比较;@EQ:次栈顶与栈顶作等于比较;@NOTEQ:次栈顶与栈顶作不等于比较;B→+<term>B@ADD | -<term>B@SUB | ε⑨<additive_A>→+<term><additive_A>@ADD | -<term><additive_A>@SUB | ε其中动作符号的含义如下@ADD:操作数相加;@SUB:操作数相减;C→*<factor>C@MULT | /<factor>C@DIV | ε⑩<term_A>→*<factor><term_A>@MULT | /<factor><term_A>@DIV | ε其中动作符号的含义如下@MULT:操作数相乘;@DIV:操作数相除;⑪< factor >→(< expression >)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i其中动作符号的含义如下@LOOK↓n↑d:查符号表n,给出变量地址d;没有,变量没定义;@LOAD↓d:将地址d的变量入栈;@LOADI↓i:将常量i入栈;3)设计结果:1) <program>→{<declaration_list><statement_list>}2)<declaration_list>→<declaration_stat> <declaration_list>| ε3) <declaration_stat>↓vartablep,datap,codep →int ID↑n@name-def↓n,t;4) <statement_list>→<statement><statement_list>| ε5) <statement>→<if_stat>|<while_stat>|<for_stat>|<read_stat>|<write_stat>|< compound_stat > |<expression_stat>6)<if_stat>→if (<expr>)@BRF↑label1<statement>@BR↑label2 @SETlabel↓label1| if (<expr>) @BRF↑label1<statement >@BR↑label2 @SETlabel↓label1else < statement > @SETlabel↓label27)<while_stat>→while@SETlabellabel1(<expression>)@BRF↑label2 <statement >@BR ↓label1 @SETlabel↓label28) <for_stat>→for (<expression>;@SETlabel↑label1< expression >@BRF↑label2@BR↑label3;@SETlabel↑label4 < expression >@BR↓label1) @SETlabel↓label3 < statement >@BR ↓label29) <write_stat>→write <expression>@OUT;10) <read_stat>→read ID↑n LOOK↓n↑d @IN@STO↓d@POP;11)<compound_stat>→{<statement_list>}12)<expression_stat>→< expression >@POP;|;13) <expression>→ID↑n@LOOK↓n↑d@ASSIGN=<bool_expr>@STO↓d@POP |<bool_expr>14) <bool_expr>→<additive_expr><bool_A>15) <bool_A>→><additive_expr>@GT|<<additive_expr>@LES|>=<additive_expr >@GE|<=< additive_expr >@LE|==< additive_expr >@EQ|!=< additive_expr >@NOTEQ | ε16) < additive_expr>→<term><additive_A>17) <additive_A>→+<term><additive_A>@ADD | -<term><additive_A>@SUB | ε18) < term >→<factor><term_A>19) <term_A>→*<factor><term_A>@MULT | /<factor><term_A>@DIV | ε20) < factor >→(< expression >)| ID↑n@LOOK↓n↑d@LOAD↓d |NUM↑i@LOADI↓i三、实验过程首先,理解书上的代码和观看相关的知识的PPT,深入理解属性反应文法的作用,据此在我之前实验写好的语法分析基础上进行修改,写出语义分析代码。

编译原理语义实验报告

编译原理语义实验报告

编译原理语义实验报告编译原理语义实验报告引言:编译原理是计算机科学中的重要课程之一,它研究的是如何将高级程序语言转化为机器语言,使得计算机能够理解并执行程序。

语义分析是编译过程中的重要环节,它负责对程序的语义进行分析和处理。

本实验报告将介绍我们在编译原理课程中进行的语义实验,并分享我们的实验结果和心得体会。

实验目的:本次实验的主要目的是掌握语义分析的基本原理和方法,了解如何构建语法树以及如何进行类型检查和语义规则的验证。

通过实验,我们将能够更好地理解编译器是如何对程序进行处理和优化的。

实验环境和工具:为了完成本次实验,我们使用了一些常见的编程语言和工具。

其中,我们选择了C语言作为实验的目标语言,并使用了Flex和Bison作为词法分析器和语法分析器的生成工具。

此外,我们还使用了一些辅助工具和库,如LLVM和GCC 等。

实验过程:在实验过程中,我们首先需要设计和实现一个简单的编程语言,包括其语法和语义规则。

然后,我们使用Flex和Bison来生成词法分析器和语法分析器,并通过这些工具将源代码转换为语法树。

接下来,我们对语法树进行类型检查和语义规则的验证,以确保程序的正确性和合法性。

最后,我们将生成的中间代码转化为目标代码,并进行优化和生成可执行文件。

实验结果:通过实验,我们成功地设计和实现了一个简单的编程语言,并使用Flex和Bison生成了相应的词法分析器和语法分析器。

我们还实现了类型检查和语义规则的验证,确保了程序的正确性和合法性。

最终,我们成功地将生成的中间代码转化为目标代码,并生成了可执行文件。

实验心得:通过本次实验,我们深入理解了编译原理中的语义分析过程。

我们学会了如何构建语法树,并对其进行类型检查和语义规则的验证。

我们还学会了使用一些常见的编程语言和工具,如C语言、Flex、Bison等。

通过实验,我们不仅提高了自己的编程能力,还加深了对编译原理的理解和认识。

结论:编译原理是计算机科学中的重要课程,语义分析是编译过程中的关键环节。

语法和语义分析器试做报告

语法和语义分析器试做报告
试做实验小结
通过本实验加深了对语法分析器和语法制导翻译方法的理解,掌握了利用yacc工具编写语法分析程序。
开出注意事项
需要安装的软件:
1.linux操作系统;
院(系、部)验收组审查意见
院(系、部)负责人签字:
注:该表一式两份,一份院(系、部做报告
单位名称:计算机科学与技术系试做日期:2012年8月28日
新开实验项目名称
语法和语义分析器
学时数
4
面向专业
计算机科学与技术、计算机软件
试作教师签名
谢飞、朱强
一、实验目的
1.掌握Yacc的基本用法,并能够根据语言给出语法规则的定义,最后生成语言的解析器;
3.使用Yacc实现一个高级计算器程序。
二、实验内容
下面是计算器的功能:
1.运算符:+、-、*、/、unminus
优先级(从高到低):unminus
*、/
+、-
三、源程序清单或实验步骤
实验步骤:
1.编写lex和yacc源程序
vi calc.lex
vi calc.y
2.运行程序
四、实验结果
说明:此部分的内容和格式可根据每个实验项目的具体需要和要求,由各院(系、部)自行设计和确定相关栏目;其余部分应按此表格式统一。

编译原理_ 语义分析_实验报告

编译原理_ 语义分析_实验报告

编译原理实验三语义分析实验报告◆学院:数学与计算机科学技术学院◆专业:计算机科学与技术◆班级:级计算机班◆小组组员:姓名:学号:姓名:学号:姓名:学号:姓名:学号:实验题目一、实验目的要求学生用与实验2相同的语言,编制语义分析程序。

二、实验准备微机CPU主频1.3G以上,128M内存,安装好C语言,PASCAL语言,或C++。

三、实验时间13学时四、实验内容要求学生用与实验2相同的语言,编制语义分析程序。

定义该语言的语义成分,将语义分析程序编制成子程序,在实验2分析出各语法单位后,分析其含义,并将可执行语句或表达式翻译为四元式输出,并将错误信息输出。

实验报告必须包括设计的思路,以及测试报告(输入测试例子,输出结果)。

五、上交文档1.实验报告(书面);2.程序文件(通过网络提交)。

<program> ::= <block> .<block> ::= <const-decl> <var-decl> <proc-decl> <statement><const-decl> ::= const <const-assignment-list> ; | ε<const-assignment-list> ::= <ident> = <number>| <const-assignment-list> , <ident> = <number><var-decl> ::= var <ident-list> ; |ε<ident-list> ::= <ident> | <ident-list> , <ident><proc-decl> ::= <proc-decl> procedure <ident> ; <block> ; |ε<statement> ::= <ident> := <expression>| call <ident>| begin <statement-list> end| if <condition> then <statement>| while <condition> do <statement>|ε<statement-list> ::= <statement> | <statement-list> ; <statement><condition> ::= odd <expression> | <expression> <relation> <expression><relation> ::= = | <> | < | > | <= | >=<expression> ::= <term> | <adding-operator> <term>| <expression> <adding-operator> <term><adding-operator> ::= + | -<term> ::= <factor> | <term> <multiplying-operator> <factor><multiplying-operator> ::= * | /<factor> ::= <ident> | <number> | ( <expression> )注意:(1) "ε" 表示空串。

语义分析实验报告

语义分析实验报告

一、实验背景随着信息技术的飞速发展,语义分析作为自然语言处理(NLP)领域的一个重要分支,日益受到学术界和工业界的关注。

语义分析旨在理解和处理人类语言中的语义信息,包括词义消歧、句法分析、指代消解等任务。

本实验旨在通过构建一个简单的语义分析系统,对中文文本进行语义分析,验证语义分析技术在中文处理中的有效性。

二、实验目的1. 了解语义分析的基本原理和方法。

2. 掌握中文语义分析的相关工具和算法。

3. 构建一个简单的语义分析系统,对中文文本进行实验验证。

三、实验内容1. 数据集准备实验数据集采用某中文新闻语料库,包含约5万条新闻文本,每条文本约500字左右。

2. 实验方法(1)词性标注利用基于统计的词性标注工具(如Stanford CoreNLP)对文本进行词性标注,识别文本中的名词、动词、形容词等。

(2)命名实体识别利用命名实体识别(NER)工具(如Stanford CoreNLP)对文本进行命名实体识别,识别文本中的人名、地名、机构名等。

(3)依存句法分析利用依存句法分析工具(如Stanford CoreNLP)对文本进行句法分析,识别文本中的句子成分及其之间的关系。

(4)语义角色标注利用语义角色标注(SRL)工具(如Stanford CoreNLP)对文本进行语义角色标注,识别文本中谓词的宾语、宾语补足语等。

3. 实验步骤(1)数据预处理对实验数据集进行预处理,包括去除停用词、分词、去除特殊符号等。

(2)词性标注使用词性标注工具对预处理后的文本进行词性标注。

(3)命名实体识别使用命名实体识别工具对文本进行命名实体识别。

(4)依存句法分析使用依存句法分析工具对文本进行句法分析。

(5)语义角色标注使用语义角色标注工具对文本进行语义角色标注。

(6)结果分析对实验结果进行分析,评估语义分析系统的性能。

四、实验结果与分析1. 词性标注实验结果显示,词性标注准确率达到95%以上,说明词性标注工具在中文处理中具有较高的准确率。

语义分析报告

语义分析报告

语义分析报告
根据任务需求,对文本进行语义分析可以从以下几个方面进行报告:
1. 实体识别:通过对文本进行实体识别,可以了解文本中包含的人名、地名、组织机
构名等实体信息。

通过识别实体,可以帮助理解文本的内容,提供更准确的语义分析
结果。

2. 关系抽取:通过对文本进行关系抽取,可以分析出文本中实体之间的关系。

例如,
可以分析出人物之间的关系(亲属关系、合作关系等)、地点之间的关系(居住关系、距离关系等)等。

关系抽取可以帮助进一步理解文本的语义含义。

3. 情感分析:通过对文本进行情感分析,可以判断文本中所表达的情感倾向。

例如,
文本的意思是否积极、消极或中性,可以帮助理解文本的观点、情感等信息。

4. 观点分析:通过对文本进行观点分析,可以分析出文本中所表达的观点或立场。

例如,可以判断文本的作者支持还是反对某个观点、行为等。

观点分析可以帮助理解文
本的立场、态度等信息。

5. 主题抽取:通过对文本进行主题抽取,可以识别出文本所讨论的主要主题或话题。

例如,可以从新闻报道中抽取出主要的新闻事件、从社交媒体中识别出热门话题等。

主题抽取可以帮助理解文本的重点内容。

以上是语义分析的一些常见任务和方法,根据具体的任务需求,可以选择适当的方法
进行分析和报告。

语义分析实验报告

语义分析实验报告

语义分析实验报告语义分析实验报告引言语义分析是自然语言处理领域中的重要研究方向,旨在理解和解释文本中的意义。

它涉及词汇、句法和语义的分析,以便将文本转化为机器可理解的形式。

本实验报告旨在介绍我们进行的语义分析实验,并分析实验结果。

实验目的本次实验的主要目的是使用现有的语义分析工具和技术,对一组文本进行分析,以探索其在语义理解方面的效果和限制。

我们希望通过实验,深入了解语义分析的原理和应用。

实验设计我们选择了一组新闻文章作为实验对象,这些文章涵盖了不同主题和语境。

我们使用了一种基于深度学习的语义分析工具,该工具能够将文本转化为向量表示,并通过计算向量之间的相似度来衡量语义相关性。

我们将对比不同文章之间的相似度,并分析结果。

实验过程首先,我们将文本数据进行预处理,包括去除停用词、标点符号和数字,以及进行词形还原和词干提取等操作。

这样可以减少文本噪音,提高语义分析的准确性。

然后,我们使用语义分析工具对预处理后的文本进行处理,将其转化为向量表示。

这些向量表示可以捕捉到文本中的语义信息,并用于计算相似度。

接下来,我们对不同文章之间的相似度进行计算,并将结果进行可视化展示。

我们使用了一种常见的相似度度量方法,如余弦相似度等。

通过比较不同文章之间的相似度,我们可以发现它们之间的语义关联程度。

实验结果我们发现,在相同主题的新闻文章中,语义分析工具表现出较高的准确性和一致性。

相似主题的文章通常具有较高的相似度,而不同主题的文章则具有较低的相似度。

这表明语义分析工具能够有效地捕捉到文本的语义信息。

然而,在处理一些语义复杂或上下文模糊的文章时,语义分析工具的效果有所下降。

这可能是由于工具在处理复杂语义结构时存在一定的局限性。

此外,工具对于一些专业领域的术语和特定语境的理解也存在一定的困难。

讨论与展望本次实验结果表明,语义分析在理解文本意义方面具有一定的能力和局限性。

在未来的研究中,我们可以进一步改进语义分析工具,以提高其对复杂语义结构和专业领域的理解能力。

语义分析实验报告

语义分析实验报告

实验三语法分析309 科3 李君林一.实验目的:通过使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。

二.实验内容(一)运行TINY的语义分析程序(二)扩充TINY的语法分析程序提示:考虑作用域(如:函数)和数组时可能需要修改符号表。

三.实验步骤1.先读懂TINY语义程序(相关联的文件:)(1)buildSymtab(syntaxTree); 充TINY的语法分析程序本次实验我首先将源程序实现的功能改成符合C_MINUS的符号表与类型检测然后加入没申明调用与数组调用错误即数组没申明而调用数组类型。

四.实验结果1.正确的测试程序/**/int gcd (int u,int v[]){if(v==0)return u;elsereturn gcd(v,u);}void main(void){int x;int y;read x;x=y=2;while(x>0)y=y-1;write y;return (gcd(x,y));}/**/运行结果:经检验测试程序代码无语义错误2.错误测试程序/**/int gcd (int u,int v[]){if(v==0)return u;elsereturn gcd(v,u);}void main(void){int x;int y;read x;t=1;x=y=2;x[2]=2;while(x>0)y=y-1;write y;return (gcd(x,y));}/**/实验结果:检测到13行 t没有申明检测到15行 x不是一个数组五.实验心得通过本次实验学会了使用、剖析和扩充TINY语言的语义分析程序,掌握编译器的语义分析程序的构造方法。

加深了对书本语义分析的理解,感受到学以致用的快感,增强对本课程的兴趣。

实验中遇到的最大问题:如何查询符号表判断数组,后面在其数据结构中增加了一个属性Len,如果不是数组将其赋为-1.六.关键程序代码()/****************************************************//* File: *//* Semantic analyzer implementation *//* for the TINY compiler *//* Compiler Construction: Principles and Practice *//* Kenneth C. Louden *//****************************************************/#include ""#include ""#include ""/* counter for variable memory locations */static int location = 0;/* Procedure traverse is a generic recursive* syntax tree traversal routine:* it applies preProc in preorder and postProc* in postorder to tree pointed to by t*/static void traverse( TreeNode * t,void (* preProc) (TreeNode *),void (* postProc) (TreeNode *) ){ if (t != NULL){ preProc(t);{ int i;for (i=0; i < MAXCHILDREN; i++)traverse(t->child[i],preProc,postProc);}postProc(t);traverse(t->sibling,preProc,postProc);}}/* nullProc is a do-nothing procedure to* generate preorder-only or postorder-only* traversals from traverse*/static void nullProc(TreeNode * t){ if (t==NULL) return;else return;}static void typeError(TreeNode * t, char * message){ fprintf(listing,"Type error at line %d: %s\n",t->lineno,message);Error = TRUE;}static void unDecError(TreeNode * t){ fprintf(listing,"Type error at line %d: the %s doesn't declaration\n",t->lineno,t->;Error = TRUE;}static void notArrayError(TreeNode * t){ fprintf(listing,"Type error at line %d: the ID %s isn't a Array\n",t->lineno,t->; Error = TRUE;}/* Procedure insertNode inserts* identifiers stored in t into* the symbol table*/static void insertNode( TreeNode * t){ switch (t->nodekind){ case StmtK:switch (t->{default:break;}break;case ExpK:switch (t->{ case IdK:if (st_lookup(t-> == -1){/* not yet in table, so treat as new definition */unDecError(t);.\n");printSymTab(listing);}}/* Procedure checkNode performs* type checking at a single tree node*/static void checkNode(TreeNode * t){switch (t->nodekind){ case ExpK:switch (t->{ case OpK:if ((t->child[0]->type != Integer) ||(t->child[1]->type != Integer))typeError(t,"Op applied to non-integer");if ((t-> == EQ) || (t-> == LT) || (t-> == BG)|| (t-> == LE) || (t-> == BG) || (t-> == UNEQ))t->type = Boolean;elset->type = Integer;break;case ConstK:case IdK:t->type = Integer;break;default:break;}break;case StmtK:switch (t->{ case SelK:if (t->child[0]->type == Integer)typeError(t->child[0],"if test is not Boolean");break;case IteK:if (t->child[0]->type == Integer)typeError(t->child[0],"while test is not Boolean");break;case WriteK:if (t->child[0]->type != Integer)typeError(t->child[0],"write of non-integer value");break;default:break;}break;default:break;}}/* Procedure typeCheck performs type checking * by a postorder syntax tree traversal*/void typeCheck(TreeNode * syntaxTree){traverse(syntaxTree,nullProc,checkNode); }。

语义分析实验报告(实验三)

语义分析实验报告(实验三)

编译原理语义分析实验报告软工082班兰洁200831104044一、实验内容二、实验目的三、实验要求四、程序流程图五、程序代码与主要过程说明六、测试用例七、输出结果八、实验心得一、实验内容定义模拟的简单语言的语义成分,将语义分析程序编制成一个子程序,在实验2分析出个语法单位后,分析其含义,并将可执行语句或表达式翻译成四元式输出,并将错误信息输出。

二、实验目的通过上机实验,加深对语义制导翻译原理的理解,掌握将语法分析所识别的语法成分变换成为中间代码的语义翻译方法。

三、实验要求采用递归下降语法制导翻译方法,对算术表达式、赋值语句进行语义分析并生成四元式序列。

例如:对于语句串Functiona=2+3*4;x=(a+b)/c;endfunc#输出的三地址指令如下●t1=3*4●t2=2+t1●a=t2●t3=a+b●t4=t3/c●x=t4四、程序流程图由于语义分析的的方法就是在语法分析过程中,根据每个产生式所对应的语义子程序进行翻译,为每个产生式配上一个翻译子程序,并在语法分析的同时执行这些子程序。

所有对应的流程图与语法分析流程图大同小异,关于各类函数的流程图我已经在词法分析报告与语法分析报告中详细画出,所以这里只说明程序主要流程。

五、程序代码与主要过程说明/*语义分析源代码*/# include<stdio.h># include<string.h># include<conio.h># include<malloc.h># include<STDLIB.H>struct quad // 四元式表{ char result[12];char ag1[12];char op[12];char ag2[12];};struct quad quad[30];int count=0;char *expression(void);char prog[200],token[9];char ch;int syn,p,m,n,sum=0;int kk=0,k=0;char *rwtab[6]={"function","if","then","while","do","endfunc"};void scaner(){ m=0;for(n=0;n<8;n++)token[n]='\0';ch=prog[p++];while(ch==' ')ch=prog[p++];if((ch>='a'&& ch<='z')||(ch>='A' && ch<='Z')){while((ch>='a'&& ch<='z')||(ch>='A'&&ch<='Z')||(ch>='0'&&ch<='9')){ token[m++]=ch;ch=prog[p++];}//end of whiletoken[m++]='\0';p--;syn=10;for(n=0;n<6;n++){if(strcmp(token,rwtab[n])==0){ syn=n+1;break;}}//end of for}else if (ch>='0'&&ch<='9'){ sum=0;while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}else{ switch(ch){ case'<':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){ syn=22;token[m+1]=ch;}else{ syn=20;ch=prog[--p];}break;case'>':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){ syn=24;token[m++]=ch;}else{ syn=23;ch=prog[--p];}break;case'=':m=0,token[m++]=ch;ch=prog[++p];if(ch=='='){ syn=25;token[m++]=ch;}else{ syn=18;ch=prog[--p];}break;case'!':m=0;token[m++]=ch;ch=prog[++p];if(ch=='='){ syn=22;token[m+1]=ch;}else{ syn=-1;}break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;default:syn=-1;}}//end of scaner}void emit(char *result,char *ag1,char *op,char *ag2) //将三地址代码送到四元式表{ strcpy(quad[count].result,result);strcpy(quad[count].ag1,ag1);strcpy(quad[count].op,op);strcpy(quad[count].ag2,ag2);count++;return;}char *newtemp() //返回临时变量t1,t2...{ char *p;char m[8];p=(char *)malloc(8);k++;itoa(k,m,10); //功能将整数装换为字符串。

实验三-语义分析-实习报告

实验三-语义分析-实习报告

实验三语义分析一、实习目的通过上机实习,加深对语法制时翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法.二、实习要求采用递归下降语法制导翻译法对算术表达式、赋值语句、条件语句、循环语句进行语义分析生成四元式序列。

三、实习过程实习代码;/***JavaCC file*/options {JDK_VERSION = "1。

5”;static=false;}PARSER_BEGIN(whileParse)package whileparse;import java。

io.FileInputStream;import java。

io.FileNotFoundException;import java.util。

ArrayList;public class whileParse {public int count=0; /*四元式标号*/public static ArrayList<Sys〉sysList = new ArrayList<Sys〉();public int ncount=0;/*临时变量下标*/public static void main(String args[]) throws ParseException {FileInputStream fileStream;t ry {fileStream = new FileInputStream("data/test.c");whileParse parser = new whileParse(fileStream);System.out。

println("Reading from standard input。

.”);System。

out。

println("Enter c programe only main()with only while();\" :");try {switch (parser.start()){case 0:System。

语义实验报告

语义实验报告

一、实验目的本次实验旨在探究语义理解在自然语言处理中的应用,通过设计一系列实验,验证不同语义分析方法在处理复杂文本数据时的效果。

实验将重点考察以下内容:1. 语义相似度计算方法在文本分类中的应用;2. 语义角色标注在信息抽取中的作用;3. 基于语义理解的文本摘要生成。

二、实验背景随着互联网技术的快速发展,文本数据呈爆炸式增长。

如何有效地处理和分析这些海量文本数据,提取有价值的信息,成为当前自然语言处理领域的研究热点。

语义理解作为自然语言处理的核心任务之一,对于文本数据的处理和分析具有重要意义。

三、实验方法本次实验采用以下方法:1. 语义相似度计算:采用余弦相似度和词嵌入(Word2Vec)两种方法计算文本之间的语义相似度,并将其应用于文本分类任务。

2. 语义角色标注:利用依存句法分析技术对文本进行语义角色标注,以提取文本中的关键信息。

3. 文本摘要生成:采用基于语义理解的文本摘要生成方法,对文本进行摘要,提取文本的主要内容和关键信息。

四、实验数据实验数据来自多个公开数据集,包括:1. 文本分类数据集:包含多个领域的文本数据,如新闻、论坛等。

2. 语义角色标注数据集:包含中文文本的依存句法标注数据。

3. 文本摘要数据集:包含多个领域的文本摘要数据。

五、实验结果与分析1. 语义相似度计算- 余弦相似度方法在文本分类任务中的准确率为85%,而词嵌入方法的准确率为90%。

这表明,词嵌入方法在语义相似度计算方面具有更高的准确率。

- 分析原因:词嵌入方法能够将文本中的词语映射到高维空间,使得语义相似的词语在空间中距离更近,从而提高了语义相似度计算的准确率。

2. 语义角色标注- 依存句法分析技术在语义角色标注任务中的准确率为78%,召回率为80%。

这表明,依存句法分析技术在提取文本关键信息方面具有较好的效果。

- 分析原因:依存句法分析能够准确地识别文本中的依存关系,从而有助于提取文本中的关键信息。

3. 文本摘要生成- 基于语义理解的文本摘要生成方法在文本摘要任务中的F1值为0.85。

编译原理实验:语义分析实验

编译原理实验:语义分析实验

实验四:语义分析一.实验目的:通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法二.实验要求:采用的是递归下降语法制导翻译法,对算术表达式,赋值语进行语义分析并生成四元式序列。

1.实验的输入和输出分别为以下:输入是语法分析后提供的正确的单词串,输出为三地址指令形式的四元式序列。

例如:对于语句串begin a:=2+3*4;x:=(a+b)/c end #输出的三地址指令如下所示:(1)t1=3*4;(2)t2=2+t1;(3)a=t2;(4)t3=a+b;(5)t4=t3/c;(6)x=t4;2.实验算法的思想为:(1)设置语义分析过程这其中用到的几个重要的函数的功能和代码如下面所列出的:1.emit (char *result ,char *ag1,char *op,char *ag2)该函数的功能是生成一个三地址语句送到四元式表中。

四元式表的结构如下:Struct {Char result[8];Char ag1[8];Char op[8];Char ag2[8];}quad[20];2char *newtemp()该函数的功能是回送一个新的变量名,临时变量的名称产生的顺序依次为T1, T2 ,……..Char *newtemp(){Char *p;Char m[8];P=(char *)malloc(8);K++;Iota(k,m,10);Strcpy(p+1,m);P[0]=’t’;Return (p);}(2)主程序的示意图如图所示:(3)函数lrparser在原来语法分析的基础上插入相应的语义分析动作,将输入串翻译成四元式序列,在实验中我们仅仅所作的是对表达式和赋值语句进行翻译。

三,实验程序源码代码如下:#include "stdio.h"#include "string.h"#include "ctype.h"char token[20] ;char prog[100];char ch;char *rwtab[6]={"begin","if","then","while","do","end"};int syn,p,m,n,sum;#define STACK_SIZE 100int compute(int x,char c,int y);int stack_num[STACK_SIZE];int num_top=-1;bool notfull_num(){if(num_top==STACK_SIZE)return false;elsereturn true;}void push_num(int value){if(notfull_num()){num_top++;stack_num[num_top]=value;}}void pop_num(){num_top--;}int num_top_value(){int m=stack_num[num_top];// printf("sing=====%d\n",m);return m;}bool empty_num(){if(num_top==-1)return true;elsereturn false;}char stack_operation[STACK_SIZE]; int operation_top=-1;bool notfull_operation(){if(operation_top==STACK_SIZE) return false;elsereturn true;}void push_operation(char c){if(notfull_operation())stack_operation[++operation_top]=c; }void pop_operation(){operation_top--;}char operation_top_value(){return stack_operation[operation_top];}bool empty_operation(){if(operation_top==-1)return true ;elsereturn false;}int compute(int x,char c,int y){int m;if(c=='+')m=x+y;else if(c=='-') m=x-y;else if(c=='*') m=x*y;else if(c=='/') m=x/y;return m;}struct {int result;int ag1;char op ;int ag2;}quad[20];void scanner();int findf(char c);int findg(char c);int findf(char c){if(c=='^' ) return 7;else if(c=='*') return 5;else if(c=='/') return 5;else if(c=='+') return 3;else if(c=='-') return 3;else if(c=='$') return 0;}int findg(char c){if(c=='^') return 6;else if(c=='*') return 4;else if(c=='/') return 4;else if (c=='+') return 2;else if(c=='-') return 2;else if (c=='$') return 0;}void main(){p=0;printf("please input the string\n");int quadsign=0;do{scanf("%c",&ch); //输入所需要的文字prog[p]=ch;p++;}while(ch!='#');p=0;push_operation('$');// printf("OK\n");do{ scanner();/*case 11:printf("(11,%d)",sum);break;case -1:printf("error");break;default:printf("(%d, %s)",syn,token);break;*/if(syn==11){ push_num(sum);// printf("sum==%d\n",sum);sum=0;}else if(syn==13||syn==14||syn==15||syn==16||syn==100){if( findf(operation_top_value()) <=findg(token[0]))push_operation(token[0]);else{do{quad[quadsign].ag2=num_top_value();pop_num();// printf("%d\n",quad[quadsign].ag2);for(int i=0;i<num_top;i++)// printf("stack==%d\n",stack_num[i]);//输出的为栈中的元素quad[quadsign].op=operation_top_value();pop_operation();quad[quadsign].ag1=num_top_value();pop_num();// printf("%d\n",quad[quadsign].ag1);quad[quadsign].result=compute(quad[quadsign].ag1,quad[quadsign].op,quad[quadsig n].ag2); //compute(int x,char c,int y);push_num(quad[quadsign].result);quadsign++;}while(!empty_operation()&&findf(operation_top_value())>findg(token[0]));push_operation(token[0]);}}}while(syn!=0);for(int i=0;i<quadsign;i++)printf("%d=%d%c%d\n",quad[i].result,quad[i].ag1,quad[i].op,quad[i].ag2); }void scanner(){for(n=0;n<8;n++)token[n]=0;ch=prog[p++];while(isspace(ch))ch=prog[p++];m=0; //设置token数组为空if(isalpha(ch)){while (isalnum(ch)){token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++){if(strcmp(token,rwtab[n])==0){syn=n+1;break;}}}else if(isdigit(ch)){while(isdigit(ch)){sum=sum*10+ch-'0';ch=prog[p++];}p--;syn=11;}elseswitch(ch){case'<':m=0;token[m++]=ch;ch=prog[p++];if(ch=='>'){syn=21;token[m++]=ch;}else if(ch=='='){syn=22;token[m++]=ch;}else{syn=20;p--;} break;case'>':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=24;token[m++]=ch;}else{syn=23;p--;}break;case':':token[m++]=ch;ch=prog[p++];if(ch=='='){syn=18;token[m++]=ch;}else{syn=17;p--;}break;case'+':syn=13;token[0]=ch;break;case'-':syn=14;token[0]=ch;break;case'*':syn=15;token[0]=ch;break;case'/':syn=16;token[0]=ch;break;case';':syn=26;token[0]=ch;break;case'(':syn=27;token[0]=ch;break;case')':syn=28;token[0]=ch;break;case'#':syn=0;token[0]=ch;break;case'$':syn=100;token[0]=ch;break;default:syn=-1;}}。

语义分析技术发展调研报告

语义分析技术发展调研报告

语义分析技术发展调研报告引言:自从计算机科学的发展以来,人工智能领域一直受到广泛关注。

随着大数据时代的来临,传统的数据处理方法已经无法满足现代社会的需求。

在这个背景下,语义分析技术应运而生。

本调研报告将对语义分析技术的发展进行调研与分析,旨在对该技术进行全面了解并为进一步研究与应用提供参考。

一、语义分析技术的概念与定义语义分析技术是指通过计算机算法和模型,对文本、语音或图像等数据进行处理与分析,以获取其隐含的语义信息。

其核心目标是理解和解释数据的本质含义,而非仅仅依赖于表面的形式特征。

语义分析技术主要包括自然语言处理、知识图谱、机器学习等相关技术的综合应用,旨在从海量数据中提取出有价值的知识。

二、语义分析技术的发展历程1. 早期发展阶段语义分析技术的萌芽可以追溯到上世纪50年代,当时的研究主要集中在机器翻译和自然语言理解领域。

然而,由于当时计算机性能的限制以及对大规模数据处理能力的缺乏,语义分析技术的发展进展较为有限。

2. 中期发展阶段随着计算机性能的提升和数据处理技术的发展,语义分析技术逐渐得到了较大的突破。

在这个阶段,自然语言处理和机器学习等相关技术迅速成熟,并开始应用于搜索引擎、智能问答系统等领域。

人们开始意识到语义分析技术的巨大潜力,并积极推动相关应用的探索与创新。

3. 当前发展阶段进入21世纪,随着深度学习和神经网络等技术的兴起,语义分析技术得到了进一步的推动和发展。

神经网络模型的引入使得语义分析技术在自然语言处理、图像识别、语音识别等方面取得了重大突破。

此外,知识图谱的建设和应用也为语义分析技术的发展提供了新的思路和方法。

三、语义分析技术的应用领域语义分析技术在如下领域得到了广泛应用:1. 搜索引擎优化:语义分析技术可以帮助搜索引擎更好地理解用户的搜索意图,提供准确的搜索结果。

同时,它还可以分析网页文本的语义信息,帮助网站优化关键词和内容。

2. 情感分析与舆情监测:语义分析技术可以对文本进行情感倾向分析,帮助企业或政府了解公众对特定事件或产品的态度和情感。

实验三 自下而上语法分析及语义分析

实验三 自下而上语法分析及语义分析

实验三自下而上语法分析及语义分析一、实验目的:通过本实验掌握LR分析器的构造过程,并根据语法制导翻译,掌握属性文法的自下而上计算的过程。

二、实验学时:4学时。

三、实验内容根据给出的简单表达式的语法构成规则(见五),编制LR分析程序,要求能对用给定的语法规则书写的源程序进行语法分析和语义分析。

对于正确的表达式,给出表达式的值。

对于错误的表达式,给出出错位置。

四、实验方法采用LR分析法。

首先给出S-属性文法的定义(为简便起见,每个文法符号只设置一个综合属性,即该文法符号所代表的表达式的值。

属性文法的定义可参照书137页表6.1),并将其改造成用LR分析实现时的语义分析动作(可参照书145页表6.5)。

接下来给出LR分析表。

然后程序的具体实现:●LR分析表可用二维数组(或其他)实现。

●添加一个val栈作为语义分析实现的工具。

●编写总控程序,实现语法分析和语义分析的过程。

注:对于整数的识别可以借助实验1。

五、文法定义简单的表达式文法如下:E->E+T|E-T|TT->T*F|T/F|FF->(E)|i上式中,i 为整数。

六、处理程序例例1: 正确源程序例:23+(45+4)* 40分析结果应为:正确的表达式。

其值为:1983例2: 错误源程序例:5+(56+)-24分析结果应为:错误的表达式:出错位置为)附录:源程序#include <stdio.h>#include"string.h"#include <iostream>using namespace std;#define R 30#define C 20typedef struct elem{char e[4];}Elem; //ACTION表与GoTo表中的元素类型Elem LR[R][C]; //存放ACTION表与GoTo表中的内容typedef struct out{int order; //序号int state[10]; //状态栈char sign[30]; //符号栈char grasen[20]; //产生式char input[30]; //输入串char explen[50]; //解释说明}OutNode; //输出结果中每一行的类型OutNode out[20]; //存放输出结果char Sentence[20]; //存放文法的一个句子char GramSent[10][20]; //存放文法的一组产生式int row,colno; //row为状态个数数,colno为ACTION表与GoTo表列总数int stateTop=0,signTop=0; //状态栈与符号栈的栈顶位置(值与栈中元素的个数相等)void input_GramSent(){int i,num;printf("请输入文法中产生式的个数\n");scanf("%d",&num);for(i=0;i<num;i++){printf("请输入文法的第%d个产生式\n",i);scanf("%s",GramSent+i-1);}printf("请输入文法的一个句子\n");scanf("%s",Sentence);printf("**********************************************************\n");printf("* 文法的产生式如下: *\n");printf("**********************************************************\n");for(i=0;i<num;i++)printf("%s\n",GramSent+i);printf("**********************************************************\n");printf("* 文法的句子如下: *\n");printf("**********************************************************\n");printf("%s\n",Sentence);}void input_LR(int row,int colno) //row为行总数,colno为列总数{int i,j;char mid[4];printf("**********************************************************\n");printf("* 提示:每输入一个元素后就回车 *\n");printf("**********************************************************\n");printf("请输入LR分析表的终结符(包括#)与非终结符\n");for(j=0;j<colno;j++)scanf("%s",LR[0][j].e);for(i=0;i<row;i++){printf("请输入%d号状态所对应的各列的元素,空白的地方用s代替\n",i);for(j=0;j<colno;j++){scanf("%s",mid);if(strcmp(mid,"s")==0||strcmp(mid,"S")==0)strcpy(LR[i+1][j].e," ");elsestrcpy(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<colno;j++)printf("%s ",LR[0][j].e);printf("\n");for(i=1;i<=row;i++){printf("%d ",i-1);for(j=0;j<colno;j++)printf("%s ",LR[i][j].e);printf("\n");}printf("\n");}int SignNum(char ch)//给定一个终结符或非终结符,返回其在ACTION表与GoTo表中的列位置int i;char c[2]="0";c[0]=ch;for(i=0;i<colno;i++)if(strcmp(c,LR[0][i].e)==0)return i;return -1;}int CharChangeNum(char* ch)//给定一数字字符串,返回其所对应的数字{int result=0;while(*ch!='\0'){result=result*10+(*ch-'0');ch++;}return result;}int OutResult(int s,int c,int i)//输出结果的第i+1行处理函数,(s 为状态,c为列){char mid[4],gra[20];int s_num,r_num;int n,len,j;strcpy(mid,LR[s+1][c].e);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);//s_num为S后的数字for(j=0;j<stateTop;j++)out[i+1].state[j]=out[i].state[j];out[i+1].state[stateTop]=s_num;out[i+1].state[++stateTop]=-1; //完成第i+1行的状态栈赋值strcpy(out[i+1].sign,out[i].sign);out[i+1].sign[signTop]=out[i].input[0];out[i+1].sign[++signTop]='\0'; //完成第i+1行的符号栈的赋值strcpy(out[i+1].grasen," "); //完成第i+1行的产生式的赋值strcpy(out[i+1].input,out[i].input+1); //完成第i+1行的输入符号串的赋值}else if(mid[0]=='r'||mid[0]=='R'){r_num=CharChangeNum(mid+1);//r_num为r后的数字strcpy(gra,*(GramSent+r_num-1));len=strlen(gra);for(j=0;j<len;j++)if(gra[j]=='-' && gra[j+1]=='>')break;n=strlen(gra+j+2);stateTop-=n; signTop-=n;for(j=0;j<stateTop;j++)out[i+1].state[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; //完成第i+1行的状态栈赋值strcpy(out[i+1].sign,out[i].sign);out[i+1].sign[signTop]=gra[0];out[i+1].sign[++signTop]='\0'; //完成第i+1行的符号栈的赋值strcpy(out[i+1].grasen,gra); //完成第i+1行的产生式的赋值strcpy(out[i+1].input,out[i].input); //完成第i+1行的输入符号串的赋值}return 1;}void OutputResult(int r){int i,j;printf("**********************************************************\n"); printf("* 句子:%s 用LR分析表规约过程如下:*\n",Sentence);printf("**********************************************************\n"); for(i=0;i<=r;i++){j=0;printf("%2d ",out[i].order);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()//输出结果的总控函数{int s_num,i=0;out[0].order=1; //序号赋值out[0].state[0]=0; stateTop=1; out[0].state[stateTop]=-1; //状态栈赋值,置栈顶位strcpy(out[0].sign,"#"); signTop=1; //符号栈赋值,置栈顶位strcpy(out[0].grasen," "); //产生式为空strcpy(out[0].input,Sentence); //以下两行为输入串赋值strcat(out[0].input,"#");strcpy(out[0].explen,"0和#进栈"); //解释说明//初使化输出结果的第一行while(1){s_num=SignNum(out[i].input[0]);//if(s_num!=-1)if(OutResult(out[i].state[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();r=OutControl(); //r为输出结果的行数OutputResult(r);}七、实验小结这个程序是从网上下载下来的,根据这个实验要求做了些更改,但是总是出现溢出错误,只能运行到LR分析表的部分(如截图),没有找到解决问题的办法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

软件学院实验卡和实验报告学号:xxxxxxxxxxx姓名:xxx年级专业班级:xxxxxxxxxxxxxxxxxxx xxx实验室组别:__ __ 实验日期:2xxx 年xx 月xxx 日输出的三地址指令如下:t1=3*4t2=2+t1a=t2t3=a+bt4=t3/cx=t4测试记录分析结论对于正确的语句串,例如:begin a:=2+3*4;x:=(a+b)/c; end#,运行结果如图:对于缺少赋值符号、“end”、“begin”、“(”、“)”等均可做出错误判断并给出相应提示。

小结实现了输出为三地址指令形式的四元式序列。

通过上机实验,加深了对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换为中间代码的语义翻译方法。

加深了对C++语言的用途的理解。

以下由实验教师填写记事评议平时成绩_______ 实验报告成绩________ 综合成绩 _________ 成绩评定指导教师签名:附录1 程序功能1.1 操作实例例如:对源程序begin a:=2+3*4;x:=(a+b)/c; end#进行判断;首先运行程序,程序出现提示:“请输入字符串,以#号结束:”,在光标处输入begin a:=2+3*4;x:=(a+b)/c; end#,回车,结果如图:程序给出了三地址码形式的四元式。

1.2 错误处理(1)如果用户在语句串开头处没有输入“begin”,程序提示“缺少begin!”;如果用户没有输入“end”,程序提示“end!错误”;(2)如果用户输入的语句串中缺少赋值符号(“:=”),程序提示“缺少赋值符号!”;(3)如果用户输入的语句串中“(”和“)”不匹配,程序提示“缺少“(”!”或“缺少“)!”。

2源程序#include<stdio.h>#include<string.h>#include <stdlib.h>char prog[80],token[8];char ch;int syn,p,m,n,sum;int kk=0,ii,N,nn=0;int k=0,t,i=0;char tt;char * keywords[6] = {"begin","if","then","while","do","end"}; //关键字表。

int scaner();int parser();int statement();int sentence();char *term();char *factor();char *expression();void emit(char *result,char *ag1,char *op,char *ag2);struct //四元式的结构。

{char resulted[8];char ag1ed[8];char oped[8];char ag2ed[8];}quad[20];void main(){p=0;printf("请输入字符串,以#号结束: \n");do{scanf("%c",&ch);prog[p++]=ch;}while(ch != '#'); //没有遇到结束符,则首先调用scaner()进行词法分析,之后进行语义分析。

p=0;parser();}char * newtemp(void) //返回一个新的临时变量名,临时变量名产生的顺序为t1,t2,…。

{char * P;char M[8];P = (char *)malloc(8);k++;itoa(k,M,10);strcpy(P+1,M);P[0] = 't';return(P);}int parser() //在语法分析的基础上插入相应的语义动作:将输入串翻译成四元式序列。

只对表达式、赋值语句进行翻译。

{int schain = 0;kk = 0;if(syn == 1){scaner();schain = sentence(); //调用语句串分析函数进行分析。

if(syn = 6) //“end”。

{scaner();if(syn == 0 && (kk == 0))printf("success");}else{if(kk!=1)printf("缺end错误"); // 输出“end”错误。

kk=1;}}else{printf("begin错误"); //输出“begin”错误。

}return(schain);}int sentence() //语句串分析函数。

{int schain = 0;schain = statement(); //调用语句分析函数进行分析。

while (syn == 26) //“;”。

{scaner();schain = statement(); //调用语句分析函数进行分析。

}return(schain);}int statement() //语句分析函数。

{char tt[8],eplace[8];int schain = 0;switch(syn){case 10:strcpy(tt,token);scaner();if(syn == 18) //赋值语句。

{scaner();strcpy(eplace,expression());emit(tt,eplace,"","");schain = 0;}else{printf("缺少赋值号"); //缺少“:=”错误。

kk=1;}return(schain);break;}char * expression(void){char * tp,* ep2,* eplace,* tt;tp = (char *)malloc(12); //分配空间。

ep2 = (char *)malloc(12);eplace = (char *)malloc(12);tt = (char *)malloc(12);strcpy(eplace,term()); //调用term分析产生表达式计算的第一项eplace。

while(syn == 13 || syn == 14) //加减。

{strcpy(tt,token);scaner();strcpy(ep2,term()); //调用term()分析产生表达式计算的第二项ep2。

strcpy(tp,newtemp()); //调用newtemp()产生临时变量tp存储计算结果。

emit(tp,eplace,tt,ep2); //生成四元式送入四元式表。

strcpy(eplace,tp);}return(eplace);}char * term(void){char * tp,* ep2,* eplace,* tt;tp = (char *)malloc(12);ep2 = (char *)malloc(12);eplace = (char *)malloc(12);tt = (char *)malloc(12);strcpy(eplace,factor());while(syn == 15 || syn == 16) //乘除。

{strcpy(tt,token);scaner();strcpy(ep2,factor());strcpy(tp,newtemp());emit(tp,eplace,tt,ep2);strcpy(eplace,tp);}return(eplace);char * factor(void){char * fplace;fplace = (char *)malloc(12);strcpy(fplace," ");if(syn == 10) //字母。

{strcpy(fplace,token);scaner();}else if (syn == 11) //数字。

{itoa(sum,fplace,10);scaner();}else if(syn == 27) //“(”。

{scaner();strcpy(fplace,expression());if(syn == 28) //有“)”。

scaner();else{printf("')'错误"); //只有“(”,缺少“)”。

kk=1;}}else{printf("'('错误");kk=1;}return(fplace);}void emit(char * result,char * ag1,char * op,char * ag2) //生成一个三地址码并返回到四元式代码中。

{strcpy(quad[nn].resulted,result);strcpy(quad[nn].ag1ed,ag1);strcpy(quad[nn].ag2ed,ag2);printf("(%d) %s=%s%s%s\n", nn+1,quad[nn].resulted,quad[nn].ag1ed,quad[nn].oped,quad[nn].ag2ed);nn++;}scaner() //此函数为词法分析。

{for(n=0;n<8;n++) token[n]=NULL;ch=prog[p++]; m=0;while(ch==' ') ch=prog[p++] ;if((ch>='a') && (ch<='z')) //判断是否是字母。

{while((ch>='a') && (ch<='z') || (ch>='0') && (ch<='9')) //判断下一个是否是字母或数字。

{token[m++]=ch;ch=prog[p++];}token[m++]='\0';p--;syn=10;for(n=0;n<6;n++)if(strcmp(token,keywords[n])==0) //判断是否匹配关键字。

{syn=n+1;break;}}else if(ch>='0' && ch<='9') //判断数字。

相关文档
最新文档