【发布时间】:2020-01-12 21:15:30
【问题描述】:
我正在为二进制算术实现递归下降解析器。在进行回溯时,我通过回退到保存的指针来做到这一点,但是用短路 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() 中定义局部变量,因为当左操作数在&& 的左操作数中返回false 时,我可以通过本地next 恢复next。我想做类似下面的事情。我怎么能用短路来做到这一点?
提前致谢!!
static boolean T(){
int save = next;
return (next = save, T1()) || (next = save, T2()) || (next = save, T3());
}
【问题讨论】:
标签: java parsing short-circuiting