Отказ от ответственности: это для курсовой работы, и это также мой первый пост 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();};