如何在语法中表达所需的'RETURN'语句

  • 本文关键字:RETURN 语句 语法 antlr4
  • 更新时间 :
  • 英文 :


我仍然是ANTLR的新手,如果我发布一个明显的问题,很抱歉。

我有一个相对简单的语法。我需要的是让用户能够输入如下内容:

if (condition)
{
    return true
}
else if (condition)
{
    return false
}
else
{
    if (condition)
    {
        return true
    }
    return false
 }

在下面的语法中,有没有办法确保如果输入字符串不包含"return"语句,则会标记错误?如果没有,我可以通过监听器来做吗,如果是,怎么做?

grammar Evaluator;
parse
 : block EOF
 ;
block
 : statement
 ;
statement
 : return_statement
 | if_statement
 ;
return_statement
: RETURN (TRUE | FALSE)
;
if_statement
 : IF condition_block (ELSE IF condition_block)* (ELSE statement_block)?
 ;
condition_block
 : expression statement_block
 ;
statement_block
 : OBRACE block CBRACE
 ;
expression
: MINUS expression                                  #unaryMinusExpression
| NOT expression                                    #notExpression
| expression op=(MULT | DIV) expression             #multiplicationExpression
| expression op=(PLUS | MINUS) expression           #additiveExpression
| expression op=(LTEQ | GTEQ | LT | GT) expression  #relationalExpression
| expression op=(EQ | NEQ) expression               #equalityExpression
| expression AND expression                         #andExpression
| expression OR expression                          #orExpression
| atom                                              #atomExpression
;
atom
 : function                                                 #functionAtom
 | OPAR expression CPAR                                     #parenExpression
 | (INT | FLOAT)                                            #numberAtom
 | (TRUE | FALSE)                                           #booleanAtom
 | ID                                                       #idAtom
 ;
function
 : ID OPAR (parameter (',' parameter)*)? CPAR
 ;
parameter
 : expression                                               #expressionParameter
 ;
OR : '||';
AND : '&&';
EQ : '==';
NEQ : '!=';
GT : '>';
LT : '<';
GTEQ : '>=';
LTEQ : '<=';
PLUS : '+';
MINUS : '-';
MULT : '*';
DIV : '/';
NOT : '!';
OPAR : '(';
CPAR : ')';
OBRACE : '{';
CBRACE : '}';
ASSIGN : '=';
RETURN : 'return';
TRUE : 'true';
FALSE : 'false';
IF : 'if';
ELSE : 'else';
// ID either starts with a letter then followed by any number of a-zA-Z_0-9
// or starts with one or more numbers, then followed by at least one a-zA-Z_ then followed
// by any number of a-zA-Z_0-9
ID
 : [a-zA-Z] [a-zA-Z_0-9]*
 | [0-9]+ [a-zA-Z_]+ [a-zA-Z_0-9]*
 ;
INT
 : [0-9]+
 ;
FLOAT
 : [0-9]+ '.' [0-9]* 
 | '.' [0-9]+
 ;
SPACE
 : [ trn] -> skip
 ;
 // Anything not recognized above will be an error
ErrChar
  : .
  ;

罗斯的回答是完全正确的。您将语法设计为接受特定输入。如果输入流不对应,解析器将抱怨。

请允许我像这样重写您的语法:

grammar Question;
/* enforce each block to end with a return statement */
a_grammar
    :   if_statement EOF
    ;
if_statement
    :   'if' expression statement+ ( 'else' statement+ )?
    ;
statement
    :   if_statement
// other statements
    |   statement_block
    ;
statement_block
    :   '{' statement* return_statement '}'
    ;
return_statement
    :   'return' ( 'true' | 'false' )
    ;
expression // reduced to a strict minimum to answer the OP question
    :   atom
    |   atom '<=' atom
    |   '(' expression ')'
    ;
atom
    :   ID
    |   INT
    ;
ID
    : [a-zA-Z] [a-zA-Z_0-9]*
    | [0-9]+ [a-zA-Z_]+ [a-zA-Z_0-9]*
    ;
INT : [0-9]+ ;
WS  : [ trn] -> skip ;
 // Anything not recognized above will be an error
ErrChar
  : .
  ;

使用以下输入

if (a <= 7)
    {
        return true
    }
else 
    if (xyz <= 99)
    {
        return false
    }
    else incor@#!$rect
    {
        if (b <= a)
        {
            return true
        }
        return false
    }

你得到这些令牌

[@0,0:1='if',<'if'>,1:0]
[@1,3:3='(',<'('>,1:3]
[@2,4:4='a',<ID>,1:4]
[@3,6:7='<=',<'<='>,1:6]
...
[@21,82:85='else',<'else'>,10:1]
[@22,87:91='incor',<ID>,10:6]
[@23,92:92='@',<ErrChar>,10:11]
[@24,93:93='#',<ErrChar>,10:12]
[@25,94:94='!',<ErrChar>,10:13]
[@26,95:95='$',<ErrChar>,10:14]
[@27,96:99='rect',<ID>,10:15]
[@28,102:102='{',<'{'>,11:1]
...
line 10:6 mismatched input 'incor' expecting {'if', '{'}

如果使用 -gui 选项运行测试远程测试机组 (-gui),它会显示解析树,其中错误标记以粉红色显示!

grun Question a_grammar -gui data.txt 

我以前从未玩过监听器。通过 Visitor,在 VisitStatement(StatementContext context) 方法中,检查 context.return_statement() (ReturnStatementContext 是否为 null。如果为 null,则引发异常。

我也是新手。 我正在考虑迫使词法分析器通过需要返回语句,因此而不是:

statement
 : return_statement
 | if_statement
 ;

它说一个语句要么是if_statement要么是return_statement我会尝试这样的事情:

statement
 : (if_statement)? return_statement
 ;

其中(我相信)说if_statement是可选的,但return_statement必须始终发生。 但您可能想尝试如下操作:

block_data : statements+ return_statement;

语句可以if_statements等,并且允许其中一个或多个。

我会对上述所有内容持保留态度,因为我只使用ANTLR4一周左右。 我有 4 个 .g4 文件在工作,并且对 ANTLR 感到满意,但您实际上可能比我有更多的 ANTLR 坚持时间。

-问候

相关内容

  • 没有找到相关文章

最新更新