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