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