2012-04-10 16 views
5

İşlev çağrılarını desteklemek için oluşturduğum basit bir dilbilgisiyle sorun yaşıyorum.
Greg tarafından limon tabanlı PHP_ParserGenerator kullanıyorum.Limon dilbilgisi ile ilgili sorunlar (önceliği?)

Bu gramer ilgili bölümü: Ben array('user' => array('name' => 'Dennis')); bir çerçevesi ile ayrıştırıcı başlatmak ve aşağıdaki kodu çalıştırdığınızda

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

şöyledir:

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

$result gibidir: ' Dennis'in. Hayat güzel.

Ama bir işlev çağrısına argüman olarak bir CONTEXT_REFERENCE arz zaman, çalışmaz: $result 'us3r.nam3' dir

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

. Beklendiği gibi değil. Kayıt için beklenen çıktı elbette 'D3nnis'. (Kullanıcı adı ilk, "Dennis" dizesiyle değiştirilir ve bundan sonra str_replace() işlevine iletilir).

Önceliği olan bir şey olduğundan şüpheleniyorum. Ama bunu yapmak için ne değiştirmem gerektiğini anlayamıyorum. Çok seyrek limon dökümantasyonu çok büyük bir yardım değil.

Herhangi bir yardım çok takdir edilecektir! Teşekkürler

cevap

1

Sorunun cevabını bulmuş gibi görünüyor. Ben benim dilbilgisi değiştirdiğinizde

:

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

O beklendiği gibi çalışıyor gibi görünüyor.
sorun ilk gramer bir belirsizlik yarattı olmasıydı: Soruyu ayrılıp diğerleri hatalarımı yarar olabilir böylece :) birileri paylaşmak için bir şey varsa burada cevap olacak

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

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

, lütfen .