Yacc使用指南的认识.doc

  1. 1、本文档共7页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
YACC(BISON)使用指南 YACC(Yet Another Compile-Compiler)是语法分析器生成工具,它生成的是LALR分析器。Yacc于上世纪70年代产生,是美国贝尔实验室的产品,已经用于帮助实现了几百个编译器。 Yacc是linux下的工具,本实验使用的编译工具是cygwin(cygwin在windows下模拟一个linux环境)下的bison,它与Yacc的使用方法基本相同,只有很少的差别。 一.YACC的使用方法: 用户按照Yacc规定的规则写出文法说明文件,该文件一般以.y为扩展名(有的系统以.grm为扩展名。) Yacc编译器将此文法说明文件(假设该文件为filename.y)转换成用C编写的语法分析器文件filename.tab.c(如果在编译时加上某些参数还可以生成头文件filename.tab.h)。这个文件里至少应该包含语法分析驱动程序yyparse()以及LALR分析表。在这个文件里,语法分析驱动程序调用yylex()这个函数获取输入记号,每次调用yylex()都能获取一个输入记号。yylex()可以由lex生成,也可以自己用c语言写一个yylex()函数,只要每次调用该函数时返回一个记号即可。 用C编译器(本实验所给工具为cygwin下的gcc)将filename.tab.c编译为可执行文件(cygwin下默认为a.exe)。 a.exe即为可执行的语法分析器。 二.文法说明文件(即Yacc源程序)的写法: 文法说明文件,顾名思义,就是将一个语言的文法说清楚。在Yacc中,这个说明文件可以分为三部分,以符号%%分开: [第一部分:定义段] %% 第二部分:规则段 [%% 第三部分:辅助函数段] 其中,第一部分及第三部分和第三部分之上的%%都可以省略(即上述方括号括起的部分可以省略)。以%开头的符号和关键字,或者是规则段的各个规则一般顶着行首来写,前面没有空格。 1. 第一部分定义段的写法: 定义段可以分为两部分: 第一部分以符号%{和%}包裹,里面为以C语法写的一些定义和声明:例如,文件包含,宏定义,全局变量定义,函数声明等。 第二部分主要是对文法的终结符和非终结符做一些相关声明。这些声明主要有如下一些:%token,%left,%right,%nonassoc,%union,%type,%start。下面分别说明它们的用法。 %token定义文法中使用了哪些终结符,定义形式为: %token TOKEN1 TOKEN2 TOKEN3 …. 其中TOKEN1,TOKEN2等为终结符,终结符一般全大写。 %left,%right,%nonassoc也是定义文法中使用的终结符,定义形式与%token类似,但是他们定义的终结符具有某种优先级和结合性,%left表示左结合,%right表示右结合,%nonassoc表示不可结合(即它定义的终结符不能连续出现:例如,如果文法中不允许出现形如abc的句子,则就是不可结合的)。而优先级关系则是以他们定义出现的顺序决定的,先定义的优先级低,最后定义的优先级最高,同时定义的优先级相同。例如,如果有如下定义: %left A B %nonassoc C %right D 则表示优先级关系为: A=B C D,而结合性关系为:A,B左结合,C不可结合,D右结合。 %start指定文法的开始符号(非终结符),定义形式为: %start startsym ,其中startsym为文法的开始符号。如果不使用%start定义文法开始符号,则默认在第二部分规则段中定义的第一条产生式规则的左部非终结符为开始符号。 %union和%type用来处理文法中各符号所带的属性。在词法分析的学习中,我们知道记号是由记号名和记号的属性值两部分组成的,文法中的终结符就是记号,他们有属性值,同样,非终结符也是可以有属性值的。 Yacc维护一个栈来保存文法符号的“属性值”,这个栈与移进-归约分析中的文法符号栈是对应的:即,如果移进归约分析栈中某个位置存放文法符号X,则对应的Yacc“属性值”栈中就存放X的属性值。 Yacc将这个属性值栈的栈内元素的类型定义为YYSTYPE(这是一个宏),默认状态下,YYSTYPE定义为int类型,你可以在文法说明文件第一部分定义段中重新定义YYSTYPE为其他类型,例如,用 #define YYSTYPE double 将其定义为double类型。 如果你想让属性值栈可以存放多种类型的属性值,例如整型和字符串型等(这在很多情况下是需要的,比如你希望标识符ID的属性是字符串而整型数NUM的属性是整型值),你最好将属性值栈元素的类型定义为一种union类型,此时,你可以用%union来定义它。例如,如下

文档评论(0)

xuefei111 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档