java - 如何保存到局部变量并在短路操作数中运行函数?

标签 java parsing short-circuiting

我正在实现一个用于二进制算术的递归下降解析器。在进行回溯时,我通过回退到已保存的指针来实现,但是使用短路 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/

相关文章:

json - Haskell、Aeson - 如何调试实例?

PHP 短路评估(好/坏?)

java - 凯撒密码帮助 ASCII 循环

java - 黑莓 - 模拟器上的安全 API 错误

java - 从 JavaFX 2.2 升级到 JavaFX 8 的问题(可能是错误?)

C++,命令行参数没有被正确解析

python - 将变量从命令行解析为 url

perl - 短路并给出不正确的结果?

c++ - 短路和括号

java - 项目关闭后,Intellij IDEA 如何减少内存?