ANTLR if语句的正确语法

时间:2018-05-02 17:41:11

标签: antlr antlr4 context-free-grammar

我已经为我决定调用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部分。我不知道如何解决这个问题,任何想法?

1 个答案:

答案 0 :(得分:0)

public String getHeaders(@RequestHeader(value="Content-Type", defaultValue="some value") String ContentType) 很好但是如果你在else之前添加另一个变量会更容易,这样你就可以使用监听器的ifcond方法了。使用此:

exit

现在您可以轻松地编辑ifelsecond: ifcond | statement ; ifcond : 'if (' condition ') then' statement+ 'stop' | 'if (' condition ') then' ifelsecond+ 'else' statement+ 'stop' ; ,如下所示:

MyListner.cpp

你的语法很好,但你正在使用一种不太需要的制作,这使得听众代码更难写。由于您使用的是void MyListener::enterIfcond(swlParser::IfcondContext *ctx) { string cond = ctx->condition()->getText(); fixString(cond); cout << "\n" << string(indent, ' ') << "if (" << cond << ") {" << endl; } void MyListener::exitIfcond(swlParser::IfcondContext *ctx) { cout << string(indent, ' ') << "}\n" << endl; } void MyListener::exitIfelsecond(swlParser::IfelsecondContext *ctx) { cout << string(indent, ' ') << "} else {" << endl; } ,因此您不会遇到dangling else问题。

我给出的解决方案可能不是最好的但是它有效,因为语法并不含糊,因为&#34;范围&#34;包含在某些内容中的语句(在您的情况下为stopthen)。