首页 > 解决方案 > 如何为以下标准编写语法 - ANTLR4 语法 - 自定义表达式

问题描述

我正在编写一个简单的表达式,我正在寻找一种为此类表达式编写语法的方法,以便 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("TEST1",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() 函数中输入一个字符串,我应该能够知道错误所在的行/位置并通知用户。我相信这是在解析阶段出现的?但只要把它放在那里,以防有任何输入,如果这个语法可以帮助我识别它。

标签: javascriptantlrantlr4grammar

解决方案


几点说明:

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

这样的事情会更有意义:

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;

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

这种语义检查应该在解析之后进行。解析器创建一个解析树。然后,在访问者内部,您可以遍历此解析树并评估输入。然后,如果评估的输入没有特定功能的正确类型,则可以产生错误/警告。


推荐阅读