I'm having trouble with a simple grammar I have created to support function calls.
I am using the lemon-based PHP_ParserGenerator by Greg.
This is the relevant part of the grammar:
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];
}
When I initialize the parser with a context of array('user' => array('name' => 'Dennis'));
and execute the following code:
$parser->doParse(PelParser::CONTEXT_REFERENCE, 'user.name');
$parser->doParse(0, 0);
The $result
is as follows: 'Dennis'. Life is good.
But when I supply a CONTEXT_REFERENCE as argument to a function call, it doesn't work:
$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);
The $result
is 'us3r.nam3'. Not quite as expected. For the record, the expected output is of course 'D3nnis'. (user.name first gets replaced with the string 'Dennis' and after that passed to the str_replace()
function).
I suspect it has something to do with precedence. But I can't figure what I should change to make this. The very sparse Lemon documentation is not of very great help.
Any help would be greatly appreciated! Thanks