Antlr4 如何表达所需的';返回';语法中的语句

Antlr4 如何表达所需的';返回';语法中的语句,antlr4,Antlr4,我还是ANTLR的新手,如果我发布了一个明显的问题,那么很抱歉 我的语法比较简单。我需要的是用户能够输入以下内容: if (condition) { return true } else if (condition) { return false } else { if (condition) { return true } return false } 在我下面的语法中,是否有方法确保在输入字符串不包含“return”语句时标

我还是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
 : [ \t\r\n] -> skip
 ;

 // Anything not recognized above will be an error
ErrChar
  : .
  ;
语法评估器;
作语法分析
:块EOF
;
块
:声明
;
陈述
:return\u语句
|if_语句
;
return\u语句
:返回(真|假)
;
if_语句
:IF条件块(ELSE IF条件块)*(ELSE语句块)?
;
条件块
:表达式语句\u块
;
语句块
:正面块C面
;
表达
:负数表达式#一元负数表达式
|非表达式#notExpression
|表达式op=(MULT | DIV)表达式#乘法表达式
|表达式op=(加|减)表达式#加法表达式
|表达式op=(LTEQ | GTEQ | LT | GT)表达式#关系表达式
|表达式op=(EQ | NEQ)表达式#等式表达式
|表达式和表达式#和表达式
|表达式或表达式#或表达式
|原子#原子表达式
;
原子
:功能#功能汤姆
|OPAR表达CPAR#parenExpression
|(INT | FLOAT)#numberAtom
|(真|假)#布尔原子
|我是汤姆
;
功能
:ID OPAR(参数(','参数)*)?CPAR
;
参数
:表达式#表达式参数
;
或:“| |”;
及:"&";
等式:'=';
NEQ:“!=”;
GT:“>”;
LT:'=';

LTEQ:“我以前从未和听众玩过。
通过访问者,在VisitStatement(StatementContext)方法中,检查context.return_语句()(ReturnStatementContext)是否为空。如果为null,则抛出异常。

我以前从未使用过侦听器。
通过访问者,在VisitStatement(StatementContext)方法中,检查context.return_语句()(ReturnStatementContext)是否为空。如果为空,则抛出异常。

我也是新手。我想强迫莱克瑟呕吐 需要返回语句,因此不是:

statement
 : return_statement
 | if_statement
 ;
也就是说一个语句是if_语句或return_语句

statement
 : (if_statement)? return_statement
 ;
block_data : statements+ return_statement;
这(我相信)表示if_语句是可选的,但return_语句必须始终出现。但您可能想尝试以下方法:

statement
 : (if_statement)? return_statement
 ;
block_data : statements+ return_statement;
Where语句可以是if_语句等,并且允许使用其中一个或多个语句

我对以上的一切都持保留态度,因为我只在ANTLR4上工作了一周左右。我有4.g4文件在工作,我对ANTLR很满意,但实际上你可能比我有更多的ANTLR坚持时间


-我也是个新手。我想强迫莱克瑟呕吐 需要返回语句,因此不是:

statement
 : return_statement
 | if_statement
 ;
也就是说一个语句是if_语句或return_语句

statement
 : (if_statement)? return_statement
 ;
block_data : statements+ return_statement;
这(我相信)表示if_语句是可选的,但return_语句必须始终出现。但您可能想尝试以下方法:

statement
 : (if_statement)? return_statement
 ;
block_data : statements+ return_statement;
Where语句可以是if_语句等,并且允许使用其中一个或多个语句

我对以上的一切都持保留态度,因为我只在ANTLR4上工作了一周左右。我有4.g4文件在工作,我对ANTLR很满意,但实际上你可能比我有更多的ANTLR坚持时间


-罗斯的回答完全正确。你设计你的语法来接受某种输入。如果输入流不对应,解析器将抱怨

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

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  : [ \t\r\n] -> 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  : [ \t\r\n] -> skip ;

 // Anything not recognized above will be an error
ErrChar
  : .
  ;

在我看来,来访者已经太晚了。我有一个编辑器,它使用解析器在调用访问之前检查语法。如果语法错误,我们将向用户显示错误(行和列)。我有一个编辑器,它使用解析器在调用访问之前检查语法。如果语法错误,我们将向用户显示错误(行和列)。