将 Listener 与 Antlr4 结合使用:编译器如何知道如何处理变量左值而不是右值?
Using Listener with Antlr4: How does the compiler know how to treat a variable lvalue as opposed to a rvalue?
在我的语法中,变量以 $ 开头,所以
$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
的侦听器中将变量作为左值处理。
在我的语法中,变量以 $ 开头,所以
$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
的侦听器中将变量作为左值处理。