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



我有以下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: '//' ~[rn]* -> skip;
WS: [ tn]+ -> skip;

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

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

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

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

可以看到,"点"在字段。V1和字段。V2从文本中丢失,也有一个<丢失')'错误节点。我认为我应该让ANTLR明白表达式也可以有带点运算符的字段。>

在此之上的一个问题:-

(Var1)(Var2)    

ANTLR不会对上述场景抛出错误,表达式不应该是(Var1)(Var2)——它应该总是有操作符(Var1) *(Var2)或(Var1) +(Var2)等。解析器错误树没有生成此错误。如何修改语法以确保考虑到这种情况?

要识别IDFields.V1,将ID的Lexer规则更改为如下内容:

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

注意,由于每个节点"我将它作为一个词法分析器片段,可以用来组成ID规则。我还将0-9添加到片段的第二部分,因为您似乎希望在IDs

中允许数字。然后ID规则使用片段来构建Lexer规则,该规则允许ID中的点。

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

要处理(Var1)(Var2)中错误条件的检测,您需要Mike的建议,将EOF Lexer规则添加到parse解析器规则的末尾。如果没有EOF, ANTLR将在到达可识别expr ((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: '//' ~[rn]* -> skip;
WS: [ tn]+ -> skip;

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

最新更新