Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
224 views
in Technique[技术] by (71.8m points)

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

I have a simple expression that I am writing and I am looking for a way to write grammar for such expressions so that ANTLR can generate the lexer and parser using this file.

My expressions don't have any assignments. They are just a bunch of operations on some pre existing fields. They don't need to be evaluated.

I have a bunch of pre defined functions ( such as SUM, MEAN, SUBSTR which the backend understands ) and these functions are applied on some existing fields.

The operators I need are :- + , - , * , / Brackets : ( , ) for opening and closing. Functions ( keywords ) : SUM, MEAN, MAX SUBSTR.

Examples :-

  1. ( A + B ) , this can also be SUM(A,B)
  2. (MEAN(A, B, C) + MAX( X, MIN(Y,Z)) + 2)/4
  3. SUBSTR("TEST1",0,6)

The expression can extend to multi line.

Here is the basic version that I've written.

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: '//' ~[
]* -> skip;
WS: [ 
]+ -> 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.

question from:https://stackoverflow.com/questions/65914097/how-to-write-grammar-for-the-below-criterion-grammar-for-antlr4-custom-expre

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A couple of remarks:

  • I'd not glue the minus to a number in the lexer, but rather match n unary eexpression
  • you're missing the nested expression in your expr rule '(' expr ')'
  • you probably also want to match an ID inside the expr rule
  • * and / usually have the same precedence, so should be grouped inside the same alternative (same for + and -)

Something like this would make more sense:

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: '//' ~[
]* -> skip;
WS: [ 
]+ -> 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.

Such semantic checks should be done after parsing. The parser creates a parse tree. Inside a visitor you then walk this parse tree and evaluate the input. Then you can produce errors/warnings if the evaluated input does not have the proper type for certain functions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...