2010/6/12最新修订
教材部分
2010-6-17
1. P289 表8-1上方倒数第4行中,"ud链的映射表"改成"du链的映射表".(注:最初提交给出版社的电子文件中是"du链的映射表".)
2010-6-9
1. P115 倒数第6行中
assignment_expression = lvalue assignment_operator assignment_expression
改成
assignment_expression = lvalue assignment_operator expression
2010-5-25
1. P293 示例代码8-5中,为强调getAIRreg( )需要自行编写而增加注释信息,即
airsrc = getAIRreg(result.getRegID( ));
改成
airsrc = getAIRreg(result.getRegID( )); // getAIRreg( )需要自行编写
2.P294示例代码8-7中存在花括号不匹配,故将
for(Iterator varit = vartype.iterator( ); varit.hasNext( );){
LIRVariableType var = varit.next( );
AIROperand[ ] operands = new AIROperand[3];
operands[0] = factory.newSymbol(var.getVariableName( ));
operands[1] = factory.newImmNumber(size);
operands[2] = factory.newImmNumber(alg);
varstmts.add(factory.newDirective(Director.COMM, operands));
改成
for(Iterator varit = vartype.iterator( ); varit.hasNext( );){
LIRVariableType var = varit.next( );
AIROperand[ ] operands = new AIROperand[3];
operands[0] = factory.newSymbol(var.getVariableName( ));
operands[1] = factory.newImmNumber(size);
operands[2] = factory.newImmNumber(alg);
varstmts.add(factory.newDirective(Director.COMM, operands));
}
2010-5-17
1. P338(附录4) 第1行中
assignment_expression = IDENTIFIER assignment_operator assignment_expression
改成
assignment_expression = IDENTIFIER assignment_operator expression
2. P339(附录5)第18行,P341(附录6)第16行中
assignment_expression = lvalue assignment_operator assignment_expression
改成
assignment_expression = lvalue assignment_operator expression
2009-7-22
P27,第5行,将"实验支持库平台"改成"实验支持库".
P37,倒数第3行,将"对ir进行代码输出"改成"对ir进行代码生成".
P158,示例代码4-20中的第11行
for (int i = 0; i < 6; i++) jj_la1[i] = -1;
改成
for (int i = 0; i < jj_la1.length; i++) jj_la1[i] = -1;
P158,在倒数第3段之后增加如下一段文字:
注意:示例代码4-20中第7~11行的初始化代码适用于block语言,而不是适用于各种要分析的源语言.当利用JavaCC生成SkipOOMiniJOOL语言的分析器时,在生成的分析器类中可能会引入final private JJCalls[] jj_2_rtns成员,这样初始化代码部分就需要增加对jj_2_rtns的初始化,即在第11行后增加
for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
在实际应用JavaCC生成语言的分析器时,保证在分析器类的doParse( )方法中正确加入初始化代码的方法是:查看JavaCC生成的分析器类(假设类名为Parser)中的带参的构造器的体,将其中的代码复制到doParse( )方法中的初始化代码处.若分析器只有一个带参的构造器,如Parser (java.io.InputStream stream),那么就将该构造器体中的代码复制到doParse( )方法中;假如分析器有2个带参的构造器,如Parser (java.io.InputStream stream)和Parser (java.io.InputStream stream, String encoding),那么就将后者的体中的代码复制到doParse( )方法中.
即便doParse( )方法中的初始化代码写得不对,当直接使用分析器类的main( )方法进行运行时,仍然可能得到正确的分析结果,而利用实验运行平台进行运行则会出错.这主要是因为,main( )方法是调用分析器类的带参的构造器来创建分析器实例,而实验运行平台则是调用分析器类的不带参数的构造器来创建分析器实例,因此需要在分析器类的doParse( )方法中正确增加对分析所需的记号管理等变量的初始化操作.
2009-6-5
1.P168,4.6.3节前的最后一段段尾增加如下红色字体的文字:
……可以在执行CUP时带上命令行参数"-expect number"(表示最多允许number个冲突)以允许冲突的存在.以bin/lab3-2-sblock.xml为例,假设期望最多允许4个冲突,则可以在其中名为java-cup的任务组内的java元素中最后一个arg子元素前增加如下的arg子元素:
光盘部分
说明
若在某系统下,光盘所提供的文本文件中的中文字符显示为乱码,那么请转换该文件的编码格式,使得能正常显示中文.
student\lib目录下的compiler.jar中提供的SimpleMiniJOOL,SkipOOMiniJOOL和MiniJOOL分析器,不支持警告和错误的检查,只针对正确的源程序才有效.
student\lib目录下的compiler.jar中提供的AST2LIR转换器只是一个可用的转换器,而不是一个标准甚至是好的转换器.
student\lib目录下的X86Generator.jar和MIPSGenerator.jar只是一个可用的代码生成器,而不是一个标准甚至是好的代码生成器.
X86Generator.jar和MIPSGenerator.jar生成的汇编码将boolean型数输出为0或1,而不是实验教程中规定的false或true.本书作者不打算修正这个bug.
X86Generator.jar生成的汇编码需要在Linux环境下使用.
2010-6-17
student\lab\lab4目录
修正bin\build.xml,将第9~11行的
改为
修正一些文件中的大小写错误,即将
private ASTSymTable symTable = new BLockSymTable();
改成
private ASTSymTable symTable = new BlockSymTable();
涉及到的文件包括:config\CUP子目录下的block.cup和block_c.cup,config\JJ子目录下的block.jj和block_c.jj,src\edu\ustc\cs\compile\parser\block\jj子目录下的SParser.java和SCParser.java,src\edu\ustc\cs\compile\parser\block\cp子目录下的SParser.java和SCParser.java.
2010-6-12
student\lib目录
更新compiler.jar,主要做如下修改:
修正原SimpleMiniJOOL,SkipOOMiniJOOL和MiniJOOL分析器不支持带下划线的标识符的bug;
test\common目录
array\InvalidOperation.mj
修改main()函数体,将
int[] a1 = {1,2,3}; // ERROR: miss the length of an array
int[3] a2 = {1,2,3};
int[3] a3 = a2; // ERROR: invalid assignment
改为
int[2] a1 = {1,2,3}; // ERROR: invalid array length
int[3] a2 = {1,2,a2[0]}; // ERROR: invalid array member refering
int[3] a3 = a2; // ERROR: invalid assignment
int[3] a4 = {1,a5[0],a5[1]}; // ERROR: invalid array member refering
int[2] a5 = {1,2};
array\OutOfBound.mj
修改main()函数体,将循环
while (i<=10) {
array[i] = i;
}
改为
while (i<=10) {
array[i] = i;
i += 1;
}
string\Invalid.mj
修改main()函数体,将invalud = "\123" 改为invalid = "\123"
string\String.mj
修改main()函数体,将escape = "\"\\\n\r\t\ "改为escape = "\"\\\n\r\t",即去掉赋给escape的字符串中结尾的"\ ".
test\SkipOOMiniJOOL\correct目录
allaspect.mj
修改类名,将SynthesisTest 改为 Allaspect
删除test0()中对boolean和String型变量的输入测试,即删除如下代码:
print("input four boolean :\t");
boolean b;
boolean[2] bArr;
read(b);
read(bArr[0]);
read(sb);
read(sbArr[0]);
print("\n\tyour input is :\t");
print(b); print("\t");
print(bArr[0]); print("\t");
print(sb); print("\t");
print(sbArr[0]);print("\n");
/* 工程LIR2MIPS还未实现读入字符串的功能
print("input four String :\t");
String s;
String[2] sArr;
read(s);
read(sArr[0]);
read(ss);
read(ssArr[0]);
print("\n\tyour input is :\t");
print(s); print("\t");
print(sArr[0]); print("\t");
print(ss); print("\t");
print(ssArr[0]);print("\n");
*/
将函数f44()的定义注释起来,因为这个函数是一个错误的函数,其错误之处在于函数的返回类型为int[].
针对测试作用域的test6(),原先的函数体中出现了违背"不允许声明作用域相嵌套的同名局部变量"同名处理规则的测试代码,现将该函数体内的主体测试代码改成:
print("global si : "); print(si); print("\n");
{
int v1 = 0;
boolean v2 = false;
print("first v1 : "); print(v1); print("\n");
print("first v2 : "); print(v2); print("\n");
int si = 10;
print("local si : "); print(si); print("\n");
}
{
boolean v1 = true;
int v2 = 1;
print("second v1 : "); print(v1); print("\n");
print("second v2 : "); print(v2); print("\n");
}
修改函数test7()的函数体中的部分代码,将
int[32] iArr;
改为
int[32] iArr32;
将
test71(iArr,iArr);
test71(iArr32,iArr32);
改为
test71(iArr32,iArr32);
test71(iArr33,iArr33);
修改函数test71(),将其函数头
static void test71(int[] iArr0, int[32] iArr1)
改为
static void test71(int[] iArr0, int[] iArr1)
因为原先的函数头中形参iArr1声明为int[32],指定了数组长度,这导致编译器产生警告.
修改函数test11()的函数体中的部分代码,将
int[2] iArr = {1,2};
改为
int[2] iArr = {2,1};
从而使得上述局部数组iArr与在test11()上方声明的全局数组iArr在元素取值上有区别.
allocation.mj
将类名Program修改为Allocation.
删去最后的注释
arrayAccess.mj
将类名Program修改为ArrayAccess.
删去最后的注释
ArrayParameter.mj
将类名Program修改为ArrayParameter.
删除最后的注释.
arraySort.mj
将类名Program修改为ArraySort.
将第75行 while(temp =0){
改为 while(j>=0 && temp -1) ;
改为
if ( (fact += 5) > -1) ;
if ( fact += 5 / 2 * 3 + b * -1 ) ;
改为
if ( (fact += 5 / 2 * 3 + b * -1)>0 ) ;
去掉第21行的分号.
Factorial.mj
将类名Program修改为Factorial.
删除最后的注释.
FunctionParam.mj
将类名Program修改为FunctionParam.
删除最后的注释.
FunctionReturn.mj
将类名Program修改为FunctionReturn.
修改最后的注释中的部分内容,即:.
10
0
改为
10
false
Gcd.mj
将类名Program修改为Gcd.
删除最后的注释.
HeapSort.mj
将类名Program修改为HeapSort.
删除最后的注释以及原第9行.
IfStat.mj
将类名Program修改为IfStat.
将 print("输入学生分数:");
改为 print("Please input a score (integer):");
删除最后的注释.
Init.mj
将类名Program修改为Init.
修改函数main()的函数体,即
if (i!=0) print("error");
if (b!=false) print("error");
if (str!=NULL) print("error");
if (ii[0]!=0) print("error");
if (bb[0]!=false) print("error");
if (sstr[0]!=NULL) print("error");
改为
if (i!=0) print("error_1");
if (b!=false) print("error_2");
//if (str!= null) print("error_3"); //error
if (ii[0]!=0) print("error_4");
if (bb[0]!=false) print("error_5");
//if (sstr[0]!=null) print("error_6");//error
删除最后的注释.
Lval_ExpWithParen.mj
将类名Program修改为Lval_ExpWithParen.
删除最后的注释.
Multiplication.mj
将类名Program修改为Multiplication.
删除函数main( )的参数,即
static void main(String[] args) {
改为
static void main() {
删除最后的注释.
Multiplication2.mj
将类名Program修改为Multiplication2.
删除函数main( )的参数,即
static void main(String[] args) {
改为
static void main() {
修改函数f(),将
int a = 2;
改为
int c = 2;
删除最后的注释.
Prime.mj
将类名Program修改为Prime.
删除函数generatePrime()的参数,并修改其函数体,即:
data[0] = true;
data[1]=true;// 1 不是素数
int i=1;
改为
data[0] = true; // 0 is not prime.
data[1] = true; // 1 is not prime.
data[2] = false; // 2 is prime.
int i=3;
修改main()函数体中的部分内容,即:
generatePrime(50);
改为
generatePrime();
修改注释.
删除最后的注释.
PrimitiveType.mj
将类名Program修改为PrimitiveType.
删除函数main( )的参数,即
static void main(String[] args) {
改为
static void main() {
删除以下除了省略号以外的各行
int b;
print("Input Integer b: ");read(b);
……
boolean d;
print("Input boolean d: ");read(d);
……
print(b);print("\n");
……
print(d);print("\n");
删除最后的注释.
PrintFunCall.mj
将类名Program修改为PrintFunCall.
删除最后的注释.
QuickSort.mj
将类名Program修改为QuickSort.
删除最后的注释.
Read.mj
将类名Program修改为Read.
修改main()函数体中的部分内容,即:
print("请输入整数a1:");
改为
print("Please input an integer a1: \n");
print("输入10个整数1:");
改为
print("Please input 10 integers: \n");
删除main()函数体中的以下内容,因为语言不允许通过read读入boolean型值,即:
//b1
print("输入bool值");
read(b1);
print(b1);
print("\n");
//b2
print("请输入5个bool型:");
print("\n");
i = 0;
while(i<5)
{read(b2[i]);i=i+1;}
i=0;
while(i<5)
{print(b2[i]);print("\n");i=i+1;}
删除最后的注释.
Scope.mj
将类名Program修改为Scope.
修改main()函数体中的部分内容,即:
int a = 4;
int b = 8;
if (a!=4) print("error"); // refer to the local variable i1
if (b!=8) print("error"); // refer to the local variable i2
{
int a = 8;
if (a!=8) print("error"); // refer to the local variable
// a in this block
}
改为
{
int a = 4;
int b = 8;
if (a!=4) print("error"); // refer to the local variable i1
if (b!=8) print("error"); // refer to the local variable i2
}
{
int a = 8;
if (a!=8) print("error"); // refer to the local variable
// a in this block
}
int a = 4;
int b = 8;
因为原先的函数体中出现了违背"不允许声明作用域相嵌套的同名局部变量"同名处理规则的测试代码.
ShellInsertSort1.mj改名为ShellInsertSort.mj
将类名Program修改为ShellInsertSort.
删除最后的注释.
ShellSort.mj
将类名Program修改为ShellSort.
删除最后的注释.
ShortCut.mj
将类名Program修改为ShortCut.
修改最后的注释,去掉其中出现的"[java]".
While.mj
将类名Program修改为While.
删除最后的注释.
test\SkipOOMiniJOOL\java目录
基于test\SkipOOMiniJOOL\correct目录所做的修改,与原光盘内容相比,增加以下文件:
Allaspect.java,ArrayAccess.java,ArrayParameter.java,ArraySort.java,Bubble.java,Calculations.java
EvenOrOdd.java,FunctionParam.java,FunctionReturn.java,HeapSort.java,IfStat.java,Init.java
Lval_ExpWithParen.java,Multiplication2.java,Multiplication.java,Prime.java,PrimitiveType.java
Read.java,Scope.java,ShellInsertSort.java,ShellSort.java,While.java
并修改以下文件:
Allocation.java,DoubleQuote.java,EmptyStatement.java,Exp.java,Factorial.java,Gcd.java
PrintFunCall.java,QuickSort.java,ShortCut.java
test\SkipOOMiniJOOL\lir目录
利用实验支持库中提供的SkipOOMiniJOOL分析器和AST2LIR转换器,编译test\SkipOOMiniJOOL\correct目录中的各个mj文件所得到的lir文件
注意:这些文件仅作为参考,并不是代表mj文件对应的标准的或最好的lir文件.
test\SkipOOMiniJOOL\x86目录
利用实验支持库中提供的SkipOOMiniJOOL分析器,AST2LIR转换器和X86汇编代码生成器,针对test\SkipOOMiniJOOL\correct目录中的各个mj文件所得到的x86汇编文件
注意:这些文件仅作为参考,并不是代表mj文件对应的标准的或最好的汇编文件.
test\SkipOOMiniJOOL\mips目录
利用实验支持库中提供的SkipOOMiniJOOL分析器,AST2LIR转换器和MIPS汇编代码生成器,针对test\SkipOOMiniJOOL\correct目录中的各个mj文件所得到的MIPS汇编文件
注意:这些文件仅作为参考,并不是代表mj文件对应的标准的或最好的汇编文件.
2010-5-30
student\lab\lab5\bin\目录
修改build.xml第18行,即
改成
2010-5-25
student\lab\lab6\config\目录
修改lab6-1.xml,lab6-2.xml和lab6-3.xml,将第7行
改成
student\lib目录
更新platform.jar,修改实验平台处理gcc调用阶段的出错提示信息 ,使得输出信息更为准确.
2009-7-22
test\SkipOOMiniJOOL\correct目录
修改test\SkipOOMiniJOOL\correct\Prime.mj
第14行 while (k<=data.length) 改为while (k
分别将block.jj文件和sblock.jj文件中的第56行以及sblock_err.jj文件中的第78行的
for (int i = 0; i < 6; i++) jj_la1[i] = -1;
改成
for (int i = 0; i < jj_la1.length; i++) jj_la1[i] = -1;
student\lab\lab3\src\edu\ustc\cs\compile\parser\目录
分别将block\jj\Parser.java文件和simpleblock\jj\Parser.java文件中的第47行,以及simpleblock\jj\EParser.java文件中的第65行的
for (int i = 0; i < 6; i++) jj_la1[i] = -1;
改成
for (int i = 0; i < jj_la1.length; i++) jj_la1[i] = -1;
student\lab\lab4\config\JJ目录
分别将block.jj文件中的第80行以及block_c.jj文件中的第120行的
for (int i = 0; i < 6; i++) jj_la1[i] = -1;
改成
for (int i = 0; i < jj_la1.length; i++) jj_la1[i] = -1;
student\lab\lab4\src\edu\ustc\cs\compile\parser\block\jj\目录
分别将SParser.java文件中的第71行以及SCParser.java文件中的第111行的
for (int i = 0; i < 6; i++) jj_la1[i] = -1;
改成
for (int i = 0; i < jj_la1.length; i++) jj_la1[i] = -1;
2009-6-12
test\SkipOOMiniJOOL\error目录
删除Program.mj,因为这是正确的程序.早期的SkipOOMiniJOOL语言对类名有限制,即限制类名为Program,现在的SkipOOMiniJOOL语言已允许取任何合法的标识符为类名.
student\lab\lab1\bin目录
对run.sh做如下修改:
删除第6,7行的前导空白符
student\lab\lab3\bin目录
对run.sh做如下修改:
将
PLATFORM_DIR=${ROOT_DIR}/platform
PLATFORM_LIB_DIR=${PLATFORM_DIR}/lib
PLATFORM_LIB=${PLATFORM_LIB_DIR}/edu.ustc.cs.compile.platform.core.jar:\
${PLATFORM_LIB_DIR}/edu.ustc.cs.compile.platform.handler.jar:\
${PLATFORM_LIB_DIR}/edu.ustc.cs.compile.platform.util.jar
改为
LIB_DIR=${ROOT_DIR}/lib
COMP_LIB=${LIB_DIR}/platform.jar:${LIB_DIR}/util.jar
删除对LIB_DIR的重复定义,即
LIB_DIR=${ROOT_DIR}/lib
修改对CLASSPATH的定义,即将${PLATFORM_LIB}改为${COMP_LIB}
student\lab\lab6\bin目录
对run.bat做如下修改:
第20行, %AIR_LI% 改为%AIR_LIB%
第27行,lab6.xml 改为lab6-1.xml
对run.sh做如下修改:
第29行,lab6.xml 改为lab6-1.xml
环境变量定义中的反斜杠需要改为斜杠,即将
PLATFORM_LIB=${LIB_DIR}\platform.jar
COMPILER_LIB=${LIB_DIR}\compiler.jar
UTIL_LIB=${LIB_DIR}\util.jar
LIR_LIB=${LIB_DIR}\lir.jar
AIR_LIB=${LIB_DIR}\air.jar
REGALLOC_LIB=${LIB_DIR}\regalloc.jar
改为
PLATFORM_LIB=${LIB_DIR}/platform.jar
COMPILER_LIB=${LIB_DIR}/compiler.jar
UTIL_LIB=${LIB_DIR}/util.jar
LIR_LIB=${LIB_DIR}/lir.jar
AIR_LIB=${LIB_DIR}/air.jar
REGALLOC_LIB=${LIB_DIR}/regalloc.jar
student\lab\lab7\bin目录
对run.sh做如下修改:
环境变量定义中的反斜杠需要改为斜杠,同student\lab\lab6\bin\run.sh中的修改
student\lib目录
更新platform.jar,主要做如下修改:
修改对执行汇编代码命令的处理,使实验平台可以输出调用gcc和执行生成的程序的结果.
更新air.jar,主要做如下修改:
新增src/edu/ustc/cs/compile/air/statement/AIRMeaninglessLine.java,用于表示AIR中的空行和注释等;
在src/edu/ustc/cs/compile/air/AIRFactory.java中添加如下工厂方法
public AIRMeaninglessLine newMeaninglessLine(String content) {
return new AIRMeaninglessLine(content);
}
用于创建一个AIRMeaninglessLine实例,其参数可以是空串或注释.
doc目录
由于platform和air类库做修改,故重新用javadoc生成实验支持库的帮助文档,更新整个doc目录中的内容.
2009-6-5
1.student\lab\lab6\config目录下的lab6*.xml以及student\lab\lab7\config目录下的lab7*.xml中,
edu.ustc.cs.compile.generator
改成
edu.ustc.cs.compile.gen
2.student\lab\lab6\bin目录和student\lab\lab7\bin目录下的build.xml中,
edu/ustc/cs/compile/generator/
改成
edu/ustc/cs/compile/gen/
3.student\lab\lab7\src\edu\ustc\cs\compile目录下的子目录
generator
改成
gen