简体   繁体   中英

AntLR4 : Build A function

I've been trying to build a function: concat('A','B') OR concat('A',9)

Here is a sample grammar I have written :

    LPAREN : '(' ;
    RPAREN : ')' ;
    FUNCTIONNAME : 'CONCAT' ;
    ARGUMENTS : TEXT (',' TEXT)* ;
    TEXT : ('a'..'z' | '0'..'9' | 'A'..'Z')+; 
    allFunction : FUNCTIONNAME LPAREN ARGUMENTS (',' ARGUMENTS)* RPAREN ;

But not able to build a tree properly.

Update1 :

Here is the Tree:

  0 null
-- 11 CONCAT
-- 4 (
-- 13 2,5
-- 5 ) 

and the grammar :

allFunction : FUNCTIONNAME LPAREN ARGUMENTS RPAREN;

Update2 :

Grammar:

allfunction : COMMA | FUNCTIONNAME LPAREN ARGUMENTS (COMMA ARGUMENTS)* RPAREN ;

Parsed output:

CONCAT(A,B,C)

[@0,0:5='CONCAT',<8>,1:0]
[@1,6:6='(',<1>,1:6]
[@2,7:11='A,B,C',<9>,1:7]
[@3,12:12=')',<2>,1:12]
[@4,13:14='\n\n',<7>,1:13]
[@5,15:14='<EOF>',<-1>,3:0]

Update3 :

I have been tring to build a function : CONCAT(TEXT,TEXT) -(Input limited to 2 params). This works fine. I have implemented IF function : IF(TEXT,TEXT,TEXT) - This also works fine.

The problem is, I have to modify it to: IF(BOOLEAN,INT,INT) - But with existing grammar for any parameter in IF, it can accept UNSIGNED_INT including the first parameter.

Grammar :

Here is the link: https://ufile.io/undqs or https://files.fm/u/7c44aaee

You should not create a lexer rule ARGUMENTS . This is something the parse should handle. And the parameters should probably not be TEXT tokens, but some sort of expressions so that CONCAT(CONCAT(A, B), C) also works.

Something like this would be a good start:

grammar T;

parse
 : expression EOF
 ;

expression
 : expression 'AND' expression
 | expression 'OR' expression
 | function
 | bool
 | TEXT
 | NUMBER
 | TEXT
 | ID
 ;

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

arguments
 : expression ( ',' expression )*
 ;

bool
 : TRUE
 | FALSE
 ;

TRUE         : 'true';
FALSE        : 'false';
NUMBER       : ( [0-9]* '.' )? [0-9]+;
ID           : [a-zA-Z_] [a-zA-Z0-9_]*;
TEXT         : '\'' ~[\r\n']* '\'';
SPACE        : [ \t\r\n]+ -> skip;

When parsing your input like this, you can simply parse any function that takes any parameter (of any type) an unknown amount of times. Eg it will parse both CONCAT('a','b') and IF(false,1,42) . But note that it will also parse IF(false,1,42,1,1,1,1,1,1,1,1,1,1) . So after the parsing is finished, you can walk your parse-tree and validate that all the functions have the proper amount of parameters of the correct type.

Also, Is there any way to edit parse tree?

See: How to rewrite Antlr4 Parse Tree manually?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM