Newsgroup: it.comp.lang.c
Titolo: Aiuto generale sulla creazione di un linguaggio di programmazione

Ciao a tutti,
posto su questo gruppo per la prima volta per chiedervi una cosa
abbastanza importante: stò cercando di sviluppare, da qualche
settimana, un linguaggio di programmazione. Lo faccio solo per scopo
didattico, per divertimento.
Non ho molta conoscenza teorica per quanto riguarda il design di
compilatori ed interpreti, quindi volevo chiedervi un po di cose.
Il mio fine è di sviluppare un linguaggio procedurale molto semplice
con una sintassi C-like, interpretato. Se ho ben capito il
procedimento da seguire per "eseguire il mio file" dovrebbe essere il
seguente:
1. Controllare con uno scanner la sintassi;
2. Eseguire il parsing del file;
3. Raggruppare in una struttura ad albero il contenuto del file, così
da facilitarne la traduzione ed il controllo;
4. Generare dall'albero ottenuto un bytecode;
5. Usare un programma per eseguire il bytecode line-by-line;
Lo scanner, il parser e la struttura ad albero sono già state
implementate. Per i primi due non ho usato strumenti come lex o yacc
(visto che non ne conoscevo l'esistenza!). Il problema principale nel
quale incorro è il seguente:
mi conviene generare linguaggio macchina (assembly x86) da compilare
per creare eseguibili senza pensare a fare un linguaggio interpretato,
mi conviene creare un "bytecode personalizzato" da eseguire con un
programma, o fare un lavoro tipo quello di Java (creando un linguaggio
"personale" simile all'assembler che venga interpretato da programmi
sviluppati appositamente per ogni macchina)???
Premetto che, anche se suona strano, la via più facile mi sembra la
terza, anche se vorrei evitarla. Preferirei di gran lunga sviluppare
del bytecode portabile. Ma il problema principale è che non so come
sia strutturato un bytecode (come vengono gestiti i cicli, le funzioni
ecc...) e non so dove trovare documentazione in proposito.
Vorrei che qualcuno mi aiutasse con un po di teoria nello sviluppo del
mio progetto, visto che ho bisogno di una mano. premetto che non ho
intenzione di sviluppare un tool iperveloce,e superfunzionale, mi
interessa solamente che funzioni a dovere.
Se potete aiutarmi non posso che ringraziarvi.
ciao

Già che si sono aggiungo una richiesta: ho saputo che è disponibile la
versione in italiano del dragon book (Compilers: principles, tecniques and
tools). Sotto quale titolo??Che casa editrice??
grazi, ciao

 sviluppati appositamente per ogni macchina)???
La distinzione che fai tu tra "bytecode personalizzato" e il metodo
utilizzato
da java in realta' non esiste, i programmi java sono file contenenti il
bytecode
del programma il quale viene poi interpretato dalla java virtual machine.
Inoltre con questo meccanismo hai gia' la massima portabilita' possibile, in
quanto
lo stesso bytecode potra' girare su qualsiasi tipo di macchina in cui sia
installata
la java virtual machine (che sara' differente a seconda dell'architettura
della macchina)
La java virtual machine non e' altro che l'interprete che legge i vari
bytecode e
trasforma il tutto in chiamate verso il sistema operativo.
Detto cio' le scelte si riducono a 2...
1) generare linguaggio assembly
2) generere un bytecode personalizzato ed un opportuno interprete per ogni
architettura
 sulla quale si vuole far girare i tuoi programmi.
Dipende da cosa vuoi ottenere... se vuoi la velocita' indubbiamente
orientati verso la prima
delle soluzioni, se invece quello che cerchi e' la portabilita' passa alla
seconda.
Ciau Il.Socio

 seconda.
penso che seguirň la via del bytecode...com'č strutturato un bytecode??Cioč:
quando incontro delle dichiarazioni, funzioni, ecc... come mi muovo per
formare il bytecode necessario??Sono righe di macroassembler da interpretare
successivamente??

   far girare i tuoi programmi.
Secondo me e' stata omessa una terza possibilita' che
e' anche quella di implementazione piu' semplice: l'idea
e' quella di interpretare direttamente la struttura
ad albero risultato del parsing senza passare alla
generazione di codice "flat".
Ovviamente come soluzione ha delle controindicazioni
abbastanza fastidiose ma la semplificazione e' notevole
e credo che per chi inizia sia una strada che conviene
sperimentare. Inoltre non e' una strada a fondo chiuso,
e permette comunque di arrivare ad avere prodotti "finiti"
in grado di lavorare degnamente... ci sono pero' cose
che risultano decisamente piu' complicate da realizzare
in assenza di un codice flat da eseguire (es. il debugger).
HTH
Andrea

Non ho capito ancora se c'è qualcuno disposto a darmi una mano ogni
tanto...comunque andiamo con ordine:
parser ok
scanner ok
albero sintattico: ho visto che come l'ho scritto non va bene...voi come lo
organizzereste (per permettere di memorizzare funzioni, procedure, array,
ecc...in modo che siano riutilizzabili nella creazione del bytecode)??
il linguaggio è interpretato da C.
spero in una mano ;)
ciao

spero in una mano ;)
Io ho un po' di esperienza nella realizzazione di
interpreti/compilatori/vm. Non riesco pero' a
comprendere quali sono i problemi che incontri...
non riesci ad essere piu' specifico ?
Andrea

Ti allego un'e-mail che ho mandato tempo addietro
"""
volevo chiederti un paio di cose: ho avuto poco tempo per pensare a come
implementare il mio linguaggio PP, ed ancora meno per legger manuali di
vario tipo (ho letto Compilers & Compilers generator, ma mi ha messo più
casino in testa che altro).
Volevo chiederti il modo in cui mi converrebbe procedere per sviluppare il
mio linguaggio interpretato.
L'obiettivo è quello di fare un linguaggio intepretato che creasse bytecode
portabile; ho già preparato la BNF con la sintassi.
io pensavo di proceder così:
1. Preparare l'albero sintattico, visto che ho letto che è conveniente
inserire in un albero il contenuto dello script prima di tradurlo. Qui sorge
un problema: degli alberi sintattici che ho visto sul manuale, non si
capisce molto, perchè sono implementati in modo "sporco". Come
funziona un albero sintattico??Lavora su una struttura a cui aggiunge nodi
ecc...??In che modo??Come potrei strutturarlo??
2. Preparare un analizzatore sintattico (penso di usare flex): l'ho già
fatto e non ho incontrato grossi problemi...ho visto che tu hai
memomorizzato anche la locazione dei token, processo che, a quanto ho letto,
rallenta le operazioni di parsing. Come mai??Ti serve per il debug?
3. Preparare il parser (penso di usare Bison): di questo non mi sono ancora
occupato molto visto che è inutile un parser senza che ci sia sotto un
albero sintattico in cui salvare i token.
4. Poi come dovrei continuare??
"""
come vedi mi manca molto, ma avevo bisogno solo di un aiuto per Avere (per
ora) una risposta alle domande che ho posto.
ciao
P.s: è giusto partire con la stesura dell'albero sintattico??

Premetto che ho l'impressione che l'informatica sia considerata
l'unica delle attivita' umane in cui e' possibile fare cose
mirabilanti senza sprecare tempo  in ore e ore di studio rigoroso.
Mah!
La costruzione di un compilatore (o interprete) e' un task complesso.
I tuoi dubbi su come proseguire probabilmente sono dovuti al non avere
ancora ben chiaro cosa fare. In altre parole : il tuo linguaggio cosa
prevede ?
a) quanti e quali tipi di dati ?
b) vuole gestire gli array?  la dimensioni degli array e' nota a
compile time o puo' essere variata run-time?
c) gestisce le stringhe? se si, a dimensione fissa o variabile ?
d) gestisce i puntatori?
e) prevede le funzioni? se si, con quale paradigma di chiamata ?
f) prevede un precompilatore ? se si, con quale sintassi ?
g) qual'e' il modello computazionale sottostante ? una macchina di Von
Neumann classica? il modello a stack e heap del C ? La Java VM ? Un
interprete ad hoc? Una macchina di Turing? Il P-Code ?
h) puo' gestire il parallelismo, il multitasking ?
i) prevede un object model per la programmazione OO ?
j) quali sono gli operatori fondamentali ?
k) prevede overloading degli operatori ?
l) le espressioni sono in notazione polacca inversa o in forma infissa
?
m) quali sono le istruzioni di branch? e i loop? e la case ?
n) le funzioni possono ritornare valori? se si, uno solo o molti ?
o) gli argomenti vengono passati per valore o riferimento ?
p) le liste vengono gestite nativamente ?
q) sono previsti  tipi di dati aggregati , tipo record  o struct ?
r) il tipo record e' a lunghezza variabile ?
s) con quale standard vengono gestiti i numeri in virgola mobile? 
t) la sintassi dell'eventuale bytecode ?
u) sono previste 'scope' gerarchiche per i nomi delle variabili ?
v) e' prevista allocazione dinamica ?
Da queste scelte e da molte altre dipende l'algoritmo di processing
del parse-tree. (concordo con un post precedente in cui si diceva che
all'inizio lal cosa migliore e' interpretare direttamente il
parse-tree).
spero di esserti stato d'aiuto
Ciao
Luca