2017-09-19 9 views
1

J'ai essayé de construire une fonction: concat('A','B') OR concat('A',9)AntLR4: construire une fonction

Voici une grammaire exemple je l'ai écrit:

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

Mais pas en mesure de construire un arbre correctement.

Update1:

Voici l'arbre:

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

et la grammaire:

allFunction : FUNCTIONNAME LPAREN ARGUMENTS RPAREN; 

Update2:

Grammaire:

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

sortie Parsed:

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:

Je suis Tring pour construire une fonction: CONCAT(TEXT,TEXT) - (Entrée limitée à 2 paramètres). Cela fonctionne bien. J'ai mis en œuvre la fonction IF: IF(TEXT,TEXT,TEXT) - Cela fonctionne également très bien.

Le problème est, Je dois le modifier à: IF(BOOLEAN,INT,INT) - Mais avec la grammaire existante pour tout paramètre dans IF, il peut accepter UNSIGNED_INT y compris le premier paramètre.

Grammaire:

Voici le lien: https://ufile.io/undqs ou https://files.fm/u/7c44aaee

+1

S'il vous plaît donner un exemple de l'entrée que vous souhaitez analyser. "pas capable" n'aide pas beaucoup. Quelles erreurs avez-vous? Quels jetons sont produits avec 'grun allFunction -tokens -diagnostics '? – BernardK

+0

@BernardK Impossible de définir Concat comme élément racine. De plus, 2,5 devrait être différent. – Bond

+0

Vous avez le même problème avec ARGUMENTS qu'avec STRUCTURE_SELECTOR dans [link] (https://stackoverflow.com/questions/46256834/how-to-make-antlr4-fully-tokenize-terminal-nodes/46258041#46258041). Et encore une fois, quel est le fichier d'entrée, Tree est l'entrée ou la sortie que vous voulez construire? – BernardK

Répondre

1

Vous ne devez pas créer une règle de lexer ARGUMENTS. C'est quelque chose que l'analyse devrait gérer. Et les paramètres ne devraient probablement pas être TEXT jetons, mais une sorte d'expressions de sorte que CONCAT(CONCAT(A, B), C) fonctionne également.

Quelque chose comme ce serait un bon départ:

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; 

Lors de l'analyse de votre entrée comme celui-ci, vous pouvez simplement analyser une fonction qui prend un paramètre (de tout type) une quantité inconnue de temps. Par exemple. il analysera à la fois CONCAT('a','b') et IF(false,1,42). Mais notez qu'il analysera également IF(false,1,42,1,1,1,1,1,1,1,1,1,1). Ainsi, une fois l'analyse terminée, vous pouvez parcourir votre arbre d'analyse et valider que toutes les fonctions ont la bonne quantité de paramètres du type correct.

De même, existe-t-il un moyen d'éditer l'arbre d'analyse?

Voir: How to rewrite Antlr4 Parse Tree manually?

+0

Thanx pour la réponse. Lorsque j'essaie de construire cette grammaire, j'obtiens cette erreur: error (210): Les ensembles de règles suivants sont mutuellement à gauche-recursive [expression] – Bond

+0

Oui, juste recherché: 'error (210)' est une erreur de la version 3 d'ANTLR. Cette version ne fonctionnera pas avec la grammaire que j'ai posté. Utilisez la version 4 à la place. –

+0

C'est correct @Bart. Juste en considérant un autre scénario, que se passe-t-il si je dois limiter mes fonctions à deux paramètres seulement? – Bond