ANTLR4 语法 - 字段和扩展表达式中 "dot" 的问题

ANTLR4 Grammar - Issue with "dot" in fields and extended expressions

我有以下ANTLR4语法

grammar ExpressionGrammar;

parse: (expr)
     ;

expr: MIN expr
    | expr ( MUL | DIV ) expr
    | expr ( ADD | MIN ) expr
    | NUM
    | function
    | '(' expr ')'
    ;

function : ID '(' arguments? ')';

arguments: expr ( ',' expr)*;

/* Tokens */

MUL : '*';
DIV : '/';
MIN : '-';
ADD : '+';
OPEN_PAR : '(' ;
CLOSE_PAR : ')' ;

NUM : '0' | [1-9][0-9]*;
ID : [a-zA-Z_] [a-zA-Z]*;
COMMENT: '//' ~[\r\n]* -> skip;
WS: [ \t\n]+ -> skip;

我有一个这样的输入表达式:-

(Fields.V1)*(Fields.V2) + (Constants.Value1)*(Constants.Value2)

ANTLR 解析器根据上面的语法生成了以下文本:-

(FieldsV1)*(FieldsV2)+(Constants<missing ')'> 

如您所见,文本中缺少 Fields.V1 和 Fields.V2 中的“点”,并且还有一个

除此之外的一个问题:-

 (Var1)(Var2)    

ANTLR 不会为上述场景抛出错误,表达式不应该是 (Var1)(Var2) -- 它应该始终包含运算符 (var1)*(var2) 或 (var1)+(var2)等解析器错误树不生成此错误。应该如何修改语法以确保考虑到这种情况。

要识别像 Fields.V1 这样的 ID,请将 ID 的 Lexer 规则更改为如下内容:

fragment ID_NODE: [a-zA-Z_][a-zA-Z0-9]*;
ID: ID_NODE ('.' ID_NODE)*;

注意,因为 ID 的每个“节点”都遵循相同的规则,所以我将它作为一个词法分析器片段,我可以用它来编写 ID 规则。我还在片段的第二部分添加了 0-9,因为您似乎希望在 IDs

中允许数字

然后 ID 规则使用片段构建 Lexer 规则,允许 ID.

中的点

您也没有将 ID 添加为有效的 expr 替代项

要处理 (Var1)(Var2) 中错误条件的检测,您需要 Mike 的建议将 EOF Lexer 规则添加到 parse 解析器规则的末尾。如果没有 EOF,ANTLR 将在到达已识别表达式 ((Var1)) 的末尾时立即停止解析。 EOF 说“然后你需要找到一个 EOF”,所以 ANTLR 将继续解析到 (Var2) 并给你错误。

处​​理您的两个示例的修订版本:

grammar ExpressionGrammar;

parse: expr EOF;

expr:
    MIN expr
    | expr ( MUL | DIV) expr
    | expr ( ADD | MIN) expr
    | NUM
    | ID
    | function
    | '(' expr ')';

function: ID '(' arguments? ')';

arguments: expr ( ',' expr)*;

/* Tokens */

MUL: '*';
DIV: '/';
MIN: '-';
ADD: '+';
OPEN_PAR: '(';
CLOSE_PAR: ')';

NUM: '0' | [1-9][0-9]*;
fragment ID_NODE: [a-zA-Z_][a-zA-Z0-9]*;
ID: ID_NODE ('.' ID_NODE)*;
COMMENT: '//' ~[\r\n]* -> skip;
WS: [ \t\n]+ -> skip;

(现在我已经通读了评论,这几乎只是在应用评论中的建议)