如何为以下标准编写语法 - Grammar for ANTLR4 - Custom Expressions

How to write grammar for the below criterion - Grammar for ANTLR4 - Custom Expressions

我正在编写一个简单的表达式,我正在寻找一种为此类表达式编写语法的方法,以便 ANTLR 可以使用此文件生成词法分析器和解析器。

我的表达式没有任何赋值。它们只是一些预先存在的字段上的一堆操作。 他们不需要评估。

我有一堆预定义的函数(例如后端理解的 SUM、MEAN、SUBSTR),这些函数应用于一些现有字段。

我需要的运算符是:- + , - , * , / 括号 : ( , ) 用于打开和关闭。 函数(关键字):SUM、MEAN、MAX SUBSTR。

示例:-

  1. ( A + B ) ,这也可以是 SUM(A,B)
  2. (平均值(A, B, C) + 最大值( X, 最小值(Y, Z)) + 2)/4
  3. SUBSTR("测试 1",0,6)

表达式可以扩展到多行。

这是我写的基础版本。

grammar ExpressionGrammar;

parse: (expr)+ EOF
    ;

expr: expr '/' expr
    | expr '*' expr  
    | expr '+' expr
    | expr '-' expr
    | NUM
    | function
    ;

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

arguments: expr ( ',' expr)*;

/* Tokens */ 

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;

最终我还必须 运行 对用户输入的表达式进行一些验证。如果我在只接受数字的 MAX() 函数中输入一个字符串,我应该能够知道错误所在的 line/position 并通知用户。我相信这是在解析阶段出现的?但只是把它放在那里,以防有任何输入,如果这个语法可以帮助我识别它。

几点说明:

  • 我不会将减号粘附到词法分析器中的数字,而是匹配 n 个一元表达式
  • 您在 expr 规则中缺少嵌套表达式 '(' expr ')'
  • 您可能还想匹配 expr 规则中的 ID
  • */ 通常具有相同的优先级,因此应该在同一替代项内分组(+- 相同)

这样的事情会更有意义:

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]*;
ID : [a-zA-Z_] [a-zA-Z]*;
COMMENT: '//' ~[\r\n]* -> skip;
WS: [ \t\n]+ -> skip;

Eventually I would also have to run some validations on the expression typed by the user. If I input a string inside a MAX() function which only accepts numbers, I should be able to know the line/position where the error is at and notify the user. I believe this comes during the parsing phase ? But just putting it out there, in case there are any inputs and if this grammar can help me identify that.

这种语义检查应该在解析之后进行。解析器创建一个解析树。然后在访问者内部遍历此解析树并评估输入。如果评估的输入不具有某些功能的正确类型,则可以生成 errors/warnings。