第1章概述 1.4.4.2Ant 1、安装ANT 你可以从http://ant.apache.org下载Ant压缩包,然后解压到某个目录,假设记为 D:DE\ant,在环境变量中加入名为ANT_HOME的环境变量,值为ant所在的解压路径。再 在PATH环境变量中加入%ANT_HOME%bin(针对Windows环境)即可。 2、编写Ant的编译文件 Ant的作用如同Make,它自动地执行编译文件中所定义的任务。编译文件是用XM 语言描写的ant任务配置文件,它的默认名为build.xml。 <project name="MyProject"default="run"basedir="" <property name="SRC_DIR"location="S(basedir)/sre" <property name="DEST_DIR"location="(basedir)/bin" <property name="DOC_DIR"location="basedir)/doc" path id="project.class.path" <pathelement location="S(DEST_DIR) </path> <target name="build"> <mkdirdir="S(DEST_DIR)/> javac sredir="S(SRC_DIR)"destdir="DEST DIR!" <jar destfile="myproject.jar"basedir="(DEST_DIR)"> </target> <target name="doc"> <mkdir dir="S(DOC_DIR)"/> <javadoc sourcepath="S(SRC_DIR)"destdir="S(DOC_DIR)"Locale="en_US"> </target> <target name="run"depends="build"> <java classname="Scope Variable"> <classpath refid="project.class.path">/classpath> <classpath <pathelement location="DEST_DIR;"> </classpath- </java> </target> </project 图1-14一个ant编译文件示例 图1-14给出了一个at编译文件示例,下面结合这个例子来说明编译文件的内部结构。 工程(project:)每个编译文件实际上是一个工程,故在ant编译文件中,project元素是 20
第 1 章 概述 20 1.4.4.2 Ant 1、安装 ANT 你可以从 http://ant.apache.org下载Ant压缩包,然后解压到某个目录,假设记为 D:\IDE\ant,在环境变量中加入名为ANT_HOME的环境变量,值为ant所在的解压路径。再 在PATH环境变量中加入%ANT_HOME%\bin(针对Windows环境)即可。 2、编写 Ant 的编译文件 Ant 的作用如同 Make,它自动地执行编译文件中所定义的任务。编译文件是用 XML 语言描写的 ant 任务配置文件,它的默认名为 build.xml。 <project name="MyProject" default="run" basedir="."> <property name="SRC_DIR" location="${basedir}/src"/> <property name="DEST_DIR" location="${basedir}/bin"/> <property name="DOC_DIR" location="${basedir}/doc"/> <path id="project.class.path"> <pathelement location="${DEST_DIR}"/> </path> <target name="build"> <mkdir dir="${DEST_DIR}"/> <javac srcdir="${SRC_DIR}" destdir="${DEST_DIR}"/> <jar destfile="myproject.jar" basedir="${DEST_DIR}"/> </target> <target name="doc"> <mkdir dir="${DOC_DIR}"/> <javadoc sourcepath="${SRC_DIR}" destdir="${DOC_DIR}" Locale="en_US"/> </target> <target name="run" depends="build" > <java classname="ScopeVariable"> <classpath refid="project.class.path"></classpath> <!--classpath> <pathelement location ="${DEST_DIR}"/> </classpath--> </java> </target> </project> 图 1-14 一个 ant 编译文件示例 图 1-14 给出了一个ant编译文件示例,下面结合这个例子来说明编译文件的内部结构。 工程(project):每个编译文件实际上是一个工程,故在 ant 编译文件中,project 元素是
第1章概述 根元素,其他元素都将在project元素内声明。project元素允许带有属性,例如name属性用 来指定该工程的名字,default属性用来指定这个工程缺省执行的任务组,basedir属性用来 指定执行这个ant编译文件时的基路径。 任务组((target):在编译文件中,一个任务组是一个名为argt的元素,它至少有一个属 性name指明自己的名称,外加可选的一个或多个其它属性(包括depends、refid等)。一个任 务组可以包含多个任务(ak,执行一个任务组就是批最地执行任务组内定义的任务。 一个 编译文件中可以定义多个任务组,如图1-l4中包含有名为build、doc和run三个任务组。 任务组的名称是重要的。At的作用是成批地执行某些单一的指令,而任务组就是执行 中与人交互的最小单位.你可以在控制台输入ant build命令行来执行当前目录下的build.xml 中定义的build任务组,或者在任意目录下用ant-buildfile=-XXX build(“-buildfile”可以换 成“le”或者“”)执行指定的编译文件XXX中定义的bud任务组。你也可以同时指 定运行多个任务组,例如,输入ant build doc命令行来依次执行build.xml中定义的build任 务组和doc任务组。 当编译文件包含多个任务组时,在这些任务组之间允许建立依赖关系。假设在某个编译 文件中有两个任务组A和B,其中A有属性depends-”B”,在执行A的时候,ant会先执行A所 依赖的任务组B,然后再执行A本身。B也可以依赖于C、D等其它任务组,这样在执行B之 前,C和D都会首先被执行。在图1-l4中,nun任务组依赖build任务组。 任务(task):At中的任务是指一段能够被执行的代码。任务的通用格式如下所示: <name attributel="value1"attribute2="value2"> At通过准确地执行任务中定义的步骤来完成它的使命。下面介绍几个常用的任务声明: <echo message=-"Message goes here.">在屏幕上输出相应的信息. javac sredir="src\mainhelloant"destdir="buildclasses"javac 目录下的*java文件,生成的代码放在build\classes下。 <mkdir dir="c:workspace"p建立目录c:workspace。. 图1-l4中build任务组包含mkdir、.javac和jar三个任务,分别用来建立目录、编译Java程 序、以及将编译得到的class文件打包成jar文件:doc任务组包含mkdir、.javadoc两个任务,分 别用来建立目录、从指定文件夹中的源程序提取注释生成HTML文档:un任务组包含jav 任务来执行指定的主类ScopeVariable。 属性(property:属性(元素名为property)是任务的一种,它的作用与环境变量和Macro 类似,属性可以作为的子元素,也可以作为target的子元素。通过定义一个属性,我们 可以在编译文件中的其它位置显式或者隐式地引用属性的名称和值。例如,在图1-14中声 明了3个property元素:第I个property元素声明一个名为SRC_DIR的属性,其location属性 指定这个属性所代表的路径,这里用的是相对路径(相对于当前at编译文件所在的路径)。 路径(path):path元素用来定义一组路径,其属性id用来指定该path元素的标识,这样其 他元素(如图-l4中的classpath元素)可以通过属性refd引用这个pah元素。path元素内可 以声明多个pathelement元素,每个pathelement元素指定一个路径, 上面只列出一些常用的元素,关于ant更多的使用特征请查询at使用手册 21
第 1 章 概述 21 根元素,其他元素都将在 project 元素内声明。project 元素允许带有属性,例如 name 属性用 来指定该工程的名字,default 属性用来指定这个工程缺省执行的任务组,basedir 属性用来 指定执行这个 ant 编译文件时的基路径。 任务组(target):在编译文件中,一个任务组是一个名为target的元素,它至少有一个属 性name指明自己的名称,外加可选的一个或多个其它属性(包括depends、refid等)。一个任 务组可以包含多个任务(task),执行一个任务组就是批量地执行任务组内定义的任务。一个 编译文件中可以定义多个任务组,如 图 1-14 中包含有名为build、doc和run三个任务组。 任务组的名称是重要的。Ant 的作用是成批地执行某些单一的指令,而任务组就是执行 中与人交互的最小单位。你可以在控制台输入 ant build 命令行来执行当前目录下的 build.xml 中定义的 build 任务组,或者在任意目录下用 ant –buildfile=XXX build(“-buildfile”可以换 成“-file”或者“-f”)执行指定的编译文件 XXX 中定义的 build 任务组。你也可以同时指 定运行多个任务组,例如,输入 ant build doc 命令行来依次执行 build.xml 中定义的 build 任 务组和 doc 任务组。 当编译文件包含多个任务组时,在这些任务组之间允许建立依赖关系。假设在某个编译 文件中有两个任务组A和B,其中A有属性depends=”B”,在执行A的时候,ant会先执行A所 依赖的任务组B,然后再执行A本身。B也可以依赖于C、D等其它任务组,这样在执行B之 前,C和D都会首先被执行。在 图 1-14 中,run任务组依赖build任务组。 任务(task):Ant 中的任务是指一段能够被执行的代码。任务的通用格式如下所示: <name attribute1="value1" attribute2="value2" ... /> Ant 通过准确地执行任务中定义的步骤来完成它的使命。下面介绍几个常用的任务声明: <echo message="Message goes here." /> 在屏幕上输出相应的信息。 <javac srcdir="src\main\hello\ant" destdir="build\classes"/> 用 javac 编译 src\main\hello\ant 目录下的*.java 文件,生成的代码放在 build\classes 下。 <mkdir dir=”c:\workspace”/>建立目录 c:\workspace。 图 1-14 中build任务组包含mkdir、javac和jar三个任务,分别用来建立目录、编译Java程 序、以及将编译得到的class文件打包成jar文件;doc任务组包含mkdir、javadoc两个任务,分 别用来建立目录、从指定文件夹中的源程序提取注释生成HTML文档;run任务组包含java 任务来执行指定的主类ScopeVariable。 属性(property):属性(元素名为property)是任务的一种,它的作用与环境变量和Macro 类似,属性可以作为project的子元素,也可以作为target的子元素。通过定义一个属性,我们 可以在编译文件中的其它位置显式或者隐式地引用属性的名称和值。例如,在 图 1-14 中声 明了 3 个property元素:第 1 个property元素声明一个名为SRC_DIR的属性,其location属性 指定这个属性所代表的路径,这里用的是相对路径(相对于当前ant编译文件所在的路径)。 路径(path):path元素用来定义一组路径,其属性id用来指定该path元素的标识,这样其 他元素(如 图 1-14 中的classpath元素)可以通过属性refid引用这个path元素。path元素内可 以声明多个pathelement元素,每个pathelement元素指定一个路径。 上面只列出一些常用的元素,关于 ant 更多的使用特征请查询 ant 使用手册
第1章概述 (http://ant apache org/manual/index html)
第 1 章 概述 22 (http://ant.apache.org/manual/index.html)
第2章MiniJOOL语言 第2章MiniJOOL语言 MiniJOOL(A Mini Java-like Object Oriented Language)语言是贯穿本书的一个用于实验 的程序设计语言。它的大部分语言特性来自于Java语言,但是比Java语言要小很多:同时 MiniJOOL语言在个别地方又与Java语言略有不同,例如,它仅支持一维数组,且数组的长 度必须静态指定,即形如“imt2a,”的形式。引入MiniJOOL语言的主要目的是:帮助和 指导你理解编译原理和技术,开展相关的编译器实现的课程实验,强化你的软件工程能力: 由于实验的课时和机时有限,我们并不需要你实现一种强大的语言。 要想为MiniJOOL语言实现一个正确的编译器,就必须先了解这个语言的各种特征。本 章将对MiniJOOL语言的词法、语法及语义进行详细阐述:并结合程序例子帮助你了解 MiniJOOL语言的特征以及需要注意的地方。在详细阐述MiniJOOL语言之后,本章进一步 介绍实验中使用的MiniJOOL语言的两个子集:SkipOOMiniJOOL语言和SimpleMiniJOOL 语言。前者是去掉MOOL语言中的面向对象特征后所形成的语言:后者则是一个程序中 仅含一个函数的简单语言。为统一起见,我们把用MiniJOOL语言或其子集编写的源程序文 件的扩展名均定义为mj。 除了非形式地阐述三种语言的特征外,本章还形式地描述SkipOOMiniJOOL语言的静 态语义,这个静态语义是以SkipOOMiniJOOL的抽象文法以及类型系统为基础的。通过静 态语义的描述,一方面能严格地定义对语言的约束规则,另一方面也初步让你了解如何形式 地定义一个语言。 2.1 MiniJOOL语言简介 本节先简要介绍MiniJOOL语言的特点,然后通过一个MiniJOOL程序示例,让你初步 认识MiniJOOL语言. 2.1.1 MiniJ00L语言的特点 MiniJOOL语言是一个小型的面向对象语言。为简单起见,这里仅列出它与Java2的 主要区别。 ●一个MiniJOOL程序的所有类都在同一个文件中,不支持Java语言中的package 包管理以及import导入指令: ·MiniJOOL语言不支持接口(interface)、抽象类(abstract class)和抽象方法(abstract method),支持类的单一继承以及方法的重载(overload)和重写(override): ·MiniJOOL语言不支持public、protected、private访问控制修饰符,类中所有的成 员都是全局可见的: ·MiniJOOL语言不支持异常(Exception),即不提供ty和catch子句: 。MiniJOOL语言的数据类型可以是类,可以是void、32位整型int、布尔型boolean 字符串类型String,还可以是以int、boolean和String为基本元素类型的一维数组 23
第 2 章 MiniJOOL 语言 23 第2章 MiniJOOL 语言 MiniJOOL(A Mini Java-like Object Oriented Language)语言是贯穿本书的一个用于实验 的程序设计语言。它的大部分语言特性来自于 Java 语言,但是比 Java 语言要小很多;同时 MiniJOOL 语言在个别地方又与 Java 语言略有不同,例如,它仅支持一维数组,且数组的长 度必须静态指定,即形如“int [2] a;”的形式。引入 MiniJOOL 语言的主要目的是:帮助和 指导你理解编译原理和技术,开展相关的编译器实现的课程实验,强化你的软件工程能力; 由于实验的课时和机时有限,我们并不需要你实现一种强大的语言。 要想为 MiniJOOL 语言实现一个正确的编译器,就必须先了解这个语言的各种特征。本 章将对 MiniJOOL 语言的词法、语法及语义进行详细阐述;并结合程序例子帮助你了解 MiniJOOL 语言的特征以及需要注意的地方。在详细阐述 MiniJOOL 语言之后,本章进一步 介绍实验中使用的 MiniJOOL 语言的两个子集:SkipOOMiniJOOL 语言和 SimpleMiniJOOL 语言。前者是去掉 MiniJOOL 语言中的面向对象特征后所形成的语言;后者则是一个程序中 仅含一个函数的简单语言。为统一起见,我们把用 MiniJOOL 语言或其子集编写的源程序文 件的扩展名均定义为 mj。 除了非形式地阐述三种语言的特征外,本章还形式地描述 SkipOOMiniJOOL 语言的静 态语义,这个静态语义是以 SkipOOMiniJOOL 的抽象文法以及类型系统为基础的。通过静 态语义的描述,一方面能严格地定义对语言的约束规则,另一方面也初步让你了解如何形式 地定义一个语言。 2.1 MiniJOOL 语言简介 本节先简要介绍 MiniJOOL 语言的特点,然后通过一个 MiniJOOL 程序示例,让你初步 认识 MiniJOOL 语言。 2.1.1 MiniJOOL 语言的特点 MiniJOOL 语言是一个小型的面向对象语言。为简单起见,这里仅列出它与 Java 2[1]的 主要区别。 z 一个 MiniJOOL 程序的所有类都在同一个文件中,不支持 Java 语言中的 package 包管理以及 import 导入指令; z MiniJOOL 语言不支持接口(interface)、抽象类(abstract class)和抽象方法(abstract method),支持类的单一继承以及方法的重载(overload)和重写(override); z MiniJOOL 语言不支持 public、protected、private 访问控制修饰符,类中所有的成 员都是全局可见的; z MiniJOOL 语言不支持异常(Exception),即不提供 try 和 catch 子句; z MiniJOOL 语言的数据类型可以是类,可以是 void、32 位整型 int、布尔型 boolean、 字符串类型 String,还可以是以 int、boolean 和 String 为基本元素类型的一维数组
第2章MiniJOOL语言 类型,数组的长度必须是常量表达式: ●MiniJOOL语言支持在类中通过final修饰符来声明一个常量,如“static final int ERROR=-1,” 。MiniJOOL语言不支持switch/for/do..…while语句,但是支持if队while/break/continue 语句: ·MiniJOOL语言不支持自增和自减运算(即“+”、“一”)、位运算以及条件运算 ●MiniJOOL语言提供“print(<表达式>),”语句用来支持输出,提供“read(<具有左 值的整型表达式>”语句用来支持输入。 2.1.2一个Mini.J600L程序示例 图2-l是一个完整的MiniJOOL程序,其中包含Program、QuickSort和Sort三个类,Program 是主类,QuickSort/从Sort派生。Sot类提供对内置数组的目泡排序,而QuickSort提供对内置 数组的快速排序。这个程序展示了MiniJOOLi语言的大部分特征。一个MiniJOOL程序可以包 含多个类,类之间可以存在继承关系(类QuickSort继承自类Sot):第一个类(主类)必须 有一个static void类型的主方法main:程序中可以使用包括整型int、字符串类型String、类类 型、一维数组类型在内的多种数据类型等。你可以通过这个程序对MiniJOOL语言有一个感 性认识。 2.2 MiniJ00L语言的词法 MiniJOOL语言的词法由两部分规则组成,一部分规定了单词的构成规则,词法分析将 根据这些规则从输入的字符流中识别出单词供语法分析使用:另一部分规定了被词法分析过 滤掉的符号串,包括注释和空白符号。单词可进一步分为标识符、关键字、分隔符、运算符 和常量值。词法分析在识别出单词后,会把该单词对应的词法记号(tokn)传给语法分析 器,这些记号将作为MiniJOOL语言语法的终结符。在附录1中,给出了MiniJOOL语言中 各种单词对应的词法记号D的约定。 下面简要说明注释、空白以及各种单词的构成特征。 1、注释 MiniJOOL语言支持单行注释和多行注释,这些和Java语言的单行、多行注释一样。单 行注释以“∥”开始并延伸到行末,可以包含任何可打印的字符(ASCI码为32-126)。多 行注释由“体”开始并以第一次遇到的“◆(”为结尾,内含任何可打印的字符。 注意:多行注释不支持嵌套!你需要特别处理“件*.序*”这样的情况(省略 号中不包含“体”和“*/”子串),在这个示例中,“*产”是多行注释,但是“” 不屈于注释中的内容。 2、空白符号 空格、制表符和换行符一般都视为空白符号,除非这些符号出现在字符串中
第 2 章 MiniJOOL 语言 24 类型,数组的长度必须是常量表达式; z MiniJOOL 语言支持在类中通过 final 修饰符来声明一个常量,如“static final int ERROR=-1;”; z MiniJOOL 语言不支持 switch/for/do…while 语句,但是支持 if/while/break/continue 语句; z MiniJOOL 语言不支持自增和自减运算(即“++”、“--”)、位运算以及条件运算; z MiniJOOL 语言提供“print(<表达式>);”语句用来支持输出,提供“read(<具有左 值的整型表达式>);”语句用来支持输入。 2.1.2 一个 MiniJOOL 程序示例 图 2-1 是一个完整的MiniJOOL程序,其中包含Program、QuickSort和Sort三个类,Program 是主类,QuickSort从Sort派生。Sort类提供对内置数组的冒泡排序,而QuickSort提供对内置 数组的快速排序。这个程序展示了MiniJOOL语言的大部分特征。一个MiniJOOL程序可以包 含多个类,类之间可以存在继承关系(类QuickSort继承自类Sort);第一个类(主类)必须 有一个static void类型的主方法main;程序中可以使用包括整型int、字符串类型String、类类 型、一维数组类型在内的多种数据类型等。你可以通过这个程序对MiniJOOL语言有一个感 性认识。 2.2 MiniJOOL 语言的词法 MiniJOOL 语言的词法由两部分规则组成,一部分规定了单词的构成规则,词法分析将 根据这些规则从输入的字符流中识别出单词供语法分析使用;另一部分规定了被词法分析过 滤掉的符号串,包括注释和空白符号。单词可进一步分为标识符、关键字、分隔符、运算符 和常量值。词法分析在识别出单词后,会把该单词对应的词法记号(token)传给语法分析 器,这些记号将作为 MiniJOOL 语言语法的终结符。在附录 1 中,给出了 MiniJOOL 语言中 各种单词对应的词法记号 ID 的约定。 下面简要说明注释、空白以及各种单词的构成特征。 1、注释 MiniJOOL 语言支持单行注释和多行注释,这些和 Java 语言的单行、多行注释一样。单 行注释以“//”开始并延伸到行末,可以包含任何可打印的字符(ASCII 码为 32~126)。多 行注释由“/*”开始并以第一次遇到的“*/”为结尾,内含任何可打印的字符。 注意:多行注释不支持嵌套!你需要特别处理“/**…/*…***/…*/”这样的情况(省略 号中不包含“/*”和“*/”子串),在这个示例中,“/**…/*…***/”是多行注释,但是“…*/” 不属于注释中的内容。 2、空白符号 空格、制表符和换行符一般都视为空白符号,除非这些符号出现在字符串中