View Full Version : [C, Flex, Bison] Generare interprete PHP
Kaesar83
11-05-2009, 22:11
Ciao raga,
avrei bisogno di una mano.
Mi sto cimentando nella creazione di un interprete PHP per il progetto di un esame.
Ho scaricato Flex e Bison, 2 tool che mi saranno utili per la creazione dell'applicazione.
Innanzitutto ho bisogno della grammatica context-free del linguaggio in esame (il PHP) che ho preso scaricando il pacchetto ufficiale dal www.php.net/downloads.php.
Il file di mio interesse si trova nella cartella Zend e si chiama zend_language_parser.y (questo dovrebbe definire la grammatica context-free, correggetemi se sbaglio).
Dando in pasto a Bison questo file me ne vengono restituiti 2:
zend_language_parser.tab.c
zend_language_parser.tab.h
Una volta fatto ciò ho preso il file zend_language_scanner.l presente sempre nella cartella Zend e l'ho dato in pasto a Flex.
Grazie a quest'ultima operazione mi viene creato il file lex.yy.c
A questo punto compilo i file lex.yy.c e zend_language_parser.tab.c (tramite gcc) in modo da ottenere l'interprete finale, cioè un file .exe (sono su Windows).
Ciò però non avviene visto che mi vengono restituiti un bel pò di errori.
Dove sbaglio!?
Grazie in anticipo
Ciao raga,
avrei bisogno di una mano.
Mi sto cimentando nella creazione di un interprete PHP per il progetto di un esame.
Ho scaricato Flex e Bison, 2 tool che mi saranno utili per la creazione dell'applicazione.
Innanzitutto ho bisogno della grammatica context-free del linguaggio in esame (il PHP) che ho preso scaricando il pacchetto ufficiale dal www.php.net/downloads.php.
Il file di mio interesse si trova nella cartella Zend e si chiama zend_language_parser.y (questo dovrebbe definire la grammatica context-free, correggetemi se sbaglio).
Dando in pasto a Bison questo file me ne vengono restituiti 2:
zend_language_parser.tab.c
zend_language_parser.tab.h
Una volta fatto ciò ho preso il file zend_language_scanner.l presente sempre nella cartella Zend e l'ho dato in pasto a Flex.
Grazie a quest'ultima operazione mi viene creato il file lex.yy.c
A questo punto compilo i file lex.yy.c e zend_language_parser.tab.c (tramite gcc) in modo da ottenere l'interprete finale, cioè un file .exe (sono su Windows).
Ciò però non avviene visto che mi vengono restituiti un bel pò di errori.
Dove sbaglio!?
Grazie in anticipo
il .h è presente? che errori sono?
Kaesar83
11-05-2009, 23:05
Presente dove?
Ecco qui uno screenshot di una parte degli errori
[img=http://img13.imageshack.us/img13/3033/reporterror.th.jpg] (http://img13.imageshack.us/my.php?image=reporterror.jpg)
Kaesar83
12-05-2009, 11:56
up
Vincenzo1968
12-05-2009, 15:02
...
A questo punto compilo i file lex.yy.c e zend_language_parser.tab.c (tramite gcc) in modo da ottenere l'interprete finale, cioè un file .exe (sono su Windows).
Ciò però non avviene visto che mi vengono restituiti un bel pò di errori.
Dove sbaglio!?
Grazie in anticipo
Attenzione,
non è sufficiente compilare i file prodotti da Flex e Bison. Devi fornire al compilatore anche i file che implementano le funzioni utilizzate nelle azioni semantiche(il codice, cioè, utilizzato all'interno delle parentesi graffe).
Per esempio, nella produzione seguente:
assignment_list_element:
variable { zend_do_add_list_element(&$1 TSRMLS_CC); }
| T_LIST '(' { zend_do_new_list_begin(TSRMLS_C); } assignment_list ')' { zend_do_new_list_end(TSRMLS_C); }
| /* empty */ { zend_do_add_list_element(NULL TSRMLS_CC); }
;
devi implementare la funzione zend_do_add_list_element, zend_do_new_list_begin e zend_do_new_list_end.
Puoi utilizzare il file zend_language_parser.y che ti fornisce la grammatica di PHP; ma devi sostituire il codice all'interno delle parentesi graffe con il tuo(creando, per esempio, il nodo dell'AST relativo alla regola di produzione in esame).
;)
P.S. nota che, nella prima sezione del file .y, sono presenti degli include che fanno riferimento alle funzioni e alle costanti utilizzate nelle azioni semantiche(implementate in files a parte):
...
#include "zend_compile.h"
#include "zend.h"
#include "zend_list.h"
#include "zend_globals.h"
#include "zend_API.h"
#include "zend_constants.h"
...
Kaesar83
13-05-2009, 17:47
Puoi utilizzare il file zend_language_parser.y che ti fornisce la grammatica di PHP; ma devi sostituire il codice all'interno delle parentesi graffe con il tuo(creando, per esempio, il nodo dell'AST relativo alla regola di produzione in esame).
Innanzitutto grazie Vincenzo.
Vorrei meglio comprendere questa frase, se potessi farmi un esempio semplice.
Altra cosa, ho notato che un sacco di librerie richiamate dai vari file non vengono trovate all'atto della compilazione, come posso fare a togliermi questa rogna invece di andarmi a trovare ciascuna libreria!?
Vincenzo1968
13-05-2009, 18:04
Scaricati questo pdf:
http://epaperpress.com/lexandyacc/index.html
È un ottimo tutorial su Flex/Bison. L'esempio "Calculator", a pag. 20, implementa un parser per un piccolo linguaggio di programmazione.
Per esempio, è possibile effettuare il parsing di programmini del tipo:
x = 0;
while (x < 3)
{
print x;
x = x + 1;
}
Il parser dell'esempio costruisce un AST. Successivamente, attraversando l'AST, è possibile scegliere se interpretare il programma o compilarlo generando il relativo codice macchina(per una ipotetica stack-based machine ;)).
Per gli errori di inclusione, non saprei: non utilizzo gcc ma visual studio. :boh:
Kaesar83
15-05-2009, 11:53
Salve ragazzi,
dopo qualche giorno di lavoro rieccomi qui. :D
Innanzitutto credo di essere arrivato ad un ottimo punto, son passato su Linux e son riuscito a far compilare il tutto, modificando un bel pò i file .y e .l, eliminando tutte le funzioni "inutili".
Se passo un file php semplice, con un solo echo o un if tra 2 espressioni la cosa va a buon fine.
Se invece provo ad interpretare un if del tipo if($x == 0) echo "ciao";l'interprete mi restituisce un errore perchè non riconosce questo tipo di sintassi.
Vedendo per bene il file .y mi sono accorto che il tutto dovrebbe dipendere da questo
expr_without_variable:
PHP_LIST '(' assignment_list ')' '=' expr
| assignment_variable_pointer '=' expr
| assignment_variable_pointer PLUS_EQUAL expr
| assignment_variable_pointer MINUS_EQUAL expr
| assignment_variable_pointer MUL_EQUAL expr
| assignment_variable_pointer DIV_EQUAL expr
| assignment_variable_pointer CONCAT_EQUAL expr
| assignment_variable_pointer MOD_EQUAL expr
| assignment_variable_pointer AND_EQUAL expr
| assignment_variable_pointer OR_EQUAL expr
| assignment_variable_pointer XOR_EQUAL expr
| assignment_variable_pointer INCREMENT
| INCREMENT assignment_variable_pointer
| assignment_variable_pointer DECREMENT
| DECREMENT assignment_variable_pointer
| expr BOOLEAN_OR expr
| expr BOOLEAN_AND expr
| expr LOGICAL_OR expr
| expr LOGICAL_AND expr
| expr '|' expr
| expr '^' expr
| expr '&' expr
| expr '.' expr
| expr '+' expr
| expr '-' expr
| expr '*' expr
| expr '/' expr
| expr '%' expr
| '+' expr
| '-' expr
| '!' expr
| '~' expr
| expr IS_EQUAL expr
| expr IS_NOT_EQUAL expr
| expr '<' expr
| expr IS_SMALLER_OR_EQUAL expr
| expr '>' expr
| expr IS_GREATER_OR_EQUAL expr
| '(' expr ')'
| '(' expr error
| expr '?'
expr ':'
expr
| var
'(' function_call_parameter_list ')'
possible_function_call
| internal_functions_in_yacc
| '$' unambiguous_class_name PHP_CLASS_OPERATOR var
'(' function_call_parameter_list ')'
possible_function_call
| NEW STRING
| INT_CAST expr
| DOUBLE_CAST expr
| STRING_CAST expr
| EXIT
| EXIT '(' ')'
| EXIT '(' expr ')'
| '@' expr
| scalar
| PHP_ARRAY '(' array_pair_list ')'
| '`' encaps_list '`'
| PHP_LINE
| PHP_FILE
;
expr:
assignment_variable_pointer
| expr_without_variable
;
Io dovrei creare quindi una sorta di expr_with_variabile, idee su come posso fare?
Grazie in anticipo.
Kaesar83
16-05-2009, 00:37
Da una serie di test son riuscito a capire che non riesce a leggermi le variabili in PHP, cioè qualsiasi stringa con il dollaro davanti.
Qualcuno riesce a darmi una mano?
Kaesar83
19-05-2009, 13:53
up
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.