实验要求

运用YACC,针对TINY语言,构造一个语法分析器。

实验方案

1.文法:

exp → exp addop term|term
addop → +|-
term → term mulop factor|factor
mulop → *
factor → (exp)|number

2.设计输入文件内容:

(注:无换行)

3.设计应有的输出:

4.Lex与Yacc的数据传递原理与方法
首先,在设计程序中,由于定义了自己的main()函数,它在某个点上调用了yyparse()。YACC会创建相应的yyparse()函数,并在y.tab.c中结束该函数。

yyparse()函数读取一个『标识符/值对』(token/value pairs)流,这些流需要事先就提供,这些流可以是手写的代码提供的,也可以是lex生成的。而在lex与Yacc的联合使用中,把这个工作丢给了lex。

每次yylex()调用都会返回一个整数值,该值代表了一个标识符类型(token type)。它告诉Yacc,已经读取了这种标识符。该标识符可以有一个值,它应该存放在yylval变量中。

但是在该文法中,yylval的变量类型并不是始终都是同一种类型,可以看到主要有int类型的number和char类型的’+’,’-’,’*’。

所以在这里为yylval定义了%union来解决这个问题,通过

%union{char chr;int integer;
}

让yylval包含了一个char型的变量与一个int型的变量来获取从lex中得到的数据,之后再利用

%token <integer> number
%type <integer> exp
%type <chr> term factor

来标识number、exp、term、factor的类型,%token表示这是一个终结符的类型,而%type只是标注类型。
之后,在lex语句中也需要修改,通过类似于从结构体中获取变量的
yylval.integer=atoi(yytext);
来控制返回的变量。

%left 表示左结合,%right 表示右结合。最后列出的定义拥有最高的优先权。因此在这个例子中乘法拥有比加法和减法更高的优先权。+ - * 所有这三个算术符都是左结合的。运用这个简单的技术,我们可以消除文法的歧义。

 %left '+' '-'%left '*'

分析表parsing table

理论和设计(描述parsing table在实验方案中的作用,观察并输出parsing table)
分析表:

分析表包含action动作表以及goto转移表,action表的每一列,对应文法中的终结符号或者$,每一项表示一个语法分析动作,goto表中的每一列对应着文法中的非终结符,每一项表示某一项遇到的每一个状态遇到某一非终结符进入的状态。
sn:将符号a、状态n压入栈
rn:用第n个产生式进行规约
利用win_bison -v test_yacc.y生成分析表

生成test_yacc.output文件
分析表:

四、内容和步骤
1、针对TINY语言给出 yacc的y文件的代码:
test_yacc.y

%{#include <stdio.h>
#include<ctype.h>
%}%union{char chr;int integer;
}%token <integer> number
%type <integer> exp
%type <chr> term factor
%left '+' '-'
%left '*'%%
command : exp { printf("the end of this calculation is %d\n",$1); };/*允许打印结果*/   exp     : exp '+' term { $$ = $1 + $3; }| exp '-' term { $$ = $1 - $3; }| term { $$ = $1; };term    : term '*' factor { $$ = $1 * $3; }| factor { $$ = $1; };factor  : number       { $$ = $1; }| '(' exp ')'  { $$ = $2; };
%%int yyerror(char *s)
{fprintf(stderr,"error:%s\n",s);return 0;
}       

2、给出.l文件的代码:
test_lex.l

%{#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#define false 0
#define ture 1
#include "test_yacc.tab.h"
%}digit [0-9]%%
{digit}+   {yylval.integer=atoi(yytext);printf("number:%d\n",yylval.integer);return(number);
}\+   {yylval.chr=yytext[0];printf("opterator:%c\n",yylval.chr);return('+');
}\-   {yylval.chr=yytext[0];printf("oprator:%c\n",yylval.chr);return('-');
}\*   {yylval.chr=yytext[0];printf("oprator:%c\n",yylval.chr);return('*');
}"("   {yylval.chr=yytext[0];printf("separator:%c\n",yylval.chr);return('(');
}")"   {yylval.chr=yytext[0];printf("separtor:%c\n",yylval.chr);return(')');
};   {return(';');
}[ \t]+  {printf("lexical analyzer error\n");/*忽略空格*/
}quit  {printf("Bye!\n");exit(0);
}%%
int yywrap()
{return(1);
}

3.main函数代码:
main2.c

#include"lex.yy.c"
#include"test_yacc.tab.c"
#include <stdlib.h>
#include <stdio.h>
extern int yyparse();int main(int argc, char* argv[]){extern FILE *yyin;if((yyin=fopen("test.txt","rt"))==NULL){perror("无法打开文件test.txt\n") ;exit(1);}if (yyparse()==1){fprintf(stderr,"parser error\n");exit(1);}printf("yyparse() completed successfully!\n");return 0;
}

3、实验具体步骤
安装flex和bison。flex和 bison 是两个用来生成程序的工具,它们用来词法和语法分析器。flex 和 bison 本身不是词法或语法分析器,利用它们生成的程序才是。
新建文本文件,更改名称为test_lex.l,敲入代码,新建文本文件,更改名称为test_yacc.y,敲入代码(后缀不能改,名称自己取,但是要注意不同名字下#include”test_yacc.tab.c”不一样,需要更改)
打开控制台,进入到刚才所建立文件所在的文件夹,输入:

得到:

之后加入test.txt文件并写入算式文本,并对主函数文件main2.c进行编译运行

五、实验结果:
截图

六、实验结论:
分析和总结
  利用工具的可以在实现语法分析和词法分析的时候,只需要根据lex和yacc工具给出的格式进行编写就可以很轻松的完成词法分析和语法分析,不用考虑整个程序的流程,等琐碎的细节,并且可以使用工具轻松输出分析表。
  手写编程程序来进行词法分析和语法分析,可以较为全面的把控所有的细节,对于输入,输出,token的定义,等等方面可以进行更加详细的设计。但缺点也很明显,对于初学者来说需要更大的学习成本,并且在手写编程的过程中若对原理不熟练会出现各种各样的问题,整个过程相对更耗时,需要更多时间才能体会到语法分析器的妙用。
实验中出现的冲突及解决过程描述
  使用%union之后,%token number语句中,%token是用来描述终结符,而%type才是非终结符的类型描述。
  使用%left语句需要确定’+’、’-’和’*’的优先级
  需要确定编译的顺序,确保顺序正确,按步骤执行,才能正确

基于YACC的TINY语法分析器的构建相关推荐

  1. 《编译原理》实验报告——基于YACC的TINY语法分析器的构建

    一.实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验方案 (1)设计基于LEX的TINY词法分析器 (2)设计基于YACC的TINY语法分析器 ( ...

  2. 编译原理——实验叁——基于YACC的TINY语法分析器的构建

    一. 实验要求 运用YACC,针对TINY语言,构造一个语法分析器.给出实验方案,实施并描述结果. 二. 实验方案 (1)设计基于YACC的TINY词法分析器 (2)设计基于LEX的TINY语法分析器 ...

  3. 编译原理——实验叁预习报告——基于YACC的TINY语法分析器的构建

    一.实验目的: 运用YACC,针对给定的文法,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验预习提示 1.表达:针对5.5节中的calculator文法,设计输入和输出 2.观察:观察p ...

  4. 《编译原理》实验预习报告——基于YACC的TINY语法分析器的构建

    一.实验目的 运用YACC,针对给定的文法,构造一个语法分析器.给出实验方案,实施并描述结果. 二.实验预习提示 1.表达:针对5.5节中的calculator文法,设计输入和输出 2.观察:观察pa ...

  5. 《编译原理》实验报告——递归下降语法分析器的构建

    一.实验要求 运用递归下降法,针对给定的上下文无关文法,给出实验方案.预估实验中可能出现的问题. 二.实验方案 1.构造LL(1),通过设计.编制.调试递归下降语法分析程序,对输入的符号串进行分析匹配 ...

  6. 递归下降语法分析器的构建_一文了解函数式查询优化器Spark SQL Catalyst

    大数据技术与架构点击右侧关注,大数据开发领域最强公众号! 暴走大数据点击右侧关注,暴走大数据!记录一下个人对sparkSql的catalyst这个函数式的可扩展的查询优化器的理解,目录如下: 0. O ...

  7. yacc语法分析minipascal_语法分析器 YACC实验报告

    课程名称 编译原理课程设计 实验课时 实验项目 基于 YACC 的语法分析器 实验时间 实验目的 1 . 学习基于 YACC 的语法分析器的构造方法. 2 . 学习 C- 的语法结构. 实验环境 Pa ...

  8. 基于Java语言的语法分析器

    LR(0)语法分析器 实验目的: 根据LR(0)语法分析的原理,编写.调试一个语法分析代码程序,对输入的句子进行分析. 实验工具: 使用了Java语言进行编写 ,使用Java开发工具IntelliJ ...

  9. 基于c语言的语法分析器的实现

    一. 总体实现思想 我采用自顶向下的预测分析技术来实现,其基本方法如下: 从文法开始符号出发,在每一步推导过程中根据当前句型的最左非终结符A和当前输入符号a,选择正确的A-产生式.为保证分析的确定性, ...

  10. 编译原理实验-递归下降语法分析器的构建

    实验目的: 针对给定的上下文无关文法,编制一个递归下降分析程序. 分析: 递归下降语法分析的前提是保证LL(1)文法 递归下降的思路就是暴力dfs.对每个程序直接不管三七二十一搜进去,只要能搜到就继续 ...

最新文章

  1. I/O多路转接之 select
  2. lda主题模型应用java_主题模型LDA及在推荐系统中的应用
  3. c 调用易语言dll字节集,总结VC与易语言DLL互相调用的方法
  4. AI繁荣下的隐忧——Google Tensorflow安全风险剖析
  5. C#基础第三天-作业-集合-冒泡排序-模拟名片
  6. 一台linux上运行多个mysql_linux下同时运行多个mysql
  7. MVC中@Html.DisPlayFor(model=model.newsName)和 @Model.newsName的区别
  8. XOS 源码详解2: os_s_xxxx.s 汇编代码的段定义AREA,程序入口ENTRY,程序结尾END.
  9. Hibernate读书笔记---继承映射
  10. 【PetShop 4.0学习】1.技术特点
  11. Array类filter方法实例--查找功能.
  12. OpenCV(二)OpenCV的介绍和发展
  13. 《变革中的思索》连载九:放飞的爱——母亲和我
  14. 【Vulnhub靶场】NOOB: 1
  15. CCS中的linked resource
  16. 网页中视频在线播放脚本
  17. 概率论---古典概型
  18. Java学习:从入门到精通week4
  19. Jenkins自动化部署阿里云K8s
  20. 网页版白噪声A Soft Murmur

热门文章

  1. VC中调用 Excel 的总结
  2. 原来做浏览器这么简单
  3. cvErode() 形态腐蚀(可多次)
  4. c语言线性拉伸0到255,数字图像处理作业题.doc
  5. java集合复习笔记-java集合继承关系图
  6. OpenCV学习笔记__特征检测与匹配之 SURF算法(转)
  7. MaxPooling里面的padding
  8. C#-SpecialFolder-特殊路径获取
  9. LINUX 7.0真机系统安装问题
  10. js如何获取php中的变量的类型,js获取变量的类型