我正在尝试使用ANTLR编译程序,我使用Java编程语言作为目标,问题的核心是开发Intent Regornizer来纠正错误并改进源代码,如果源代码不是按照语法。 关于ANTLR的教程和书籍我看到如何编译一个简单的代码,假设我做了词法分析器和解析器,源代码如下:
int main(){
int a,b;
c=20;
}
程序如何检测变量'C'之前未声明的错误?
我尝试按照如何使用ANTLR进行编译的说明来应用它,但是ANTLR生成器的代码被认为是有效的,因为它是根据表达式的语法规则。但实际上变量c是未知的。
或如何制作一个可以在其中实现面向对象概念的语法?我尝试过使用ANTLR语法,但结果仍然无法解释OOP的概念。
public class Hello {
}
public class HelloTwo {
Hello hl = new HelloWrong();
}
如果我编译代码,结果是有效的,因为符合Grammar.but看起来HelloWrong类真的没有。它也与我在第一个问题上写上一个变量有关。
对不起我的英文。 我希望你能解决我的问题。 谢谢你
答案 0 :(得分:4)
是否已声明'c'不是语法的一部分 解析器输出Abstract Syntax Tree,编译器获取该AST并对其执行semantic analysis。正是在那个阶段生成了编译器错误,例如“变量c在该范围内不存在”。
ANTLR为您生成AST,然后就完成了。下一阶段(语义分析和编译以及生成可执行文件)由编译器的另一部分完成。
我用来产生你正在寻找的行为的方法是遍历AST,在每个节点上进行“语义分析”。 AST的外观将完全取决于用于生成它的语法,但您的第一个程序可能如下所示:
PROGRAM
|- FUNCTION_DEC "main"
|- ARGS <none>
|- SCOPE 1
|- LOCAL_DEC "a", "b"
|- EXPRESSION_STMT
|- ASSIGNMENT
|- VARIABLE "c"
|- LITERAL 20
语义分析可以做这样的事情:
1)将“main”添加到符号表中作为全局可访问的函数
2)将主函数范围内的范围1添加到符号表
3)在符号表中添加“a”和“b”作为范围1中的局部变量
4)在符号表中查找范围1内的变量“c”,失败,查看“main”的父范围,失败,查看全局范围,失败,产生错误消息:找不到变量“c”。
据我所知,这是一个相当典型的过程。