我最近一直在研究ANTLR和Java,并构建了一个简单的语法来解析此代码并生成AST。我还编写了一个内置的解释器来执行此代码,它似乎运行良好:
关于玩具语言的一些说明:
/* A sample program */
BEGIN
j := 1;
WHILE j <= 5 DO
PRINT "ITERATION NO: "; PRINTLN j;
sumA1 := 0;
WHILE 1 = 1 DO
PRINT "Enter a number, 0 to quit: ";
i := INPUT;
IF i = 0 THEN
BREAK;
ENDIF
sumA1 := ADD sumA1, i;
ENDWHILE
j := ADD j, 1;
PRINT "The sum is: "; PRINTLN sumA1;
ENDWHILE
j := MINUS j;
PRINTLN j;
END
然后我将代码生成函数写入AST,以将其从我的AST类输出到C,并得到此结果(美化):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char * argv[]) {
double j;
j = 1.00000;
while (j <= 5.0) {
printf("ITERATION NO: ");
printf("%g\n", j);
double sumA1;
sumA1 = 0.00000;
while (1.0 == 1.0) {
printf("Enter a number, 0 to quit: ");
double i;
scanf("%lf", & i);
if (i == 0.0) {
break;
}
sumA1 = sumA1 + i;
}
j = j + 1.00000;
printf("The sum is: ");
printf("%g\n", sumA1);
}
j = -j;
printf("%g\n", j);
}
在代码生成期间,我首先检查变量名在HashMap中是否可用。如您所见,对于赋值语句/输入语句,我在赋值之前添加了变量声明。对于除赋值以外的变量使用,我在使用前抛出了一个用于未初始化变量的异常。
都很好。上面的代码适用于此示例,因为在我的源程序中,我没有在声明它的范围之外使用任何变量。
但是有一个问题。由于我正在块内初始化某些变量(例如while
,因此它们不能在范围外使用),因此我需要一种方法来收集在源程序中使用的所有变量,这些变量在C中是全局变量(或至少在主变量之上)。 ()函数)。如果在块外我的程序中使用了变量,则在用C之前声明变量将导致源语言中的有效程序无法在C中编译。
我以为我可以通过以下方法解决它:首先解析所有变量,然后在C程序的开头声明它们,然后生成代码。
但是如果在生成代码之前更新符号表(HashMap),我将无法知道在使用之前是否确实分配了该变量。
重新设计此方法以确保确保质量的最佳方法是什么?
这是我第一次尝试这样的事情。请为我提供任何可能解决方案的指示。
我最近一直在研究ANTLR和Java,并构建了一个简单的语法来解析此代码并生成AST。我还写了一个内置的解释器来执行此代码,它似乎可以工作...
在一般情况下,不可能在分配前检测使用情况。考虑以下(不是很好)的C代码:
我通过从各个分配节点中删除变量声明,而只是将分配节点中使用的变量添加到全局哈希图中,然后在遍历树后生成声明来解决了这个问题。