我正在实现一个用于二进制算术的递归下降解析器。在进行回溯时,我通过回退到已保存的指针来实现,但是使用短路 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()
我可以恢复next
按本地 save
当左操作数返回false
时在 &&
的左操作数中。我想做如下的事情。我怎样才能通过短路做到这一点?
提前致谢!!
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);
}
关于java - 如何保存到局部变量并在短路操作数中运行函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57882220/