ImageVerifierCode 换一换
格式:DOCX , 页数:15 ,大小:30.20KB ,
资源ID:5629475      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/5629475.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(构建编译器的工具.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

构建编译器的工具.docx

1、构建编译器的工具构建编译器的工具By Richard A. Sevenich 翻译:iNDY第一部分: JFlex 和 CUPby Richard A. Sevenich, Department of Computer Science, Eastern Washington University March 25, 1999 在UNIX世界里,传统上有两种在功能上互补的编译器构造工具存在。 一种用来构造编译器的词法分析程序(又称为“词法分析器”或者是“词法扫描程序”)例如:lex、JLex、JFlex等 另一种则是用来构造分析程序语法的程序(通常称为“语法分析器”或者“词法分析器”、“词法程序

2、”)例如:byacc、bison、CUP 这些工具,在Linux/GNU平台上你都可以轻易找到,而且通常是GPL版权的自由软件。(比较广泛使用的编译器生成工具还有PCCTS和Antlr )需要指出的是,词法分析和语法分析只是一个语言解释器的基本部分。一个使用上述工具构造的出来的词法分析器和语法分析器无法完成另一件至关紧要的事生成目标代码。不过这些工具通常提供给编程者一些被称为“钩子”的接口,使用者可以使用它将代码生成部分和词法及语法分析器合为一体。 在以后的文章中,我将简单介绍两种具有代表性的编译工具:JFlex和CUP。我要在选修我的编译器设计课程的学生中选一些来帮助我共同完成这篇文章。最终

3、。我希望能够使那些对这些工具还不十分熟悉的人能够熟练的使用它们。之所以选取JFlex和CUP是因为它们可以用来实现基于JAVA语言的编译器,这也是我学习JAVA的一个好机会。同样,对JAVA的不了解也成为我的“替罪羊”(委过的猪肉 )。当我犯错误时,我可以归罪于对JAVA不熟悉。 第一部分将为以后的内容提供一个背景介绍。下一部分将告诉你如何得到这些工具以及如何安装和使用,我还会提供一个简单的创建应用的例子。第三部分将给一个实际的应用实例(在下面会介绍)。如果第三部分过大而无法一次刊出,会将它分成几个部分依次刊登。 词法分析器 语言转换器的作用是将某种语言的源代码转换成另一种语言的目标代码。传统

4、的编译器一般是将源码转换成汇编语言或机器语言但这并不是我们在以后的文章中所要讨论的重点。语言转换器处理过程的第一步一般是做类似于英文教师检查一篇英文短文,确定文中是否存在单词拼写错误这样的一个动作。所不同的是词法分析器代替了英文教师的角色,而检查的对象就是源代码。词法分析器挨个检查那些符号是否构成合法的单词。词法分析器将: 辨认出“while”是一个关键字 辨认出“47452”是一个十进制数字 报告字符串“fr%$glp:) ”是一个无法辨认的字符串 词法分析器就类似一个源代码的拼写检查器 一个象JFlex这样的词法工具,从一个指定的文件中读入词法规则,然后生成相应的词法分析器。我们不妨假设某

5、个程序员需要定义一个名为pronto的语言,于是他将语言pronto的有效词法规则写在一个叫pronto.flex的文件中。然后再以命令行方式执行操作:JFlex pronto.flex。这样他就可以得到一个叫Lexer.java的JAVA程序,这个程序就是一个JAVA版本的pronto的词法分析器。 当然,这样一个单独的词法分析器仅有简单的功能,它除了可以告诉你程序是不是完全由合法的单词组成之外不能完成任何其他事情。我们要讨论的词法分析器可以做更多的事情。它们和句法程序共同完成一些任务(在下一个标题中我们会讨论这个问题)。在典型的应用中,词法分析器实际上是被句法程序调用以完成以下任务: o

6、辨认出一个词,并将该词相对应的标志值返回给句法程序; o 传送给句法程序与这个被辨认出来的字符串相关的信息,或者是这个整数的数值; o 在辨认出单词之后,调用一些可编程的函数。 这三项任务中的第一项使得词法分析器可以支持句法程序完成它的最重要的工作,句法分析。而其余两项任务对于句法程序最终生成目标文件是相当有用的。 句法分析器(又称句法程序) 继续上一节的话题,如同词法分析器检查拼写错误一样,句法分析器通过检查源文件来保证所有的“单词”都是按照有效的语法规则排列的。举例来说,对于某种“新”语言,词法分析器将会判断下面六个单词有效,并将它们报告给句法程序: if + while -词法分析器只关

7、心单词和符号的有效性,而不在乎它们出现的地方。不过,句法程序将会指出 if + while 是一个不合法的组合。这就好象是词法分析器只检查拼写错误,而句法程序检查句法错误。 注意:实际编译器中的词法规则都是通过非常简单的所谓“正则语法”表达式描述的,而语法分析器的语法规则则是通过较为简单的“上下文无关语法”表达式描述的。相关描述可以参照Chomsky hierachy的Typical compiler design books一书中有相关的理论介绍(国内的朋友可以参考编译原理的相关书籍) 象CUP这样的工具,是通过从指定的文件中读入相应语言的语法规则的定义来生成对应的句法程序。我们继续使用虚构

8、的新语言pronto,程序员需要将语法规则写入指定的文件pronto.cup内,然后在命令行下执行java java_cup.Main mkdir javatools mkdir javatools/CUP 然后修改你的 .bash_profile 和 .bashrc 文件,包含所需的 java CLASSPATH 等。这里是一些示例行: JAVB=/usr/lib/jdk1.1 JAVT=/home/jsmith/javatools CLASSPATH=./:$JAVB/lib/classes.zip:$JAVT/JFlex/lib/JFlex.jar:$JAVT/CUP PATH=$PAT

9、H:$JAVB/bin:$JAVT/JFlex/bin export PATH CLASSPATH 注意:目录 /usr/lib/jdk1.1 是用于指示从 blackdown 的 tarball里解开的文件所放的地方。在作者 的实际情况中,它是一个到 /usr/lib/jdk1.1.5v5-980311/ 的符号连接。 要使你的这些修改起作用,你必须退出系统,再重新注册。 2.0 JFlex2.1 得到 JFlex JFlex 可以从 www.informatik.tu-muenchen.de/kleing/jflex/index.html#Download 得到,是一个 tar.gz 格式

10、的文件。在写本文的时候,该文件的名字是 jflex-1.2.tar.gz。这个 tar 包包括一个 自带安装指南的丰富文档。 2.2 一个具体的安装情形 下载tar 包,jflex-1.2.tar.gz, 到javatools/ 目录中; 用命令tar xvfz jflex-1.2.tar.gz在javatools/目录中展开tar 包。 这样就会创建带有相关的子目录树的目录JFlex。它将含有所有需要的东西,包括在doc子目录中 的文档。这儿的文档内容详尽,指出了怎样用 JFlex 来创建独立的词法分析器(例如下面2.3节中的例子) 或是用于其它程序(如CUP)创建的处理器的词法分析器。在目

11、录 JFlex/bin 中你可以找到一个 Shell脚本 程序jflex,它需要做如下修改: 设置 JFLEX_HOME 变量: JFLEX_HOME=/home/jsmith/javatools/JFlex (根据你的环境) 设置 JAVA_HOME 变量: JAVA_HOME=/usr/lib/jdk1.1 (根据你的环境) 2.3 对安装进行测试 切换目录到 javatools/JFlex/examples/standalone (例如, cd /home/jsmith/javatools/JFlex /examples/standalone/) 执行该目录中的 README 文件中的指

12、令,会得到如下的屏幕输出: Hello someone! This is a sample input file for the standalone example scanner. Have a nice day!3.0 CUP3.1 得到 CUP CUP 从 www.cs.princeton.edu/appel/modern/java/ 得到。在那儿你能找到所需的源代码(压缩的tar包) 和用户手册。这个手册可以html 方式下载以提供一个在线的手册或者以适于打印的形式(如 postscript) 下载。下一节将讨论下载源代码的问题。 注:上述的 Web 站点还有一个 JFlex 的变种

13、,叫JLex。 3.2 一个 CUP 的具体的安装情形, 包括测试 下载压缩的tar 包到javatools/CUP 目录中; 切换到那个目录中 (如,cd /home/jsmith/javatools/CUP) 展开tar 包 键入命令行: ./INSTALL, 来运行安装/测试文件。注意安装程序是一个 csh,或它的替代物 tcsh 的脚本。所以,tcsh 是需要的。这样将得到一个成功的消息:Install and test was successful。 4.0 下一步随 JFlex 和 CUP 下载的文档提供了足够的信息让用户把它们运行起来。版权所有 (C) 1999 NJLUG出版于

14、第41期Linux公报1999年5月 中文版第七期译者注: 本篇介绍的是在Linux下使用Java 版的词法生成器和语法生成器来构造一个编译器, 本文的示例是经典的计算器的例子, 即把计算器支持的表达式看作一种简单的语言来处理. 这里, 词法器是JFlex, 即 Flex 的Java 版, CUP 全称是: (Java Based) Constructor of Useful Parsers, 相当于常用的 Yacc. 用 JFlex 和 CUP 创建一个计算器Christopher Lopes, 东华盛顿大学学生 1999 年 4 月 26 日 这是一个系列文章的第三篇,第一篇登载在 199

15、9 年 4 月号的 Linux 公报(Gazette)见:编译器构造工具,第一部分。第二部份提供了详细的JFlex和CUP的安装指南,也登载在本期的公报中。 本篇的这个具体的例子是CUP手册中的那个计算器例子的修改版本。特别的,我们包含了随同的用于JFlex的详细说明文件。而且,这个文件以及关联的CUP的详细说明文件都有大量的注释。计算器例子是显示如何使用 lex/yacc 系列工具的经典例子。我们现在正在进行一个包含更深一步的例子的项目-一个用于模糊逻辑引擎的初始化语言,它用作决策产生应用。如果对于这个项目的长期有足够兴趣的话,我们将准备一篇文章在这儿或别的地方发表。 使用 JFlex 使用

16、 CUP 我们的计算器程序的主体 编译计算器程序 计算器的输入输出的例子 使用 JFlex 这个项目中使用 JFlex 的目的是为我们的计算器创建一个词法分析器。这个词法分析器,或者叫扫描器,将为我们计算器检查输入,而且确认所有的字符归类是有效的。 用于 JFlex 的词法分析说明文件可以分成三个部分。每个部分由 % 分开。 用户代码段 % 参数设置和声明段 % 词法规则段 用户代码段 这个段中的所有内容将被拷贝到生成的词法类的类声明之前。在这个段中,常见的是 package 和 import 语句。我们的词法说明在这个段中引入(import)了两个类,sym 和 java_cup.runti

17、me.*,如下所示: import java_cup.runtime.*; import sym; 在我们的例子中,sym 类(与处理器一起)由CUP产生。 参数设置和声明段 这个段含有参数,词法状态,和宏定义。设置参数将包含额外的代码,它们将被包括在产生的扫描器类。参必须另开新行,以 % 开头。可以包含的参数很多。在随 JFlex 来的手册中可以得到一个可以包含的参数列表。在我们的词法说明中用到的参数如下: %class Lexer %line %column %cup 第一个参数,class Lexer,告诉 JFlex 把生成的类命名为Lexer并把代码写到名为Lexer.java的文件

18、。参数 Line打开行计数,使你可以用变量yyline存取输入的当前行号。参数column有类似的作用,除了它是通过变量yycolumn存取当前列号。最后一个参数,cup,把JFlex设置成一个特殊模式,使它与CUP产生的处理器兼容,我们使用的就是。 然后,你可以声明扫描器用到的成员变量和函数。可以加入的代码是Java代码,并放在 % 和 %之间。它们将被拷贝到生成的词法类源代码中。在我们的词法说明中,声明了两个成员函数。这些函数创建java_cup.runtime.Symbol对象。第一个仅仅记录当前记号的位置信息。第二个还包含了记号的值。以下是到这个声明的连接。 Declarations

19、这个段的最后是宏定义。宏用作正则表达式的缩写。一个宏定义包含一个宏标识符,其后为一个=,然后是宏要代表的正则表达式。如下是一个我们的词法说明中用到的宏定义的连接。还有一个连接包含了一个列表,列出了创建正则表达式可用的东西,及每一项的含义。 Macro Declarations 可用于创建正则表达式的列表 词法规则段 词法分析说明的最后一段包含正则表达式和当扫描器匹配了相关的正则表达式后所要执行的动作。扫描器会激活具有最大匹配的表达式。所以如果存在两个正则表达式to和too,扫描器会匹配too,因为它是最长的。如果两个正则表达式完全相同,具有相同的长度,那么扫描器将匹配最先列在说明中的表达式。假

20、设扫描器读进了字符串to,它试图在下面所列的正则表达式中寻找一个来匹配所读入的。第二个正则表达式是可选的,因为它包含的字符串类是可以匹配字符串to的。但扫描器会选择列表中的第一个正则表达式,因为它列在最前面。 to a-z* 每个正则表达式可以附带动作,这样当扫描器匹配了正则表达式后就可以激活它的动作。每个正则表达式的动作就是你可以写的Java代码片段。你想要的动作可以是打印出一些东西,或是返回扫描器发现的标识符给处理器。用于打印出扫描器发现的标识符并且返回给处理器的示例代码如下所示: + System.out.print(+); return symbol(sym.PLUS); - Syst

21、em.out.print(-); return symbol(sym.MINUS); * System.out.print(*); return symbol(sym.TIMES); / System.out.print(/); return symbol(sym.DIVIDE); JFlex 允许程序员定义特殊的词法状态(lexical states)用作开始条件来细化说明。YYINITIAL 是一个预定义的词法状态,是词法分析器初始扫描输入的状态。它是我们将用的唯一状态。所以,我们所有的正则表达式都将从这个词法状态开始识别。然而,可以定义其它这样的状态,本质上说将建立一个状态机的新的分支的

22、开始。在下面的例子中,从 YYINITIAL 通过一个变换到达词法状态。在这个状态段定义的正则表达式将只能在这个分支中被识别。 string.setLength(0); yybegin(STRING); = return symbol(sym.EQ); = return symbol(sym.EQEQ); + return symbol(sym.PLUS); yybegin(YYINITIAL); return symbol(sym.STRINGLITERAL, string.toString(); nr+ string.append(yytext(); 在如上的代码中,扫描器将从状态 YYINITIAL 开始。当它匹配了正则表达式,也就是找到了一个双引号,它将把状态转换到 STRING 状态。那么现在能够匹配的正

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1