2012-05-09 18 views
5

Me gustaría hacer una gramática que permita las llamadas a la función al curry.cómo eliminar la recursividad a la izquierda

Es decir:

a() /// good 
a()() /// good 
a()()() /// good 
a(a) /// good 
a(a()()) /// good 
/// etc 

Mi primer intento fue la siguiente:

ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 

fncall : expr '(' (expr (',' expr)*)? ')'; 

expr : ID|fncall; 

Pero eso falla debido a la recursividad por la izquierda.

Respuesta

3

Suponiendo (a)() también sería válida, aquí es una manera de resolver esto:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    EXPR_LIST; 
    CALL; 
    INDEX; 
    LOOKUP; 
} 

parse 
: expr EOF -> expr 
; 

expr 
: add_expr 
; 

add_expr 
: mul_exp (('+' | '-')^ mul_exp)* 
; 

mul_exp 
: atom (('*' | '/')^ atom)* 
; 

atom 
: fncall 
| NUM 
; 

fncall 
: (fncall_start -> fncall_start) ('(' expr_list ')' -> ^(CALL $fncall expr_list) 
            | '[' expr ']'  -> ^(INDEX $fncall expr) 
            | '.' ID   -> ^(LOOKUP $fncall ID) 
           )* 
; 

fncall_start 
: ID 
| '(' expr ')' -> expr 
; 

expr_list 
: (expr (',' expr)*)? -> ^(EXPR_LIST expr*) 
; 

NUM : '0'..'9'+; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 

El analizador generado a partir de la gramática anterior se analiza la entrada:

(foo.bar().array[i*2])(42)(1,2,3) 

y construir la siguiente AST:

enter image description here

Sin las reglas de reescritura de árboles, la gramática se vería así:

grammar T; 

parse 
: expr EOF 
; 

expr 
: add_expr 
; 

add_expr 
: mul_exp (('+' | '-') mul_exp)* 
; 

mul_exp 
: atom (('*' | '/') atom)* 
; 

atom 
: fncall 
| NUM 
; 

fncall 
: fncall_start ('(' expr_list ')' | '[' expr ']' | '.' ID)* 
; 

fncall_start 
: ID 
| '(' expr ')' 
; 

expr_list 
: (expr (',' expr)*)? 
; 

NUM : '0'..'9'+; 
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*; 
+0

¿Le importaría explicar cómo funcionan los predicados en este contexto? Pero muchas gracias por el código. –

+0

@luxun, no usé ningún predicado: es solo una gramática (simple) que crea un AST, por lo que hay un par de reglas de reescritura. Edité mi respuesta para incluir la misma gramática, pero sin las reglas de reescritura (no hace falta decir que esa gramática no creará un AST como en la imagen que publiqué ...). –

+0

Ah, ya veo. Muchas gracias. –

Cuestiones relacionadas