2010-01-11 7 views
1

J'essaye de créer un analyseur pour un langage simple avec le lemon port to PHP, et cela fonctionne, presque.PHP_ParserGenerator - bug dans la grammaire ou dans le générateur d'analyseur?

La grammaire suivante:

%name SP_ 
%declare_class { class SpecParser } 
%token_prefix SP_ 
%include_class { 
public $retvalue = '<todo: error handling>'; 
public function singleKey($elem) { 
    end($elem); 
    return key($elem); 
} 
} 
%parse_accept { 
$this->retvalue = $this->_retvalue; 
} 

%right ASSIGN. 

start(A) ::= spec(B) . { A = B; } 

spec(A) ::= top_stmt(B) . { A = B; } 

top_stmt(A) ::= . { A=array('empty' => NULL); } 
top_stmt(A) ::= conditional(B) . { A = B;} 
top_stmt(A) ::= retval(B) . { A = B; } 
top_stmt(A) ::= assignment(B) . { A = array('assignment' => B); } 
top_stmt(A) ::= MOD STRING(B) top_stmt(C) . {C['rulename'] = B; A=B;} 

conditional(A) ::= IF stmt_list(B) . { A = array('condbreak' => array('stmt_list' => B)); } 
conditional(A) ::= IF stmt_list(B) stmt(C) . { A = array('condexec' => array('cond' => B,'exec' => C)); } 

retval(A) ::= access(B) . { A = array('access' => B); } 
retval(A) ::= invoke(B) . { A = array('invoke' => B); } 

assignment(A) ::= access(B) ASSIGN expr(C) . {A = array('lval' => B, 'rval' => C);} 

expr(A) ::= retval(B) . { A = array('retval' => B); } 
expr(A) ::= NOT retval(B) . { A = array('!retval' => B); } 

stmt(A) ::= expr(B) . { A = array('expr' => B); } 
stmt(A) ::= assignment(B) . { A = array('assignment' => B); } 

empty_stmt_list(A) ::= . {A = array();} 
empty_stmt_list(A) ::= stmt(B) . { 
    A = array(B); 
} 
empty_stmt_list(A) ::= empty_stmt_list(B) COMMA stmt(C) . { 
    B[] = C; 
    A = B; 
} 

stmt_list(A) ::= stmt_list(B) COMMA stmt(C) . {B[] = C; A=B; } 
stmt_list(A) ::= stmt(B) . { A = array(B); } 

invoke(A) ::= access(B) LPAREN empty_stmt_list(C) RPAREN . { A = array('target' => B,'args' => C); } 

access(A) ::= VARIABLE(B) . { A = array('variable' => B); } 

devrait analyser les entrées comme:

  1. « si cond1 $, cond2 de $, cond3 de $() $ var = $ this ($ a(), $ inst1 = $ b()) »
  2. '$ var'
  3. '% rulename $ var'

Alors que les entrées comme 1 et 2 fonctionnent comme prévu, d'une manière ou d'une autre, pas compréhensible pour moi comment, l'entrée 3 renvoie string (8) "rulename". Je n'ai aucune idée des réductions qui devraient avoir lieu pour que cela se produise. Est-ce quelque chose qui ne va pas avec la grammaire, ou dois-je commencer à débugger PHP_ParserGenerator lui-même?

Merci

Répondre

1

Je dois être très fatigué. L'erreur est la mauvaise affectation:

top_stmt(A) ::= MOD STRING(B) top_stmt(C) . {C['rulename'] = B; A=B;} 

qui aurait dû être:

top_stmt(A) ::= MOD STRING(B) top_stmt(C) . {C['rulename'] = B; A=C;}