基本表达式Antlr4语法

Basic expression Antlr4 grammar

我正在尝试编写一个以 '{' 开头并以 '}' 结尾的基本语法。 它只有 'IF''Else'。还有一些基本的表达式,比如 a = (算术运算). 不需要变量初始化和声明检查。有人可以指导我吗,我正在写语法,但它不能正常工作。我在下面写我的语法代码。

prog: stat_block+ EOF;

stat_block
: OBRACE block CBRACE
;

block
: stat*
;

stat: expr
;

expr: expr ('*'|'/') expr
| expr ('+'|'-') expr
| expr ('<'|'<='|'>='|'>'|'=') expr
| expr ( '&&'|'||') expr
| expr '(' exprList? ')'
| IF condition_block  (ELSE stat_block)?
;

exprList : expr (',' expr)* ;

condition_block
: OPAR expr CPAR stat_block
;

IF : 'IF';
ELSE : 'ELSE';
OPAR : '(';
CPAR : ')';
OBRACE : '{';
CBRACE : '}';
ID : [a-zA-Z]+ ;
INT : [0-9]+ ;
NEWLINE:'\r'? '\n' ;
WS : [ \t]+ -> skip ;

我正在尝试为其编写语法的示例代码

{
 IF ( a > 10 && funcName(param) = Found ) {
    b = 10;
 }
 ELSE {
    b=20;
 }
}

If语句可以嵌套。如果有人可以为我提供语法或告诉我,我做错了什么。那将是巨大的帮助。谢谢。

通过以下更改,我得到了一个没有错误的解析和一个解析树:

1.

NEWLINE:'\r'? '\n' ;

您没有使用 NEWLINE 标记,因此,您可能想从解析器规则中隐藏该标记。 -> skip 是实现该目标的一种简单方法。

NEWLINE:'\r'? '\n' -> skip;
expr
    : expr ('*' | '/') expr
    | expr ('+' | '-') expr
    | expr ('<' | '<=' | '>=' | '>' | '=') expr
    | expr ( '&&' | '||') expr
    | expr '(' exprList? ')'
    | IF condition_block (ELSE stat_block)?
    ;

IDs 和 NUMBERs 也应该被认为是表达式

expr
    : expr ('*' | '/') expr
    | expr ('+' | '-') expr
    | expr ('<' | '<=' | '>=' | '>' | '=') expr
    | expr ( '&&' | '||') expr
    | expr '(' exprList? ')'
    | IF condition_block (ELSE stat_block)? 
    | ID
    | INT
    ;
block
: stat*
;

stat: expr
;

你还没有考虑表达式

;的possibility/requirement

不清楚你的意图。所以

简单地说,每个表达式 可以 后跟一个 ;

stat: expr ';'?;

当表达式彼此相邻而没有 ; 时,这可能会造成一些混淆,因此请考虑将其设为非可选。

stat: expr ';';

许多语言将 ; 视为 expression/statement 分隔符。

block: (stat (stat ';')*)?;

变化总和:

grammar Basic
    ;

prog: stat_block+ EOF;

stat_block: OBRACE block CBRACE;

block: (stat (stat ';')*)?;

stat: expr ';'?;

expr
    : expr ('*' | '/') expr
    | expr ('+' | '-') expr
    | expr ('<' | '<=' | '>=' | '>' | '=') expr
    | expr ( '&&' | '||') expr
    | expr '(' exprList? ')'
    | IF condition_block (ELSE stat_block)?
    | ID
    | INT
    ;

exprList: expr (',' expr)*;

condition_block: OPAR expr CPAR stat_block;

IF:      'IF';
ELSE:    'ELSE';
OPAR:    '(';
CPAR:    ')';
OBRACE:  '{';
CBRACE:  '}';
ID:      [a-zA-Z]+;
INT:     [0-9]+;
NEWLINE: '\r'? '\n' -> skip;
WS:      [ \t]+     -> skip;