compiler-construction - 在 Antlr4 中使用监听器:编译器如何知道如何处理变量左值而不是右值?
问题描述
在我的语法中,变量以 $ 开头,所以
$a = 10
已验证。当然,下面的语句也是如此:
$c = $a + $b
我的语法用这个(部分)定义来处理变量;
start: (expr | stmt)* EOF ;
stmt
: lvalue=id EQUAL assignexpr=expr # AssignId
| declare EQUAL assignexpr=expr #DeclareAndAssign
| declare # DeclareVar
;
expr
: sign=(PLUS|MINUS) expr # signed_expr
| LPAREN expr RPAREN # paren_exp
| id # idval
| value #constval
| lvalue=expr op=(PLUS | MINUS | MULT |DIV) rvalue=expr # arith
;
到目前为止,当我在侦听器中遇到一个常量值时,我只需发出一个 ICONST(假设它是一个整数),它将值推送到堆栈中。当我得到一个变量时,我发出一个 ILOAD 来获取变量值并将其推送到堆栈 - 只要它位于语句的右侧就可以了。
我遇到的问题是:当变量在左侧时..我不需要发出 ILOAD 因为该值将被覆盖并且不会在任何时候从堆栈中弹出。因此,在代码中达到这个变量时,我需要一种知道如何使用它的方法。
我怎么知道如何处理这个变量 $c?我是否需要更改语法以更具体地处理这种情况?我需要走两次树吗?人们通常如何对待必须是微不足道的常见情况?
解决方案
正如您在评论中澄清的那样,您正在监听id
s,它被赋值和变量表达式使用。如果您idval
改为侦听 s,则只会获得用作表达式/右值的变量。
您可以直接在监听器中将变量作为左值处理AssignId
。
推荐阅读
- javascript - 如何打印包含页面css的div?
- cluster-analysis - 基于质心的均值偏移算法用于聚类的距离度量是什么?
- node.js - Mongoose model.find() 返回一个空集合
- python - 使用 OpenCV 将 numpy 数组显示为灰度图像
- javascript - 通过初始化属性,确保此属性在数据选项或基于类的组件中是反应性的
- ipmi - ipmiutil 如何检查电源状态?
- android - 在 Android 上实现可恢复调度程序的正确方法是什么?
- c++ - 如何检查n个给定图块中的任何一个是否重叠
- code-documentation - YARD doc - how to document a class type focusing on its parent class
- ruby - 代码没有检查 ruby 中的第二个 elsif 条件