Javascript 如何为下面的标准编写语法-ANTLR4语法-自定义表达式
我正在编写一个简单的表达式,我正在寻找一种为这些表达式编写语法的方法,这样ANTLR就可以使用这个文件生成lexer和parser 我的表达式没有任何赋值。它们只是一些预先存在的字段上的一系列操作不需要对其进行评估。 我有一堆预定义的函数(如SUM、MEAN、SUBSTR,后端可以理解),这些函数应用于一些现有字段 我需要的运算符是:-+,-,*/ 括号:(,)用于打开和关闭。 函数(关键字):求和、平均值、最大值SUBSTR 示例:-Javascript 如何为下面的标准编写语法-ANTLR4语法-自定义表达式,javascript,antlr,antlr4,grammar,Javascript,Antlr,Antlr4,Grammar,我正在编写一个简单的表达式,我正在寻找一种为这些表达式编写语法的方法,这样ANTLR就可以使用这个文件生成lexer和parser 我的表达式没有任何赋值。它们只是一些预先存在的字段上的一系列操作不需要对其进行评估。 我有一堆预定义的函数(如SUM、MEAN、SUBSTR,后端可以理解),这些函数应用于一些现有字段 我需要的运算符是:-+,-,*/ 括号:(,)用于打开和关闭。 函数(关键字):求和、平均值、最大值SUBSTR 示例:- (A+B),这也可以是和(A,B) (平均值(A,B,C)
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()函数中输入字符串,我应该能够知道错误所在的行/位置并通知用户。我相信这是在分析阶段?但只要把它放在那里,以防有任何输入,如果这个语法能帮助我识别它。几句话:
- 我不会将负号粘贴到lexer中的数字上,而是匹配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;
最后,我还必须对用户键入的表达式运行一些验证。如果我在只接受数字的MAX()函数中输入字符串,我应该能够知道错误所在的行/位置并通知用户。我相信这是在分析阶段?但只要把它放在那里,以防有任何输入,如果这个语法能帮助我识别它
这种语义检查应该在解析之后进行。解析器创建一个解析树。然后在访问者内部遍历此解析树并评估输入。然后,如果评估输入的类型不适合某些函数,则可能会产生错误/警告。我首先要阅读ANTLR文档和/或学习一些ANTLR教程。当你已经完成了,并且陷入了实际编写语法的过程中,你可以自由地提出这样的问题。像你这样的问题,没有实际的技术问题,而是“有人能指导我吗?”,在这里不太合适(见:)。我想你已经开始写语法了,请把它添加到你的问题中,并解释它的错误。@BartKiers我的错,我应该在发布问题之前添加它。你现在可以看一下吗?我还添加了3个测试片段。我只是想看看这个语法是否有效,我是否遗漏了一些小格。我已经从您的一个答案中添加了函数实现,这证明非常有用。我的表达式有时会以括号开始(第二个示例),因此我添加了(expr)+,这是正确的方法吗?谢谢Bart,现在有意义了。只是一个简单的问题——“expr:MIN expr”在这一行中,MIN表示什么?另外,如果在解析后我必须检查匹配的括号,我是否必须将函数语法写成“function:ID OPEN\u PAR arguments?CLOSE\u PAR”;这对于标记化是必要的吗?或者像我在上述语法中所做的那样,仅仅添加一个标记作为OPEN_PART和CLOSE_PAR就足够了?
MIN
代表负数。这是与-
:MIN:'-'匹配的规则代码>“…正如我在上述语法中所做的那样足够吗?”是的,这样就可以了。我有这样一个表达式:-(Fields.V1)*(Fields.V2)+(Constants.Value1)*(Constants.Value2)。ANTLR解析器根据上面的语法(FieldsV1)*(FieldsV2)+(常量)生成以下文本。如您所见,文本中缺少Fields.V1和Fields.V2中的“点”,并且还有一个