2012-04-10 14 views
5

Mam problem z prostą gramatyką, którą utworzyłem, aby obsługiwać wywołania funkcji.
Używam opartego na cytrynach PHP_ParserGenerator firmy Greg.Problemy z gramatyką cytryny (pierwszeństwo?)

Jest odpowiednia część gramatyki:

program ::= expr(A).      { $this->result = A; } 

value(A) ::= SIMPLE_STRING(B).    { A = B; } 
value(A) ::= NUMBER(B).      { A = B; } 
value(A) ::= CONTEXT_REFERENCE(B).   { A = B; } 

arg_list ::= arg_list SEPARATOR value(B). { $this->args[] = B; } 
arg_list ::= value(B).      { $this->args[] = B; } 
arg_list ::= . 

expr(A) ::= SIMPLE_STRING(B) PAREN_LEFT arg_list PAREN_RIGHT. { A = call_user_func_array(B, $this->args); } 

expr(A) ::= CONTEXT_REFERENCE(B). { 
    list($context, $key) = explode('.', B); 
    A = $this->context[$context][$key]; 
} 

Kiedy zainicjować parser w kontekście array('user' => array('name' => 'Dennis')); i wykonać następujący kod:

$parser->doParse(PelParser::CONTEXT_REFERENCE, 'user.name'); 
$parser->doParse(0, 0); 

$result jest w następujący sposób: " Dennis ". Życie jest dobre.

Ale kiedy dostarczyć CONTEXT_REFERENCE jako argument wywołania funkcji, to nie działa:

$parser->doParse(PelParser::SIMPLE_STRING, 'str_replace'); 
$parser->doParse(PelParser::PAREN_LEFT, '('); 
$parser->doParse(PelParser::SIMPLE_STRING, 'e'); 
$parser->doParse(PelParser::SEPARATOR, ','); 
$parser->doParse(PelParser::NUMBER, 3); 
$parser->doParse(PelParser::SEPARATOR, ','); 
$parser->doParse(PelParser::CONTEXT_REFERENCE, 'user.name'); 
$parser->doParse(PelParser::PAREN_RIGHT, ')'); 
$parser->doParse(0, 0); 

$result jest 'us3r.nam3'. Nie całkiem zgodnie z oczekiwaniami. Dla rekordu oczekiwany wynik to oczywiście "D3nnis". (user.name pierwszy zostaje zamieniony na ciąg "Dennis", a następnie przekazany do funkcji str_replace()).

Podejrzewam, że ma to coś wspólnego z pierwszeństwem. Ale nie mogę wymyślić, co powinienem zmienić, żeby to zrobić. Bardzo skąpa dokumentacja Lemon nie jest bardzo pomocna.

Każda pomoc będzie bardzo ceniona! Dzięki

Odpowiedz

1

Wygląda na to, że znalazłem odpowiedź na moje pytanie.

Kiedy zmienić gramatykę do:

program ::= expr(A).      { $this->result = A; } 

value(A) ::= SIMPLE_STRING(B).    { A = B; } 
value(A) ::= NUMBER(B).      { A = B; } 
value(A) ::= CONTEXT_REFERENCE(B). { 
    // B=='{context}.{name}' 
    list($context, $key) = explode('.', B); 
    A = $this->context[$context][$key]; 
} 

arg_list ::= arg_list SEPARATOR value(B). { $this->args[] = B; } 
arg_list ::= value(B).      { $this->args[] = B; } 
arg_list ::= . 

expr(A) ::= SIMPLE_STRING(B) PAREN_LEFT arg_list PAREN_RIGHT. { A = call_user_func_array(B, $this->args); } 

wydaje się działać zgodnie z oczekiwaniami.
Problemem było to, że stworzył niejasności w pierwszej gramatyki:

value(A) ::= CONTEXT_REFERENCE(B).   { A = B; } 

expr(A) ::= CONTEXT_REFERENCE(B). { 
    list($context, $key) = explode('.', B); 
    A = $this->context[$context][$key]; 
} 

Zostawię Pytania i odpowiedzi tu więc inni mogą korzystać z moich błędów :) Jeśli ktoś ma coś do podzielenia, proszę .

Powiązane problemy