0

免责声明:这是针对课程作业的,这也是我的第一篇 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 parse\n");
            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) + " values\n");
            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 supplied\n");
                    }
                };
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();};
4

1 回答 1

0

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

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

于 2014-11-14T22:14:02.160 回答