2012-04-10 5 views
5

함수 호출을 지원하기 위해 만든 간단한 문법에 문제가 있습니다.
Greg의 레몬 기반 PHP_ParserGenerator를 사용하고 있습니다.레몬 문법의 문제 (우선?)

이 문법의 중요한 부분이다 : I가 array('user' => array('name' => 'Dennis'));의 문맥 파서를 초기화하고 다음 코드를 실행할 때

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]; 
} 

는 다음

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

$result이므로 ' 데니스 '. 인생은 좋습니다.

하지만 함수 호출에 인수로 CONTEXT_REFERENCE를 제공 할 때, 그것은 작동하지 않습니다 다음 $result는 'us3r.nam3'이다

$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); 

. 예상대로. 기록을 위해 예상되는 출력은 물론 'D3nnis'입니다. (user.name 첫 번째은 'Dennis'문자열로 바뀌고 이후에는 str_replace() 함수로 전달됩니다.

우선 순위와 관련이 있다고 생각됩니다. 그러나 나는 이것을 만들기 위해 내가 무엇을 바꾸어야 하는지를 알 수 없다. 아주 희소 한 레몬 문서는 큰 도움이되지 않습니다.

도움이 될 것입니다. 감사합니다.

답변

1

저는 제 질문에 대한 답을 찾은 것 같습니다. 나는 내 문법을 변경하면

는 :

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); } 

이 예상대로 작동하는 것 같다.
문제는 내가 처음 문법의 모호함 만든했다 : 나는 질문을 떠나 다른 사람이 내 실수 혜택을 누릴 수 있도록 :) 을 누군가가 공유 할 수있는 무엇이든이있는 경우 여기에 답변 해 드리겠습니다

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

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

을 수행하십시오 .