Я создал простую грамматику для языка, который я решил назвать SWL:
grammar swl;
program : 'begin' statement+ 'end';
statement : assign | add | sub | mul | div | print | whilecond | ifcond ;
condition : expr ;
expr : '(' expr ')' | expr 'and' expr | expr 'or' expr | 'not' expr | expr '=' expr | expr '>=' expr | expr '<=' expr | expr '>' expr | expr '<' expr | ID | NUMBER;
assign : 'let' ID 'be' (NUMBER | ID) ;
print : 'print' (NUMBER | ID) ;
add : 'add' (NUMBER | ID) 'to' ID ;
sub : 'sub' (NUMBER | ID) 'to' ID ;
mul : 'mul' (NUMBER | ID) 'to' ID ;
div : 'div' (NUMBER | ID) 'to' ID ;
whilecond : 'while (' condition ') do' statement+ 'stop' ;
ifcond : 'if (' condition ') then' statement+ 'stop' | 'if (' condition ') then' statement+ 'else' statement+ 'stop' ;
ID : [a-z]+ ;
NUMBER : [0-9]+ ;
WS : [ \n\t]+ -> skip;
ErrorChar : . ;
У меня немного проблемы с ifcond
. Учитывая эту программу SWL:
begin
if (not(a > 1) or (c <= b)) then
mul 5 to k
stop
end
Я могу получить вывод C ++:
#include <iostream>
using namespace std;
int main() {
if ( !(a>1) || (c<=b)) {
k *= 5;
}
}
Это здорово! Кстати со следующим входом:
begin
if (not(a > 1) or (c <= b)) then
mul 5 to k
else
mul 15 to k
stop
end
У меня есть такой вывод:
#include <iostream>
using namespace std;
int main() {
if ( !(a>1) || (c<=b)) {
k *= 5;
k *= 15;
}
}
Как видите, во втором примере отсутствует часть else statement
. Что случилось? Должен ли я изменить грамматику ifcond
и добавить другое правило / переменную? Это файл MyListner.cpp
.
void fixString(string& cond) {
size_t pos = cond.find("and", 0);
if (pos != string::npos) { cond.replace(pos, 3, " && "); }
pos = cond.find("or", 0);
if (pos != string::npos) { cond.replace(pos, 2, " || "); }
pos = cond.find("not", 0);
if (pos != string::npos) { cond.replace(pos, 3, " !"); }
}
void MyListener::enterIfcond(swlParser::IfcondContext *ctx) {
string cond = ctx->condition()->getText();
fixString(cond);
cout << string(indent, ' ') << "if (" << cond << ") {" << endl;
}
void MyListener::exitIfcond(swlParser::IfcondContext *ctx) {
cout << string(indent, ' ') << "}" << endl;
}
Я подозреваю, что грамматика недостаточно хороша, и мне понадобится другая переменная для вызова части else. Я не знаю, как решить эту проблему, любая идея?