Antlr4 RPN计算;堆栈上的最终结果丢失



免责声明:这是为了课程工作,也是我的第一篇SO帖子,因为通常在之前都会问我问题

在一个关于antlr的简短速成课程之后,我已经尽了最大努力来找出如何最好地解决创建一个支持数字、逻辑和关系运算的RPN计算器的问题。只接受int和boolean。

现在,虽然我的代码可能远未达到标准的antlr质量,但除了我的"开始"规则匹配时,其他代码都正常工作。我希望它打印出堆栈中的结果,但由于某种原因,匹配后堆栈总是空的。

例如2 3+;在我的打印调试语句中,我看到所有内容都被推送、弹出,并且5的结果被按预期推送。但是一旦终止";",堆栈就会为空与"开始"规则匹配。

我确信我错过了一些基本的东西,因为我们只在课堂上和antlr呆了一天,但我想不出来。我没有为antlr4找到任何幸运的调试器,它可以让我在代码运行时逐步完成代码,但我确实打印出了输入,弹出了项目,并在进行时推送了项目,一切似乎都在"启动"之前

下面是我的代码示例,只有加法运算,没有布尔输入:

grammar RPN;    
@header {
    import java.util.Stack;
}
@members {
    Stack<String> s = new Stack<String>();
    int first;
    int second;
    int parseInteger(String value) {
        if(tryParseInt(value)) {
            System.out.println("Integer parsed from stack: " + value + "n");
            return Integer.parseInt(value);
        } else {
            System.out.println("ERROR: Invalid integer value; Unable to parsen");
            return 0;
        }
    }
    boolean tryParseInt(String value) {
        try {
            Integer.parseInt(value);
            return true;
        } catch(NumberFormatException nfe) {
            return false;
        }
}
    boolean stackCheck(Stack st, int size) {
        if(st.size() >= size) {
            return true;
        }
        else {
            System.out.println("ERROR: Operation needs " + Integer.toString(size) + " valuesn");
            return false;
        }
    }
}
// PARSER RULES
start
    : ( expr+ ';')+ EOF
                {
                    if(stackCheck(s, 1)) {
                        System.out.println("Result: " + s.pop() + ';');
                    }
                    if(s.size() > 0) {
                        System.out.println("Too many operands suppliedn");
                    }
                };
expr
    : atom+ OPERATION;
atom
    : INT;
// LEXER RULES
INT         
    : [0-9]+    { s.push(getText()); };
OPERATION   
    : '+'       {
                    if(stackCheck(s, 2)) {
                        second = parseInteger(s.pop());
                        first = parseInteger(s.pop());
                        s.push(Integer.toString(first + second));
                    }
                };
WS          
    : ( ' ' | 't' | 'r' | 'n' )+   {skip();};

我已经解决了我的问题。我仍然不完全理解为什么,但解析器规则似乎是在lexer规则之前运行的。因此,我修改了我的程序,使我的解析器规则具有推送新输入和执行操作的操作。

如果有人能帮我理解为什么会这样,我将不胜感激。在我看来,解析器规则是由其他解析器规则和lexer规则组成的。Lexer规则由正则表达式规则组成。由于lexer是最低的公分母,我认为lexer规则会首先被调用,但在我使用antlr时发现这是错误的。

最新更新