如何在短路操作数中保存到局部变量和运行函数?
How to save to a local variable and run a function in short circuit operand?
我正在为二进制算术实现一个递归下降解析器。在进行回溯时,我是通过回退到保存的指针来实现的,但是用短路 AND (&&
) 操作似乎是不可能的。以下是当前使用全局变量 save
和 next
的实现,我意识到这是错误的,因为单个 save
将被后续保存覆盖。
/*
*
* COMPILE : javac .\RecursiveDescentParse.java
* RUN : java RecursiveDescentParse
* compile and run : javac .\RecursiveDescentParse.java -Xlint:deprecation; java RecursiveDescentParse
*
* Unambiguous grammer for Binary Arithmetic
* E -> T | T + E
* T -> int | int * T | ( E )
*
* Example token stream for grammer:
* (int)
* OPEN INT CLOSE
*
* (int + int) * int
* TOKEN.OPEN, TOKEN.INT, TOKEN.PLUS ,TOKEN.INT, TOKEN.CLOSE, TOKEN.TIMES, TOKEN.INT
*
* int * int + int
* TOKEN.INT, TOKEN.TIMES ,TOKEN.INT, TOKEN.PLUS, TOKEN.INT
*/
enum TOKEN{
INT, // int
OPEN, // (
CLOSE, // )
PLUS, // +
TIMES // *
}
public class RecursiveDescentParse{
// pointing to the start token of the token stream
public static int next = 0;
// saving next pointer for backtracking
public static int save;
public static TOKEN[] tokenStream = new TOKEN[]{ TOKEN.INT, TOKEN.TIMES ,TOKEN.INT, TOKEN.PLUS, TOKEN.INT };
static boolean term(TOKEN token){
return tokenStream[next++] == token;
}
// E -> T
static boolean E1(){
return T();
}
// E -> T + E
static boolean E2(){
return T() && term(TOKEN.PLUS) && E();
}
// E -> T | T + E
static boolean E(){
// save pointer before incrementing cause guessing may be incorrect
save = next;
return (backtrack() & E1()) || (backtrack() & E2());
}
// T -> int
static boolean T1(){
return term(TOKEN.INT);
}
// T -> int * T
static boolean T2(){
return term(TOKEN.INT) && term(TOKEN.TIMES) && T();
}
// T -> ( E )
static boolean T3(){
return term(TOKEN.OPEN) && E() && term(TOKEN.CLOSE);
}
// T -> int | int * T | ( E )
static boolean T(){
save = next;
return (backtrack() & T1()) || (backtrack() & T2()) || (backtrack() & T3());
}
static boolean backtrack(){
next = save;
return true;
}
public static void main(String[] args){
// start parsing the token stream
System.out.println("Parsing status : " + E());
}
}
我需要在 E()
和 T()
中定义局部变量,因为我可以在左操作数 returns [=21 时通过局部 save
恢复 next
=] 在 &&
的左操作数中。我想做类似下面的事情。我怎样才能通过短路做到这一点?
提前致谢!!
static boolean T(){
int save = next;
return (next = save, T1()) || (next = save, T2()) || (next = save, T3());
}
如果您使用的是 Java 8(或更高),您可以编写如下包装方法,它将首先恢复 next
变量,然后调用实际方法。
static boolean resetNextAndExecute(int savedNext, Supplier<Boolean> function) {
next = savedNext;
return function.get();
}
那么你的T()
方法可以改成下面这样。
static boolean T(){
int save = next;
return resetNextAndExecute(save, RecursiveDescentParse::T1) || resetNextAndExecute(save, RecursiveDescentParse::T2) || resetNextAndExecute(save, RecursiveDescentParse::T3);
}
我正在为二进制算术实现一个递归下降解析器。在进行回溯时,我是通过回退到保存的指针来实现的,但是用短路 AND (&&
) 操作似乎是不可能的。以下是当前使用全局变量 save
和 next
的实现,我意识到这是错误的,因为单个 save
将被后续保存覆盖。
/*
*
* COMPILE : javac .\RecursiveDescentParse.java
* RUN : java RecursiveDescentParse
* compile and run : javac .\RecursiveDescentParse.java -Xlint:deprecation; java RecursiveDescentParse
*
* Unambiguous grammer for Binary Arithmetic
* E -> T | T + E
* T -> int | int * T | ( E )
*
* Example token stream for grammer:
* (int)
* OPEN INT CLOSE
*
* (int + int) * int
* TOKEN.OPEN, TOKEN.INT, TOKEN.PLUS ,TOKEN.INT, TOKEN.CLOSE, TOKEN.TIMES, TOKEN.INT
*
* int * int + int
* TOKEN.INT, TOKEN.TIMES ,TOKEN.INT, TOKEN.PLUS, TOKEN.INT
*/
enum TOKEN{
INT, // int
OPEN, // (
CLOSE, // )
PLUS, // +
TIMES // *
}
public class RecursiveDescentParse{
// pointing to the start token of the token stream
public static int next = 0;
// saving next pointer for backtracking
public static int save;
public static TOKEN[] tokenStream = new TOKEN[]{ TOKEN.INT, TOKEN.TIMES ,TOKEN.INT, TOKEN.PLUS, TOKEN.INT };
static boolean term(TOKEN token){
return tokenStream[next++] == token;
}
// E -> T
static boolean E1(){
return T();
}
// E -> T + E
static boolean E2(){
return T() && term(TOKEN.PLUS) && E();
}
// E -> T | T + E
static boolean E(){
// save pointer before incrementing cause guessing may be incorrect
save = next;
return (backtrack() & E1()) || (backtrack() & E2());
}
// T -> int
static boolean T1(){
return term(TOKEN.INT);
}
// T -> int * T
static boolean T2(){
return term(TOKEN.INT) && term(TOKEN.TIMES) && T();
}
// T -> ( E )
static boolean T3(){
return term(TOKEN.OPEN) && E() && term(TOKEN.CLOSE);
}
// T -> int | int * T | ( E )
static boolean T(){
save = next;
return (backtrack() & T1()) || (backtrack() & T2()) || (backtrack() & T3());
}
static boolean backtrack(){
next = save;
return true;
}
public static void main(String[] args){
// start parsing the token stream
System.out.println("Parsing status : " + E());
}
}
我需要在 E()
和 T()
中定义局部变量,因为我可以在左操作数 returns [=21 时通过局部 save
恢复 next
=] 在 &&
的左操作数中。我想做类似下面的事情。我怎样才能通过短路做到这一点?
提前致谢!!
static boolean T(){
int save = next;
return (next = save, T1()) || (next = save, T2()) || (next = save, T3());
}
如果您使用的是 Java 8(或更高),您可以编写如下包装方法,它将首先恢复 next
变量,然后调用实际方法。
static boolean resetNextAndExecute(int savedNext, Supplier<Boolean> function) {
next = savedNext;
return function.get();
}
那么你的T()
方法可以改成下面这样。
static boolean T(){
int save = next;
return resetNextAndExecute(save, RecursiveDescentParse::T1) || resetNextAndExecute(save, RecursiveDescentParse::T2) || resetNextAndExecute(save, RecursiveDescentParse::T3);
}