2. 例程2
(1) 测试用例分析
在这个例子中,我们着重检验我们的语法树是否正确。 (2) 测试结果
在test2.txt中内容如下: --here are notes.
for T from 0 to 120 step 1 draw (t, -t); 测试结果如下:
3. 例程3
(1) 测试用例分析
这第三个用例我们用来对词法分析器中的反射机制进行测试。而在这里,我们需要在类parser中添加下面的两个函数:
}
for (double x = from; x <= to; x += dx) { }
try { }
double y = (Double) f.invoke(null, x); System.out.printf(\e.printStackTrace();
public static void printTable(double from, double to, int n, Method f) {
System.out.println(f);
double dx = (to - from) / (n - 1); public static void myPrint(String n) { }
System.out.println(n);
} catch (Exception e) {
接着,我们需要在函数public void PrintSyntaxTree(ExprNode root,int indent)中switch
语句 else if (root.OpCode == Token_Type.FUNC)中增加如下测试代码:
try {
{ }
System.out.println(e.toString());
System.out.println(\System.out.println(\System.out.println(\Method sp = parser.class.getMethod(\sp.invoke(null, \
printTable(1, 10, 10, root.content.CaseFunc.MathFunPtr);
} catch (Exception e)
上面的代码可以动态地调用传进去的函数,也就是说,我们完全可以在语义分析中使用这种方法来进行表达式的求值。我们求的是从1到10等间隔的10个数,并将结果进行打印。
(2) 测试结果 在test3.txt中内容如下: origin is (100, 300); rot is sqrt(45); 测试结果如下:
四、总结、体会及其他
由于有了词法分析器的基础,再次编写语法分析器的时候难度已经大大减少了。在编写过程中主要有以下的体会:
1. 编写语法分析器时首先遇到的问题就是Java中的package问题。
2. 而且涉及到要调用其他文件中的类或者函数,所以在编写时可能需要将一些函
数和变量改成public。
3. 另一个给我深刻印象的就是Java将诸如int、double、float、char之类的基本类
型在java.lang中进行了包装,将它们包装成了一个一个的类,使得我们完全可以用调用类的方法来调用它们。
4. 至于指向全局变量T的指针CaseParmPtr,笔者则将其使用了Double进行定义。
另一个原因是基本类型double和类Double在java1.5以后可以直接进行转化。
附录:源代码
一、 analyser中的代码
1. Token_Type中的代码
package analyser;
public enum Token_Type {// 记号的类别
ORIGIN, SCALE, ROT, IS, // 保留字 TO, STEP, DRAW, FOR, FROM, // 保留字 T, // 参数
SEMICO, L_BRACKET, R_BRACKET, COMMA, // 分隔符 PLUS, MINUS, MUL, DIV, POWER, // 运算符 FUNC, // 函数 CONST_ID, // 常数 NONTOKEN, // 空记号 ERRTOKEN // 出错记号 }
2. Token中的代码
package analyser;
import java.lang.reflect.Method; public class Token {
public Token_Type type; public StringBuffer lexeme; public double value; // double (*FuncPtr)(double); // 在此暂不进行函数映射 public Method FunPtr; // double (*FuncPtr)(double); // 在此暂不进行函数映射 public Token() throws Exception // we change it to be visible!! // 在这我们加了一行这个…… {
type = Token_Type.ERRTOKEN; // type = Token_Type.SEMICO ; // 在这里,我们初始化type为SEMICO // 如此初始化?
lexeme = new StringBuffer(\