PDA

View Full Version : [SPIKE] Parser per un semplice linguaggio


fek
19-11-2005, 18:34
Mi serve uno spike per esplorare diverse soluzioni del seguente problema:

Scrivere un parser per un semplice linguaggio che accetti comandi del tipo:

play sound XXX
play animation YYY
wait 10 seconds
draw XXXX at (X, Y)

Molto probabilmente non serviranno loop o branch complicati.

Vorrei analizzare le seguenti possibilita':

- scrivere il parser a mano
- usare librerie di parsing gia' fatte (ANTLR e' il piu' promettente: http://www.antlr.org/)
- usare un linguaggio tipo Jython, o integrare LUA o Ruby

Chi si offre volontario?

71104
20-11-2005, 00:44
IO!!! O.o'
mi piace un sacco l'argomento del parsing, è logica pura, ferrea e brainfucking!! :D
se mi spieghi di preciso la sintassi vorrei provare io scrivendo il parser a mano :)

DanieleC88
20-11-2005, 08:39
Anche a me piace l'idea, ma mi chiedevo: scriverlo in Python o Ruby a cosa servirebbe? In fondo andrebbe integrato con un progetto scritto in Java! (perdonate la niubbagine :D)
E, infine, mi chiedevo: si potrebbe provare a scriverlo in C++, in modo da utilizzare un linguaggio con una sintassi che si avvicina leggermente a Java?
Spero di non aver sparato solo ca**ate. :D

ciao ;)

fek
20-11-2005, 10:21
IO!!! O.o'
mi piace un sacco l'argomento del parsing, è logica pura, ferrea e brainfucking!! :D
se mi spieghi di preciso la sintassi vorrei provare io scrivendo il parser a mano :)

Abbiamo un volontario.
La sintassi del linguaggio te la inventi, quelli sono degli esempi. Ovviamente Jocchan ti dara' molte dritte su quello che potrebbe servrigli in futuro. E' uno spike e non un task perche' ancora non abbiamo un'idea precisa di cio' di cui abbiamo bisogno e di una possibile soluzione.

Valuta molto seriamente ANTLR perche' sono gia' disponibili i task per Ant per automatizzare la creazione dello scanner e del parser a partire dalla grammatica direttamente dal nostro build script.

Divertiti :)

fek
20-11-2005, 10:25
Anche a me piace l'idea, ma mi chiedevo: scriverlo in Python o Ruby a cosa servirebbe? In fondo andrebbe integrato con un progetto scritto in Java! (perdonate la niubbagine :D)
E, infine, mi chiedevo: si potrebbe provare a scriverlo in C++, in modo da utilizzare un linguaggio con una sintassi che si avvicina leggermente a Java?
Spero di non aver sparato solo ca**ate. :D

ciao ;)

L'idea di un linguaggio di scripting per un gioco come il nostro e' l'essere SEMPLICE tanto da non richiedere alcuna nozione di programmazione per essere usato. Non e' proprio il caso di C++ :D

Python e Ruby potrebbero essere soluzioni interessanti. Ad esempio in Fable hanno deciso di usare LUA per lo scripting e per tutto il game code; e' una soluzione interessantissima, ma credo che non si adatti ad un progetto semplice come il nostro. Ed inoltre Python e Ruby potrebbero essere troppo complessi per chi e' a totale digiuno di programmazione.

Ti vuoi occupare tu di vedere quanto sarebbe complessa una tale integrazione?

71104
20-11-2005, 10:49
Valuta molto seriamente ANTLR perche' sono gia' disponibili i task per Ant per automatizzare la creazione dello scanner e del parser a partire dalla grammatica direttamente dal nostro build script. hum, e allora su cosa mi butto per primo? parser fatto a manina o questo ANTLR?

fek
20-11-2005, 11:04
hum, e allora su cosa mi butto per primo? parser fatto a manina o questo ANTLR?

Libera scelta tua. Personalmente inizierei da Antlr, ma vorrei esplorare entrambe le possibilita'. Sceglieremo quella che ci fa risparmiare piu' tempo.

DanieleC88
20-11-2005, 11:57
L'idea di un linguaggio di scripting per un gioco come il nostro e' l'essere SEMPLICE tanto da non richiedere alcuna nozione di programmazione per essere usato. Non e' proprio il caso di C++ :D
*ahem* :D
Ritiro tutto. XD

^TiGeRShArK^
20-11-2005, 18:51
:D
questo mi sa che assomiglia un pò al linguaggio di scripting utilizzato da ron jeffries per i customer test :D
o sbaglio? ;)

VICIUS
20-11-2005, 20:31
Interessante. Non vedo l'ora di avere tra le mani qualche spike da guardare. Dite che ce la facciamo ad avere qualcosa con ruby?

ciao ;)

Jocchan
20-11-2005, 20:45
Interessante. Non vedo l'ora di avere tra le mani qualche spike da guardare. Dite che ce la facciamo ad avere qualcosa con ruby?

ciao ;)

Ruby, anche se consente una libertà totale, probabilmente potrebbe essere troppo complesso per l'uso che faremo di questo linguaggio di scripting.
Forse la cosa migliore è qualcosa di "fatto a mano" o, come ha scritto prima Fek, usare Antlr (che è integrato con Ant).

VICIUS
20-11-2005, 20:52
Ruby, anche se consente una libertà totale, probabilmente potrebbe essere troppo complesso per l'uso che faremo di questo linguaggio di scripting.
Forse la cosa migliore è qualcosa di "fatto a mano" o, come ha scritto prima Fek, usare Antlr (che è integrato con Ant).
Ma è cosi carino!!! :D
Uff. Vabbe vediamo che cosa combina 71104.

ciao ;)

^TiGeRShArK^
20-11-2005, 21:57
il linguaggio usato da ron jeffries era ESTREMAMENTE semplice...
in pratica lo usava per testare un editor xml....
il customer scriveva in un file di testo il testo normale...
e in + aggiungeva i comandi da eseguire...
ad esempio...
*newline
e cose del genere..
in + la posizione attuale del cursore veniva identificata da | che veniva correttamente riconosciuto dal parser....
così facendo il customer poteva testare il tutto senza avere la minima conoscenza di programmazione! :D

Jocchan
20-11-2005, 22:17
il linguaggio usato da ron jeffries era ESTREMAMENTE semplice...
in pratica lo usava per testare un editor xml....
il customer scriveva in un file di testo il testo normale...
e in + aggiungeva i comandi da eseguire...
ad esempio...
*newline
e cose del genere..
in + la posizione attuale del cursore veniva identificata da | che veniva correttamente riconosciuto dal parser....
così facendo il customer poteva testare il tutto senza avere la minima conoscenza di programmazione! :D

Bingo! ^_^
Il nostro linguaggio di scripting deve anche consentire di creare, ad esempio, delle cutscene tra uno stage e l'altro dello story mode, più molto altro (creare situazioni di gioco complesse per i vari test, e - perchè no? - anche di cambiare qualche regola del gioco per aggiungere facilmente nuove modalità).
Deve essere, insomma, flessibile, ma non troppo complesso, ed utilizzabile anche da chi ha conoscenze blande di programmazione... un'utopia? Credo proprio di no ;)

cdimauro
21-11-2005, 08:58
Ho dato un'occhiata ad ANTLR ed è MOLTO promettente (una figata per chi sviluppa linguaggi :D).

Non so di preciso quali sono gli obiettivi di questo linguaggio di script (Jocchan, sei stato troppo generico. :D), quindi quali sono tutte le tipologie di istruzioni che dovranno essere presenti / supportate, ma penso che un criterio per decidere quale strumento utilizzare si possa abbozzare dalle seguenti questioni:

1) abbiamo bisogno di definire funzioni / subroutine e/o variabili tipizzate e/o espressioni con operatori (o altro)?
2) gli script saranno costituiti tutti da comandi del tipo "Variabile = valore" oppure "Comando [parametro1, parametro2, ..., parametro n]"?

Nel primo caso opterei per ANTLR (o qualche altro generatore di parser "classico", YACC-like).
Nel secondo caso sarebbe sufficiente scrivere un parserino semplice semplice in Java stesso.

Ovviamente la prima soluzione richiede (molto) più tempo della seconda. ;)

P.S. Finalmente m'è tornato il router e sono disponibile la sera o la mattina presto per lavorare a Diamonds. Peccato sia arrivato tardi in questo caso... :cry:

fek
21-11-2005, 09:02
1) abbiamo bisogno di definire funzioni / subroutine e/o variabili tipizzate e/o espressioni con operatori (o altro)?
2) gli script saranno costituiti tutti da comandi del tipo "Variabile = valore" oppure "Comando [parametro1, parametro2, ..., parametro n]"?


1) Assolutamente no
2) Ce lo deve dire Jocchan, io propenderei per un linguaggio molto simile all'inglese.


P.S. Finalmente m'è tornato il router e sono disponibile la sera o la mattina presto per lavorare a Diamonds. Peccato sia arrivato tardi in questo caso... :cry:

Bene, abbiamo un volontario per Jython :D

Jocchan
21-11-2005, 09:22
Anche io propenderei per un linguaggio semplice e simile all'inglese, magari con la possibilità di svilupparlo man mano che andiamo avanti.
Insomma, se volessimo iniziare dalla parte dedicata alle cutscene, potremmo partire dall'introduzione di comandi come:

- wait (xx) <--- inutile spiegarlo
- show bg (personaggio) <--- mostra lo sfondo del personaggio dato
- dialogue (nomepersonaggio) (testo) <--- mostra una finestra con dei dialoghi in basso ed una gif "nomepersonaggio.gif" per l'intestazione della finestra
- show character (codice) (nomepersonaggio) (xx, yy) <--- mostra un pg alle coordinate date dandogli un codice identificativo
- move character (codice) (coord.destinazione) (velocità) <--- semplice traslazione fino alle coordinate date, con velocità settabile
- anim character (codice) (xx) <--- mostra l'animazione xx per il personaggio specificato
- delete character (codice) <--- elimina il pg
- show picture (codice) (xx, yy) (trasparenza%) (dimensioni) <--- idem, ma per una png statica con una % variabile di trasparenza
- move picture (codice) (coord.destinazione) (velocità) (trasparenza%) (dimensioni) <--- per spostare e trasformare la png in questione
- delete picture (codice) <--- elimina la png
- show text (coordinate) (font) (testo) <--- mostra del testo generico, con font variabile, allineato a sinistra e partendo dalle coordinate date
- flash screen (colore) (durata) <--- non credo ci sia bisogno di spiegarlo
- shake screen (potenza) (durata) <--- idem ;)

Già con questi comandi, da implementare poco alla volta, si potrebbero creare praticamente TUTTE le cutscene del gioco :D
Per i comandi relativi al gioco vero e proprio devo valutare bene cosa serve, magari con un pò di consulenza tecnica :p


Vabbè le cutscene potremmo anche girarle con l'engine di The Movies... :Prrr:

VICIUS
21-11-2005, 11:32
Interessante finalmente qualcosa su cui lavorare un po' mentre gli altri stanno smanettando con i Task :D
Se non ho niente da fare qusto pomeriggio vedo di tirare fuori qualcosa di funzionate.

ciao ;)

cdimauro
21-11-2005, 11:59
Ma questo "task" non se l'era accalappiato 71104? ;)

Comunque proporrei una sintassi senza parentesi per gli eventuali argomenti dei comandi. Del tipo:

Show Character 'Luke Skywalker', 320, 240

Simpler is better :D

VICIUS
21-11-2005, 12:18
Ma questo "task" non se l'era accalappiato 71104? ;)
Me ne ero scordato. Sara per la prossima volta. :muro:

Comunque proporrei una sintassi senza parentesi per gli eventuali argomenti dei comandi. Del tipo:

Show Character 'Luke Skywalker', 320, 240

Simpler is better :D
Visto che ci siamo evitiamo anche le ",". Ci sono gia gli spazi a fare da separatori. Poi per le stringhe proporrei di usare " invece di '. Cosi evitiamo di dover pensare a sequenze di escape se ci serve l'appostrofo.

ciao ;)

Jocchan
21-11-2005, 12:29
Ottimo, io le parentesi le ho messe solo per chiarezza, se è possibile evitare tanto meglio ;)

fek
21-11-2005, 12:45
Non eccitatevi troppo, non e' un task questo, e' uno Spike :)

Se 71104 vuole provare a usare ant, Vicius puo' provare a scriverlo a mano e Cesare puo' dare un'occhiata a Jython o Ruby.
Niente di cio' che scrivete deve finire nella code base.

VICIUS
21-11-2005, 13:57
Non eccitatevi troppo, non e' un task questo, e' uno Spike :)

Se 71104 vuole provare a usare ant, Vicius puo' provare a scriverlo a mano e Cesare puo' dare un'occhiata a Jython o Ruby.
Niente di cio' che scrivete deve finire nella code base.
Nha per ora aspetto di vedere cosa combinano gli altri. Anche perchè come sospettavano mi hanno incastrato con il lavoro :(

ciao ;)

cdimauro
22-11-2005, 09:48
Potrei scegliere di portare avanti il parserino "scritto a mano"? Per quello che ci serve, francamente lo trovo una soluzione migliore rispetto alla sperimentazione di jython, ruby o altro.
Poi VICIUS fortunatamente è impegnato col lavoro... :fiufiu: :D

VICIUS
22-11-2005, 10:37
Poi VICIUS fortunatamente è impegnato col lavoro... :fiufiu: :D
:angel:

Jocchan
22-11-2005, 12:29
Potrei scegliere di portare avanti il parserino "scritto a mano"? Per quello che ci serve, francamente lo trovo una soluzione migliore rispetto alla sperimentazione di jython, ruby o altro.
Poi VICIUS fortunatamente è impegnato col lavoro... :fiufiu: :D

Io sono d'accordo, credo sia la cosa migliore da fare.

fek
22-11-2005, 13:58
Va bene scartare l'opzione Ruby/Python.

Vorrei comunque entrambi gli spike sul parser scritto a mano e sull'uso di Antlr. Alla lunga un parser solo manuale potrebbe essere troppo costoso da gestire, abbiamo bisogno di un piano B.

cdimauro
23-11-2005, 09:39
Certamente. L'uno non esclude l'altro. ;)

71104
24-11-2005, 12:05
come detto nel thread della Storia 2 (che adesso dovrebbe essere conclusa) purtroppo nei giorni passati non ho badato per nulla a Diamonds :sob:
ora dovrei essere più presente e vedrò di fare qualche esperimento con questo parser; per ora da quanto ho capito la sintassi è definita più o meno così:

le parti incluse tra parentesi quadre sono opzionali

sintassi del file:
[comando1]
[comando2]
[comando3]
...

sintassi di un comando:
[separatori] nome [separatori] ( [parametro1] [, parametro2] [, ...] ) [newline]

separatori: qualsiasi sequenza contigua di spazi e tabulazioni

nome: sequenza di almeno 1 caratteri alfanumerici e underscores; non deve iniziare con un numero.

sintassi di un parametro: boh...?

newlines: qualsiasi sequenza contigua di \n e \r

che ne dite? i newlines al termine di ogni comando sono obbligatori? se il parser incontra un errore di sintassi deve anche distinguere tra i diversi tipi di errore oppure resttuisce l'errore, il numero di linea e basta? e questi parametri di che tipo saranno? solamente numeri? solo interi o anche con la virgola (cioè col punto :p)?

71104
24-11-2005, 12:17
versione aggiornata:

le parti incluse tra parentesi quadre sono opzionali

sintassi del file:
[comando1]
[comando2]
[comando3]
...

sintassi di un comando:
[separatori] nome [separatori] ( [parametro1] [, parametro2] [, ...] ) [newline]

separatori: qualsiasi sequenza contigua di spazi e tabulazioni

nome: sequenza di almeno 1 caratteri alfanumerici e underscores; non deve iniziare con un numero.

sintassi di un parametro:
numero oppure stringa

numero: qualsiasi sequenza contigua (di almeno 1 carattere) di cifre numeriche da 0 a 9; la sequenza può eventualmente contenere un solo punto ("."), volendo anche all'inizio o alla fine: nel primo caso il numero è interpretato come 0.1234..., nel secondo come ...1234.000

stringa: qualsiasi sequenza di caratteri circondati da virgolette doppie ("); per inserire caratteri speciali si usa il backslash con una delle seguenti combinazioni:
- \" <-- virgolette doppie
- \n <-- line feed
- \r <-- carriage return
- \t <-- tabulazione
- \x <-- x = qualsiasi numero intero da 0 a 255; serve ad includere un carattere ASCII arbitrario
- \xXXX <-- XXX = qualsiasi numero esadecimale da 0 a FF; stessa funzionalità della precedente
- altri...

newlines: qualsiasi sequenza contigua di \n e \r

i parametri oltre che numeri interi o con la virgola possono essere anche stringhe. siamo sicuri che non vogliamo metterci l'uso di variabili?

VICIUS
24-11-2005, 17:55
Dunque queste sono un po di idee sparse.
1. Secondo me puoi risparmiarti il parsing di "(", ")" per racchiudere la lista dei parametri e del "," per separarli. basta usare [separatore] anche per questo.
2. Per ora di sequenze di escape come \n \t o \r non ci servono quindi puoi anche non implementarle. Molto probabilmente il testo sara composta da piccoli dialoghi quindi non ci sara bisogno di formattarlo.
3. Io aggiungerei anche \n a [separatore]. In questo modo se il comando diventa lungo si puo andare a capo. Per terminare il comando poi usi un ";".

ciao ;)

cdimauro
25-11-2005, 11:18
D'accordo sullo spazio come separatore e sulla non inclusione dei caratteri di escape (per adesso non servono: semmai dovessero servire, li implementeremo. Extreme Programming rulez :D).

Non sono d'accordo invece sull'uso del ";" come terminatore di comando: nei linguaggi di scripting più semplici in genere si usa il ritorno a capo. Il testo viene più "naturale" da leggere (e scrivere). Per chi non è abituato a programmare scrivere uno script dovrebbe equivalere alla scrittura della lista della spese / cose da fare, IMHO. ;)

Eventualmente potremmo utilizzare un "\" per "legare" due righe, ossia proseguendo il parsing del comando attuale sulla riga successiva (ed eventuali altre righe, a catena, per quelli particolarmente lunghi).

Per quanto mi riguarda sto cercando di sviluppare il parser in TDD, quindi prima pensando a tutti i test necessari e poi "tirando fuori" classi e/o metodi. E' una cosa che mi richiede più tempo (non sono ancora abituato a "pensare" e sviluppare in TDD, mi spiace). Se per gli spike serve finirli nel più breve tempo possibile, mi metto subito davanti alla tastiera. :p

Jocchan
25-11-2005, 12:37
Concordo con Vicius e Cdimauro, ma un ";" al termine di ogni comando non è che sia una cosa molto gravosa da aggiungere, quindi potrebbe andare ugualmente bene ;)

fek
25-11-2005, 12:48
Concordo con Vicius e Cdimauro, ma un ";" al termine di ogni comando non è che sia una cosa molto gravosa da aggiungere, quindi potrebbe andare ugualmente bene ;)

Se riusciamo a farne a meno pero' e' meglio. Niente variabili, la metafora della lista della spesa e' azzeccata.

fek
25-11-2005, 12:51
Per quanto mi riguarda sto cercando di sviluppare il parser in TDD, quindi prima pensando a tutti i test necessari e poi "tirando fuori" classi e/o metodi. E' una cosa che mi richiede più tempo (non sono ancora abituato a "pensare" e sviluppare in TDD, mi spiace). Se per gli spike serve finirli nel più breve tempo possibile, mi metto subito davanti alla tastiera. :p

Per gli spike non e' strettamente necessario sviluppare in TDD, perche' sono codice usa e getta (e si', lo si getta a prescindere da quello che ci si scrive, fosse anche la cosa piu' bella del mondo :)).

Pero' se vuoi imparare a fare TDD e' un'ottima occasione per allenarsi. Un consiglio, non ti serve scrivere prima tutti i test possibili e immaginabili, butta giu' un elenco di test iniziali su carta e man mano che te ne vengono in mente ne aggiungi, man mano che li implementi li cancelli, se un test non serve piu' lo cancelli.

Esempio banale di una test list per un parser:

- Riconosci una riga
- Riconosci i separatori di token
- Riconosci il primo token di una riga
- etc etc

E cosi' via. Ho tirato a caso per rendere l'idea.

71104
25-11-2005, 13:42
ragazzi, secondo me ha ragione fek sul punto e virgola (e io pensandola come lui non ce l'ho messo apposta fin dall'inizio :Prrr: ); noi in pratica possiamo fare in queste due maniere:
1) usare il ";" per separare i comandi, così i newlines e carriage returns li possiamo usare anche "intra-comando" e farli rientrare nella categoria "separatori"
2) non usare il ";", fare una sintassi stile BASIC, e riservare i newlines/carriage returns per la separazione di comandi (dunque questi non potranno rientrare nella categoria dei separatori)
io sono per la seconda: è una sintassi meno flessibile ma più semplice, non penso che noi abbiamo particolare bisogno della versione più flessibile :p ci complica solo la vita a occhio di una 30ina di righe di codice :D

altro discorso, il backslash a fine riga stile C99: io non ce lo metterei per lo stesso discorso di sopra, anche se in effetti potrebbe servire per chiarezza nei comandi *molto* lunghi... direi che il codice va progettato in modo da lasciare aperta questa possibilità.

posto qui una versione leggermente aggiornata della sintassi, perché ho dimenticato che i separatori possono stare anche tra i parametri :)


le parti incluse tra parentesi quadre sono opzionali

sintassi del file:
[comando1]
[comando2]
[comando3]
...

sintassi di un comando:
[separatori] nome [separatori] ( [separatori] [parametro1] [separatori] [, parametro2] [separatori] [, ...] [separatori] ) [separatori] [newline]

separatori: qualsiasi sequenza contigua di spazi e tabulazioni

nome: sequenza di almeno 1 caratteri alfanumerici e underscores; non deve iniziare con un numero.

sintassi di un parametro:
numero oppure stringa

numero: qualsiasi sequenza contigua (di almeno 1 carattere) di cifre numeriche da 0 a 9; la sequenza può eventualmente contenere un solo punto ("."), volendo anche all'inizio o alla fine: nel primo caso il numero è interpretato come 0.1234..., nel secondo come ...1234.000

stringa: qualsiasi sequenza di caratteri circondati da virgolette doppie ("); per inserire caratteri speciali si usa il backslash con una delle seguenti combinazioni:
- \" <-- virgolette doppie
- \n <-- line feed
- \r <-- carriage return
- \t <-- tabulazione
- \x <-- x = qualsiasi numero intero da 0 a 255; serve ad includere un carattere ASCII arbitrario
- \xXXX <-- XXX = qualsiasi numero esadecimale da 0 a FF; stessa funzionalità della precedente
- altri...

newlines: qualsiasi sequenza contigua di \n e \r

71104
25-11-2005, 13:48
errata coccige (:D)
discutendo con ciddimauro si è visto che in effetti le escape sequences a noi non è che servano molto, tranne il carattere " messo all'interno di una stringa, percui direi di implementare solo quella come sequenza e lasciare le altre come possibilità aperta (una volta implementata una non è difficile in futuro implementarne altre).

fek
25-11-2005, 13:59
Solo una cosa ragazzi, sospendete questo Spike e chiudiamo la Storia 1 prima. Al momento il nostro collo di bottiglia e' li'.

cdimauro
25-11-2005, 14:31
Grazie per i consigli: ne farò tesoro. :)

Per quanto riguarda la sintassi, però, definiamola una volta in modo da non perdere altro tempo.


Comando [spazio parametro 1 spazio parametro 2 spazio ... spazio parametro n] newline

Parametro = (intero | float | stringa)

intero = ['+' | '-'] sequenza di '0'..'9'
float = intero ['.' intero]
stringa = '"' sequenza di caratteri '"' Se è necessario inserire un '"' dentro la stringa, bisogna ripeterlo due volte '""'

Per adesso finiamo qui con questo spike. Se serve una mano per finire la storia 1, forse stasera sono a disposizione. Devo vedere un po' quando finisco col lavoro (oggi ho un'urgenza). Se sono su MSN questa sera, OK.

Una cosa: con Alberto abbiamo deciso di scambiarci gli spike. Quindi lui penserà al parser "a mano", e io mi studierò ANTLR e proverò a realizzarlo con questo strumento.

71104
25-11-2005, 18:41
cidimauro, la sintassi di un comando da te definita non corrisponde alla mia: dobbiamo decidere se usare o no le parentes tonde per includere i parametri! in effetti a pensarci bene non è detto che servano, potremmo fare una sintassi simile a quella del BASIC, però questo significa che per separare i comandi non possiamo usare i punti e virgola, ma per forza i newline (in teoria si potrebbe fare anche col punto e virgola ma diventa troppo confuso secondo me).
allora a me va bene la sintassi BASIC, parametri separati da virgole non inclusi tra parentesi.

fek
25-11-2005, 18:59
Questa decisione spetta a Jocchan. Io vorrei che il linguaggio fosse leggibile come l'inglese e senza parentesi.

cdimauro
26-11-2005, 08:43
Perfettamente d'accordo. Vediamo cosa dice Jocchan prima di iniziare. :p

Io intanto mi studio ANTLR... :D

Jocchan
26-11-2005, 09:24
Io sono assolutamente per gli spazi come unico tipo di separatori, senza virgole nè parentesi (al limite solo un ";" al termine dei comandi, ma se possibile meglio non avere nemmeno quello).
Giusto per capirci, ecco un esempio:


show bg Ice
show character 1 Josh 325 248
show character 2 Kathy 525 248
move character 1 450 248 3
dialogue Josh \"Ciao, hai impegni stasera?\"
anim character 2 37
dialogue Kathy \"Anvedi questo...\"
flash screen #FFFFFF 10
start battle Josh Kathy


P.S.: Per l'esempio ho usato i comandi che avevo elencato tempo addietro in questo post:

Anche io propenderei per un linguaggio semplice e simile all'inglese, magari con la possibilità di svilupparlo man mano che andiamo avanti.
Insomma, se volessimo iniziare dalla parte dedicata alle cutscene, potremmo partire dall'introduzione di comandi come:

- wait (xx) <--- inutile spiegarlo
- show bg (personaggio) <--- mostra lo sfondo del personaggio dato
- dialogue (nomepersonaggio) (testo) <--- mostra una finestra con dei dialoghi in basso ed una gif "nomepersonaggio.gif" per l'intestazione della finestra
- show character (codice) (nomepersonaggio) (xx, yy) <--- mostra un pg alle coordinate date dandogli un codice identificativo
- move character (codice) (coord.destinazione) (velocità) <--- semplice traslazione fino alle coordinate date, con velocità settabile
- anim character (codice) (xx) <--- mostra l'animazione xx per il personaggio specificato
- delete character (codice) <--- elimina il pg
- show picture (codice) (xx, yy) (trasparenza%) (dimensioni) <--- idem, ma per una png statica con una % variabile di trasparenza
- move picture (codice) (coord.destinazione) (velocità) (trasparenza%) (dimensioni) <--- per spostare e trasformare la png in questione
- delete picture (codice) <--- elimina la png
- show text (coordinate) (font) (testo) <--- mostra del testo generico, con font variabile, allineato a sinistra e partendo dalle coordinate date
- flash screen (colore) (durata) <--- non credo ci sia bisogno di spiegarlo
- shake screen (potenza) (durata) <--- idem ;)

Già con questi comandi, da implementare poco alla volta, si potrebbero creare praticamente TUTTE le cutscene del gioco :D
Per i comandi relativi al gioco vero e proprio devo valutare bene cosa serve, magari con un pò di consulenza tecnica :p


Vabbè le cutscene potremmo anche girarle con l'engine di The Movies... :Prrr:

cdimauro
28-11-2005, 08:09
OK. Unica cosa, eviterei \" per indicare l'inizio e la fine di una stringa: lascerei soltanto '"', che è più "naturale / intuitivo".

P.S. ANTLR è una gran figata. :sbav:

Jocchan
28-11-2005, 08:31
In realtà avevo inserito \" perchè apparissero delle virgolette nel testo, considerando già gli spazi come separatori (il riconoscimento sarebbe iniziato subito dopo il primo parametro, e sarebbe terminato con il ritorno a capo)...
Ora, riflettendoci bene, le virgolette sono più propenso ad escluderle dal testo a video.
Magari per il parsing della stringa basta un " prima ed un " dopo, cosa che aumenta la leggibilità dello script :)

71104
28-11-2005, 09:48
Jocchan, è proprio necessario che i nomi dei comandi debbano contenere spazi? così le parti del nome successive alla prima si confondono coi parametri...
inoltre per favore quando hai pronta una lista di comandi anche provvisoria scrivila qui (http://www.hwupgrade.it/forum/showthread.php?t=1035133) :)

71104
28-11-2005, 09:51
ho un'idea: siccome le istruzioni che abbiamo definito possono contenere come parametri solamente numeri e stringhe, per evitare confusioni tra parametri e parti del nome del comando basta correggere alcune cose nel tuo script di prova: i nomi dei personaggi (Josh e Kathy) mettili tra virgolette doppie; inoltre toglici il backslash dietro le virgolette ;)

Jocchan
28-11-2005, 10:50
ho un'idea: siccome le istruzioni che abbiamo definito possono contenere come parametri solamente numeri e stringhe, per evitare confusioni tra parametri e parti del nome del comando basta correggere alcune cose nel tuo script di prova: i nomi dei personaggi (Josh e Kathy) mettili tra virgolette doppie; inoltre toglici il backslash dietro le virgolette ;)

Credo sia la cosa migliore, tanto gli unici parametri di tipo stringa dovrebbero essere appunto i nomi ed il contenuto dei dialoghi.
Vedrò di stilare una lista, nel frattempo potete prendere per buona quella vecchia (solo con il ritocco delle virgolette per le stringhe) ;)

fek
28-11-2005, 12:12
Con Jocchan si pensava per i dialoghi a comandi di questa forma:


Josh says fast
Hello, how are you?
Everything's fine?
end


Io preferirei non vedere parentesi, virgolette, ma comandi semplicissimi come questo.

cionci
28-11-2005, 18:21
fek...messo in quel modo è molto facile e veloce da implementare...

Che ne dite di mettere ogni parametro in una nuova riga ?

Per i comandi con parametri variabili si legge fino a 'end'...

Una cosa di questo tipo:

wait
3000

show background
personaggio

Josh says
fast
Hello, how are you?
Everything's fine?
end

show
0001
Josh

move character
0001
328
100
1

e così via...

Semplificherebbe molto il matching dei comandi ed il parsing delle stringhe...

71104
28-11-2005, 19:00
Io preferirei non vedere parentesi, virgolette, ma comandi semplicissimi come questo. questo temo sia impossibile proprio perché appunto come dicevo prima i vari pezzi di un comando si confondono con i parametri non inclusi tra virgolette... almeno le virgolette per racchiudere le stringhe ci vogliono per forza imho... poi se avete altre soluzioni ottimo, purché la sintassi sia ben definita ed inequivocabile. ;)

ma senti, il parser lo devo committare nel repository? oppure tengo solo la mia copia locale e ve lo incollo in un post del forum quando è finito?

cionci
28-11-2005, 19:05
almeno le virgolette per racchiudere le stringhe ci vogliono per forza imho...
Non ci vogliono per forza se si mette ogni parametro di un comando una riga diversa...

Jocchan
28-11-2005, 19:23
ma senti, il parser lo devo committare nel repository? oppure tengo solo la mia copia locale e ve lo incollo in un post del forum quando è finito?

Direi la seconda, per lo meno finchè non avremo una sintassi vera e propria.
L'idea di separare i vari parametri nelle varie righe mi sembra buona, però ho paura che si perda in leggibilità, quindi per ora eviterei questa soluzione.
Stavo riflettendo piuttosto sul fatto che non credo ci possano essere problemi con i comandi costituiti da due parole: la seconda infatti può essere sempre considerata come un parametro della prima.
Mi spiego meglio:

- move character
- move picture

Character e picture possono essere considerati come dei parametri per il comando "move". Idem per "show", "delete" e "anim" (per il quale il parametro picture non ha molto senso, ma va bene lo stesso con character).
Io sarei molto più orientato per dei comandi su una sola linea, insomma, credo sia più sintetico e più comodo da leggere e da scrivere.

71104
28-11-2005, 19:25
Non ci vogliono per forza se si mette ogni parametro di un comando una riga diversa... hum, ok, basta che ci mettiamo d'accordo... :p
poi ho scoperto una classe Java che ci aiuta moltissimo nel parsing, presente sia in Java 1.4.2 che nell'1.5: StreamTokenizer, che serve a dividere in tokens un InputStream e a leggerlo token per token; con questa classe e con una sintassi così semplice diventa tutto uno scherzo :)

fek, va bene se il progetto lo committo nel repository in una nuova directory con questo percorso

extras/Spikes/71104/CommandParser

?

fek
28-11-2005, 21:10
hum, ok, basta che ci mettiamo d'accordo... :p
poi ho scoperto una classe Java che ci aiuta moltissimo nel parsing, presente sia in Java 1.4.2 che nell'1.5: StreamTokenizer, che serve a dividere in tokens un InputStream e a leggerlo token per token; con questa classe e con una sintassi così semplice diventa tutto uno scherzo :)

fek, va bene se il progetto lo committo nel repository in una nuova directory con questo percorso

extras/Spikes/71104/CommandParser

?

Si' perfetto :)

cdimauro
29-11-2005, 09:43
Con Jocchan si pensava per i dialoghi a comandi di questa forma:

Josh says fast
Hello, how are you?
Everything's fine?
end


Io preferirei non vedere parentesi, virgolette, ma comandi semplicissimi come questo.
Preferisco anch'io questo tipo di sintassi: più ci si avvicina ai linguaggi "umani", meglio è. ;)

Però con con l'esempio che hai proposto sorgono problemi con i generatori di parser "canonici".
Ad esempio, dopo il token "fast" il testo è da prendere così com'è, tenendo conto soltanto dell' "end" + new line per indicare al fine di questo tipo di parsing.

Con yacc non sarebbe tanto problematica la cosa, perché il lex è un "modulo" a se stante, per cui è facile scrivere degli analizzatori lessicali che cambino anche radicalmente il loro comportamento in base al contesto attuale.
Ad esempio, io ho sempre scritto i lex "a mano", passando i token al parser yacc, e potendo in qualsiasi momento mostrare o nascondere dei token "al volo".

Ad esempio in linguaggi come il pascal, dov'è possibile definire roba come questa:

procedure Pippo; cdecl; external;
begin
end;

i token cdecl ed external si possono attivare dopo la definizione di Pippo e disattivare subito prima dell'inizio della procedura (prima del begin).

Con ANTLR è un po' diverso, perché il lexer lo puoi generare direttamente nel file della grammatica del parser. Anzi, è esattamente quello che si fa normalmente: non ho ancora visto esempi di lexer "scritti a mano" e utilizzati dalla classe che del parser (darò un'altra occhiata alla documentazione e ai forum).

Comunque in generale linguaggi "umani" comportano dei problemi quando si "mischiano" quelli che sono dei token da riconoscere dai "dati", questo è poco ma sicuro.

Sul fatto di mettere Josh e Kathy come stringa, non sono molto d'accordo: se i personaggi sono "predefiniti", si possono includere nell'elenco dei token in modo da evitare l'uso di '"' per rappresentarli negli script. Inoltre in questo modo deleghiamo già al parser il compito di controllare se quello specificato è un character valido oppure no; altrimenti dovremmo farlo noi, a livello di codice, andando a controllare COMUNQUE se il nome immesso fa parte di una lista: cioé la stessa cosa che farebbe il parser normalmente. ;)

Per quanto detto, per adesso proporrei qualcosa del genere:
Josh says fast "
Hello, how are you?
Everything's fine?"

Oppure:
Josh says fast
" Hello, how are you?
Everything's fine?"

Entrambe possono essere implementate senza troppi problemi (normalmente le stringhe non vanno a capo e il newline indica la fine di un comando. In questo caso il newline non dev'essere processato finché la stringa non viene chiusa; è necessario di definire un altro tipo di stringa rispetto agli altri casi).

Quanto ad ANTLR, è molto potente anche perché, a differenza di tool come YACC & derivati (che generano un automa a stati, che necessita di un certo tempo), genera dei parser di tipo recursive descendant: quindi MOLTO veloci nell'eseguire il parsing. Non è il nostro caso, ma è comunque utile saperlo (a me interessa moltissimo :D).

Trattandosi di spike e non di task, magari per il momento direi di lasciare un certo margine di flessibilità nel linguaggio da riconoscere. Discutiamone un po', magari cercando di non mettere dei paletti preventivamente. Vediamo di realizzare qualcosa di funzionante, anche soltanto a livello embrionale, e di decidere poco alla volta cosa aggiungere.
Questo lo dico perché scrivere un parser per un linguaggio non è una cosa semplice, ma a volte lavorandoci saltano fuori delle problematiche derivante dal fatto che certe grammatiche sono difficili da implementare; è facile che magari aggiungendo un nuovo elemento al linguaggio sorgano dei conflitti.

cdimauro
29-11-2005, 09:50
Direi la seconda, per lo meno finchè non avremo una sintassi vera e propria.
L'idea di separare i vari parametri nelle varie righe mi sembra buona, però ho paura che si perda in leggibilità, quindi per ora eviterei questa soluzione.
Idem.
Stavo riflettendo piuttosto sul fatto che non credo ci possano essere problemi con i comandi costituiti da due parole: la seconda infatti può essere sempre considerata come un parametro della prima.
Mi spiego meglio:

- move character
- move picture

Character e picture possono essere considerati come dei parametri per il comando "move". Idem per "show", "delete" e "anim" (per il quale il parametro picture non ha molto senso, ma va bene lo stesso con character).
Non sono mica dei parametri: move character e move picture sono due comandi diversi. ;)

Non farti problemi nel presentare "comandi" che abbiano più di una parola: non è questo che rende difficoltoso il parsing del testo. ;)
move character at 320 240

Non è niente di eccezionale. ;)
Io sarei molto più orientato per dei comandi su una sola linea, insomma, credo sia più sintetico e più comodo da leggere e da scrivere.
E anche da implementare. ;)

Resta da definire se il case è significativo. Per il momento, per semplificare il parsing, proporrei di sì. Poi vediamo se è possibile rendere il parser case insensitive, che è sicuramente più "umano".
Per il parser "scritto a mano" è un problema di semplice soluzione, ma per un parser con ANTLR non è banale. :p

cionci
29-11-2005, 10:08
E anche da implementare. ;)
Non con il parser scritto a mano...

fek
29-11-2005, 10:22
Per quanto detto, per adesso proporrei qualcosa del genere:
Josh says fast "
Hello, how are you?
Everything's fine?"

Oppure:
Josh says fast
" Hello, how are you?
Everything's fine?"



Proprio non mi piace l'idea di usare le virgolette. Secondo me se il linguaggio si mantiene molto semplice e' possibile farne a meno. C'e' da studiarci un po'. Il token \n in questo caso definirebbe, dopo il comando says, quando inizia la stringa, ed un 'end' a inizio riga definirebbe la fine. Mi sembra che Python abbia qualcosa di analogo.

Trattandosi di spike e non di task, magari per il momento direi di lasciare un certo margine di flessibilità nel linguaggio da riconoscere.

Certo, possiamo mantenere lo Spike complicato e flessibile per analizzare piu' problematiche possibile.

^TiGeRShArK^
29-11-2005, 13:20
hum, ok, basta che ci mettiamo d'accordo... :p
poi ho scoperto una classe Java che ci aiuta moltissimo nel parsing, presente sia in Java 1.4.2 che nell'1.5: StreamTokenizer, che serve a dividere in tokens un InputStream e a leggerlo token per token; con questa classe e con una sintassi così semplice diventa tutto uno scherzo :)

fek, va bene se il progetto lo committo nel repository in una nuova directory con questo percorso

extras/Spikes/71104/CommandParser

?
stavi facendo il parser senza usare il tokenizer??? :eek:

:D

^TiGeRShArK^
29-11-2005, 13:32
dunque... sto notando un pò di confusione...
io non sono x nulla un esperto di parser... al max ho toccato un pò del codice scritto mediante javacc (mi pare si kiamasse così...)
ma x fare cose del tipo:

Josh says fast
Hello, how are you?
Everything's fine?
Wilma says slow
mmmmm, not so bad....
but the show must go on!

non credo sia molto complesso da realizzare con un parser fatto a mano...
io leggerei una riga per volta col metodo readLine dello streamReader, quindi utilizzando lo StringTokenizer sulla stringa restituita analizzerei il primo token...
se è un comando passerei alla procedura di controllo del comando e lì caricherei i successivi parametri mediante i token successivi...
a questo punto nella linea successiva ci sarebbe il testo da visualizzare perchè facendo un analisi del primo token vedo che non è il nome di un comando (eventualmente si potrebbe analizzare anche il secondo token nel caso in cui Josh dicesse qualkosa del tipo "Wilma u're such a bitch!" ke porterebbe a confondere il parser controllando solo il primo token)....
arrivati alla linea in cui il primo token è un comando e il secondo token è un parametro ripeterei il processo perchè significa che sto parsando effetivamente il comando successivo...
non so se mi sono spiegato bene... cmq se ho un pò di tempo stasera vedo di darci un okkiata casomai....

P.S. 71104 cmq usa SIA readLine ke StringTokenizer per parsare... nn oso immaginare che cosa stavi usando per riconoscere i vari token...... :mbe:

^TiGeRShArK^
29-11-2005, 23:27
Allora... ecco come promesso una prima skifiltosa versione di parser che "dovrebbe" riconoscere tutti i comandi elencati da jocchan precedentemente
(però ho solo inserito due character... ma come vedete dal codice è banale inserirne di +....):

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;

public class Parser {
Set<String> textCommands = new HashSet();

Set<String> commands = new HashSet();

Set<String> params = new HashSet();

public Parser() {
textCommands.add("josh");
textCommands.add("wanda");
textCommands.add("show");
commands.add("anim");
commands.add("wait");
commands.add("delete");
commands.add("flash");
commands.add("shake");
params.add("bg");
params.add("character");
params.add("picture");
params.add("text");
params.add("screen");

try {
BufferedReader in = new BufferedReader(new FileReader(
"c:/input.txt"));
while (in.ready()) {
String line = in.readLine();
StringTokenizer st = new StringTokenizer(line);
String text = "";
String commandValue = "";
String parametri = "";
boolean textCommand = false;
while (st.hasMoreTokens()) {
String token = st.nextToken();
if (commandValue.equalsIgnoreCase("")
&& textCommands.contains(token.toLowerCase())) {
commandValue = token.toLowerCase();
System.out.println("Comando: "
+ commandValue);
textCommand = true;
continue;
}
if (commandValue.equalsIgnoreCase("")
&& commands.contains(token)) {
commandValue = token.toLowerCase();
System.out.println("Comando: " + commandValue);
continue;
}
if (textCommand) {
if (token.equalsIgnoreCase("text")) {
parametri = token + " " + st.nextToken() + " " + st.nextToken() + " " + st.nextToken() + " ";
while (st.hasMoreTokens()) {
text += st.nextToken() + " ";
}
System.out.println("Parametro: " + parametri);
System.out.println("Testo: " + text);
} else if (token.equalsIgnoreCase("says")) {
parametri = token + " " + st.nextToken();
while (st.hasMoreTokens()) {
text += st.nextToken() + " ";
}
System.out.println("Parametro: " + parametri);
System.out.println("Testo: " + text);
} else {
parametri = token + " ";
while (st.hasMoreTokens()) {
parametri += st.nextToken() + " ";
}
System.out.println("Parametro : " + parametri);
}
textCommand = false;
continue;
}
parametri = token + " ";
while (st.hasMoreTokens()) {
parametri += st.nextToken() + " ";
}
System.out.println("Parametro : " + parametri);
}
System.out.println("---------------------------------");
}
} catch (Exception e) {
e.printStackTrace();
}
}


public static void main(String[] args) {
Parser p = new Parser();

}
}

per ora questo codice distingue i comandi, i parametri ed il testo inserito.
La limitazione è ke il testo di un comando va tutto su una linea.
Potrei suggerire a josh di provarlo, e per fare questo allego il file input.txt sul quale vanno i comandi e che va nella directory c:\ e il file .class da eseguire col .bat allegato.

ogni suggerimento è ben accetto..
ma credo che seguendo questa filosofia implementare il parser non dovrebbe essere difficile ...
(ovviamente quel codice puzza di morto.....però ora non avevo tempo per renderlo + leggibile... magari domani ci do un okkiatina se può servire...)

[EDIT] corretto un errore del kakkio... ma tranquilli ce ne saranno tanti altri dato che non ho usato il TDD :D
dimenticavo... dovrebbe essere pure nase insensitive se non ho sbagliato qualkosa... :fagiano:

P.S. ..... si si ... lo so fek... il forum è k-free... ma ho sonno... non rompere :Prrr:

^TiGeRShArK^
30-11-2005, 08:59
aggiornamento...la notte porta consiglio si sa.....:D
un modo per semplificare notevolmente il parser è:
1)utilizzare print al posto di show text (penso ke sia comunque molto chiaro come comando :D)
2)anteporre il comando character ai nomi dei protagonisti quando devono dire qualcosa
Inoltre se funziona quello che ho in mente dovrei eliminarmi un bel paio di if e la complessità ciclomatica del parser scenderebbe di molto....
cmq.. a stesera se riesco a trovare un pò di tempo.

cdimauro
30-11-2005, 09:38
Non con il parser scritto a mano...
Finché il linguaggio si mantiene su questi livelli di semplicità, sì. ;)

cdimauro
30-11-2005, 09:40
Proprio non mi piace l'idea di usare le virgolette. Secondo me se il linguaggio si mantiene molto semplice e' possibile farne a meno. C'e' da studiarci un po'. Il token \n in questo caso definirebbe, dopo il comando says, quando inizia la stringa, ed un 'end' a inizio riga definirebbe la fine. Mi sembra che Python abbia qualcosa di analogo.
Letto stamattina (alle 5 :D) : ANTLR supporta l'uso di lexer multipli. :D
Quindi non dovrebbe essere un problema implementare un parser per lo spezzone di testo che hai riportato. ;)

Comunque, come hai detto, c'è da studiarci un po': ANTLR è molto potente, ma dev'essere "metabolizzato". :p
Certo, possiamo mantenere lo Spike complicato e flessibile per analizzare piu' problematiche possibile.
Perfetto. Grazie. :)

fek
30-11-2005, 10:00
(ovviamente quel codice puzza di morto.....però ora non avevo tempo per renderlo + leggibile... magari domani ci do un okkiatina se può servire...)

Una piccola precisazione, e' uno Spike, quindi tutto quello che abbiamo detto fino ad ora sul testing e sul refactoring non si applica. Il motivo e' semplice: tutto questo codice verra' buttato alla fine dello Spike e verra' riscritto con tutti i canoni quando entra in produzione.

Quello che interessa nello Spike e' esplorare le soluzioni il piu' velocemente possibile e buttare giu' tanto codice in poco tempo, codice che in futuro non sara' da mantenere perche' viene buttato.

^TiGeRShArK^
30-11-2005, 11:35
si si lo so...
però lo stesso puzza di morto :p
cmq esplorando queste cose con lo spike mi è venuta un ideuzza simpatica, che sperando che funzioni, dovrebbe darci una soluzione efficiente ed elegante per il parsing dei comandi....
sempre che jocchan dia l'ok almeno sull'uso del comando character prima del nome dei personaggi quando devono dire qualcosa....

fek
30-11-2005, 11:36
si si lo so...
però lo stesso puzza di morto :p
cmq esplorando queste cose con lo spike mi è venuta un ideuzza simpatica, che sperando che funzioni, dovrebbe darci una soluzione efficiente ed elegante per il parsing dei comandi....
sempre che jocchan dia l'ok almeno sull'uso del comando character prima del nome dei personaggi quando devono dire qualcosa....

Cera di fare senza "character", in fondo i nomi dei personaggi per noi sono delle keyword.

71104
30-11-2005, 11:57
ho fatto il commit del mio parser (scritto a mano senza ANTLR). la sintassi è quella inizialmente definita da Jocchan:
Anche io propenderei per un linguaggio semplice e simile all'inglese, magari con la possibilità di svilupparlo man mano che andiamo avanti.
Insomma, se volessimo iniziare dalla parte dedicata alle cutscene, potremmo partire dall'introduzione di comandi come:

- wait (xx) <--- inutile spiegarlo
- show bg (personaggio) <--- mostra lo sfondo del personaggio dato
- dialogue (nomepersonaggio) (testo) <--- mostra una finestra con dei dialoghi in basso ed una gif "nomepersonaggio.gif" per l'intestazione della finestra
- show character (codice) (nomepersonaggio) (xx, yy) <--- mostra un pg alle coordinate date dandogli un codice identificativo
- move character (codice) (coord.destinazione) (velocità) <--- semplice traslazione fino alle coordinate date, con velocità settabile
- anim character (codice) (xx) <--- mostra l'animazione xx per il personaggio specificato
- delete character (codice) <--- elimina il pg
- show picture (codice) (xx, yy) (trasparenza%) (dimensioni) <--- idem, ma per una png statica con una % variabile di trasparenza
- move picture (codice) (coord.destinazione) (velocità) (trasparenza%) (dimensioni) <--- per spostare e trasformare la png in questione
- delete picture (codice) <--- elimina la png
- show text (coordinate) (font) (testo) <--- mostra del testo generico, con font variabile, allineato a sinistra e partendo dalle coordinate date
- flash screen (colore) (durata) <--- non credo ci sia bisogno di spiegarlo
- shake screen (potenza) (durata) <--- idem ;)

Già con questi comandi, da implementare poco alla volta, si potrebbero creare praticamente TUTTE le cutscene del gioco :D
Per i comandi relativi al gioco vero e proprio devo valutare bene cosa serve, magari con un pò di consulenza tecnica :p


Vabbè le cutscene potremmo anche girarle con l'engine di The Movies... :Prrr:
i commenti sono a linea singola e sono come quelli del BASIC (iniziano con l'apice singolo); i comandi devono occupare una sola riga, cioè sono separati l'uno dall'altro solo dal newline; le stringhe non richiedono virgolette doppie (come richiesto), ma il problema è che non devono contenere spazi altrimenti vengono interpretate come stringhe separate.

71104
30-11-2005, 12:17
sto migliorando il codice in maniera tale che le virgolette attorno alle stringhe siano opzionali: se non ci sono la stringa viene letta come una parola sola (se ci sono più parole vengono considerate parametri distinti), se invece ci sono tutto quello che c'è dentro viene considerato un unico parametro stinga.

71104
30-11-2005, 12:26
fatto: dovrebbe funzionare; però mi sono accorto che non parsa correttamente i commenti a linea singola: devo ancora capire bene come si deve usare lo StreamTokenizer in proposito.

fek
30-11-2005, 12:26
Jocchan, quando hai tempo ci dai un po' di feedback sul lavoro di 71104 e TigerShark?

Nel frattempo 71104 puo' fiondarsi sul suo task che abbiamo un po' di gente in fila in attesa :)

71104
30-11-2005, 12:28
ok ^^'

^TiGeRShArK^
30-11-2005, 13:14
Cera di fare senza "character", in fondo i nomi dei personaggi per noi sono delle keyword.
ti spiego...
usando character sarei riuscito a distinguere i comandi completamente senza if...
invece utilizzando il nome dei personaggi devo mettergli degli if per ricondurli al caso base di comando di visualizzazione testo....
vabbè...detto così non si capisce niente...
praticamente:
avevo intenzione di usare un classloader che mi caricasse direttamente il codice passandogli il nome della classe del comando..
in questo modo con qualcosa del tipo:
Class.forName(comando);
mi risultava gratis il riconoscimento dei comandi....
però utilizzando il nome dei personaggi avrei due possibilità:
1)creare una classe per ogni nome del personaggio (quindi assolutamente da scartare perchè crea una replicazione di codice inutile)
2)eseguire dei confronti..................
fsdkajfklsadlkfas
:rotfl:
mentre scrivevo mi è venuta in mente la soluzione :D
ok.. vada per il nome dei personaggi come comando :D

fek
30-11-2005, 14:01
mentre scrivevo mi è venuta in mente la soluzione :D
ok.. vada per il nome dei personaggi come comando :D

Bingo :D

Non sai quante volte mi succede.

io: Scusa ho un problema... bla bla ... e poi succede che bla bla bla... ma allora bla bla.. e quindi bla bla bla... ah.. ecco, gia', la soluzione e' questa, sei stato di grande aiuto :)

lui: uh?!

^TiGeRShArK^
30-11-2005, 14:05
:rotfl:
siamo messi male, eh? :D

fek
30-11-2005, 14:10
:rotfl:
siamo messi male, eh? :D

Ma no, e' perfettamente normale. Quando pensi dai molto per scontato e ti focalizzi solo su alcuni aspetti. Quando invece spieghi il problema a qualcun altro sei costretto a ripetere tutti i particolari del problema e ti focalizzi anche sui particolari che mentre pensi dai per scontati. E da qui arriva spesso la soluzione :)

71104
30-11-2005, 16:08
sono dei vostri: succede spesso anche a me :D
mi sa che pure su Usenet è rimasta ancora qualche mia traccia di questo fatto... :D

71104
30-11-2005, 16:09
io: Scusa ho un problema... bla bla ... e poi succede che bla bla bla... ma allora bla bla.. e quindi bla bla bla... ah.. ecco, gia', la soluzione e' questa, sei stato di grande aiuto :)

lui: uh?! in un certo senso lui infatti è stato di grande aiuto :D
in realtà però in questi casi basterebbe anche un manichino o un amico immaginario LOL :D

Jocchan
30-11-2005, 16:54
Jocchan, quando hai tempo ci dai un po' di feedback sul lavoro di 71104 e TigerShark?


Scusate il ritardo, ho avuto svariate seccature :p

EDIT: Ho provato la soluzione di Tiger e mi piace molto, e vorrei toccare con mano quella di 71104 (che mi sembra anche valida, dato che comunque garantisce una sintassi come quella voluta). Dovrei comunque testarla per dirlo ^^
Apprezzo molto il fatto che la soluzione di Tiger sia case insensitive.
Per i dialoghi, pensandoci bene sono nettamente a favore della reintroduzione delle virgolette: la leggibilità dello script ci guadagna in maniera notevole.
Fate un pò voi il confronto:

Josh says fast "Ciao belli!"
Ice says fast "E chi è 'sto tizio?"
Tizio says fast "Non ne ho idea..."

Josh says fast Ciao belli!
Ice says fast E chi è 'sto tizio?
Tizio says fast Non ne ho idea...

fek
30-11-2005, 18:13
Per i dialoghi, pensandoci bene sono nettamente a favore della reintroduzione delle virgolette: la leggibilità dello script ci guadagna in maniera notevole.
Fate un pò voi il confronto:

Josh says fast "Ciao belli!"
Ice says fast "E chi è 'sto tizio?"
Tizio says fast "Non ne ho idea..."

Josh says fast Ciao belli!
Ice says fast E chi è 'sto tizio?
Tizio says fast Non ne ho idea...

Allora direi che se la stringa e' sulla stessa riga va virgolettata, se invece si va a capo, va copiata integrale senza virgolette. Il meglio dei due mondi. Che te ne sembra?

^TiGeRShArK^
30-11-2005, 18:55
ehm....
per comandi su unica riga non avrei problemi a renderlo anche indipendente dalle virgolette... nel senso che usarle o non usarle darebbe lo stesso risultato...
per comandi su + righe mi sa che dovrei cambiare la logica che ho usato finora.....
cmq finito il task 2 vedo e vi faccio sapere.....

71104
30-11-2005, 18:58
fek, Jocchan: come ho spiegato la mia soluzione è flessibile sul punto delle virgolette (o perlomeno dovrebbe esserlo a meno di bug :D): le virgolette sono opzionali: se ci sono tutto quello che c'è dentro è una stringa, se non ci sono invece ogni parola viene interpretata come singolo parametro.

PS: anche il mio parser è case insensitive: lo StreamTokenizer ha un metodo che converte subito tutto in lower case.

71104
30-11-2005, 18:59
EDIT: Ho provato la soluzione di Tiger e mi piace molto, e vorrei toccare con mano quella di 71104 (che mi sembra anche valida, dato che comunque garantisce una sintassi come quella voluta). Dovrei comunque testarla per dirlo ^^ provala pure: l'ho committata stamattina in extras/Spikes/71104/CommandParser/ ;)
è abbastanza flessibile perché permette facilmente di aggiungere comandi in futuro e di implementarli nella apposita classe che dovrebbe essere derivata da CommandImpl.

a proposito, il programmetto di prova, ParserMain, crea una nuova istanza del parser e gli fa parsare il file prova.txt; ne ho messo uno che contiene un paio di comandi; se vuoi giocare un po' col parser posso implementare delle versioni fake dei comandi che mancano (attualmente ho implementato solo wait e una versione di show) che stampano qualche output su System.out.

^TiGeRShArK^
30-11-2005, 23:48
ok.. ultime novità...
la mia ideuzza funzionava! :D

if(textCommands.contains(commandValue)&&!commandValue.equalsIgnoreCase("Show")){
parametri = commandValue + " " + parametri;
commandValue = "Character";
}
if (commandValue!=null){
commandValue = getFirstUpperCase(commandValue);
CommandInterface command = (CommandInterface)Class.forName("commands."+commandValue).newInstance();
command.setParameters(parametri);
command.setText(text);
command.execute();
}
}

questo semplice codice passa il controllo alla classe opportuna che si chiama come il comando (tranne che per i personaggi che sono gestiti dalla classe Character), vengono settati i parametri ed il testo (eventuale) da visualizzare.
Tutte le classi si trovano nel package commands ed ereditano dalla classe CommandInterface (dovrebbe essere un interfaccia.. ma x evitare di riscrivermi lo stesso codice in tutte le classi figlie per ora è una classe ;))
così facendo, per implementare la gestione di comandi nuovi è sufficiente crearsi una classe nuova nel package commands che estende l'interfaccia CommandInterface.
Inoltre il riconoscimento dei comandi presenti passati e futuri ci viene praticamente gratis senza utilizzare nemmeno un if (a parte quello per capire quali comandi si riferiscono ai personaggi per farli gestire dalla classe character)
ora vedo di committare il codice in un nuovo branch :D
a domani! ;)

[EDIT]potete scaricare sorgenti e binari dal repository nella cartella extras/spike/TigerShark
Per provarlo basta lanciare il file .bat e modificare il file input.txt che non deve stare + obbligatoriamente su c:\ ma che deve stare nella cartella da dove lanciate il .bat

buon divertimento jocchan :D
(anche se ora forse sarebbe meglio che anche gli altri dessero un'okkiatina al codice e mi dicano come va ;))

cdimauro
01-12-2005, 10:29
Allora direi che se la stringa e' sulla stessa riga va virgolettata, se invece si va a capo, va copiata integrale senza virgolette. Il meglio dei due mondi. Che te ne sembra?
Quindi le sintassi sarebbero questa:
Josh says fast "Ciao belli!"
di sicuro (singola linea).

Mentre per l'altro caso le possibilità sarebbero le seguenti:
Josh says fast Ciao
belli!
end<newline>
Josh says fast Ciao
belli! end<newline>
Josh says fast
Ciao belli!
end<newline>
Josh says fast
Ciao belli! end<newline>
Quale di queste (anche più di una, eventualmente) adottiamo?

Anche con ATNLR la sintassi sarà case-insensitive (visto stamattina :D).

fek
01-12-2005, 10:42
Mentre per l'altro caso le possibilità sarebbero le seguenti:
Josh says fast Ciao
belli!
end<newline>
Josh says fast Ciao
belli! end<newline>
Josh says fast
Ciao belli!
end<newline>


Per semplificare eliminiamo queste due sintassi.

E lasciamo solo la seguente:

Josh says fast
Ciao belli! end<newline>

Jocchan
01-12-2005, 13:07
71104, dopo alcuni problemi con Spartacus sono riuscito (finalmente) a fare il checkout, ed ho scaricato il tuo spike... solo che non riesco a farlo partire (ho provato ad adattare il .bat di Tiger per far partire Parser.class ma non funzia).

71104
01-12-2005, 19:32
siccome quello è un progetto a parte io per farlo partire da Eclipse 3.1 faccio così: cancello il progetto corrente (scegliendo ovviamente di non cancellare i contenuti), poi File -> Import, Existing non ricordo cosa, navigo fino alla directory CommandParser contenente il mio spike e gli do' l'OK; però non basta perché bisogna anche sistemare la configurazione di Run: devi settare ParserMain come main class; dopodiché se fai Run dovrebbe andare e parsare i comandi scritti in prova.txt.

Jocchan
01-12-2005, 19:34
siccome quello è un progetto a parte io per farlo partire da Eclipse 3.1 faccio così: cancello il progetto corrente (scegliendo ovviamente di non cancellare i contenuti), poi File -> Import, Existing non ricordo cosa, navigo fino alla directory CommandParser contenente il mio spike e gli do' l'OK; però non basta perché bisogna anche sistemare la configurazione di Run: devi settare ParserMain come main class; dopodiché se fai Run dovrebbe andare e parsare i comandi scritti in prova.txt.

Quindi per testarlo devo installare Eclipse e - potenzialmente, ma molto probabilmente - mandare a pu**ane il repository con qualche impostazione errata? :eek:
Non c'è un qualche altro modo che non preveda Eclipse per testarlo? :confused:

71104
01-12-2005, 19:56
Quindi per testarlo devo installare Eclipse e - potenzialmente, ma molto probabilmente - mandare a pu**ane il repository con qualche impostazione errata? :eek:
Non c'è un qualche altro modo che non preveda Eclipse per testarlo? :confused: ma che puttane e che repository, casomai se vuoi stare sicuro fai il checkout solamente della cartella extras/Spikes/71104/, così al limite mandi a puttane solo quella, anzi non committarla così non mandi a puttane un bel niente :D
ho detto 3 volte "puttane" in... anzi 4 :D in un solo post, e senza censura :D

PS: se è tutto un modo per dire che preferisci la soluzione di TigerShark dillo chiaramente :sob:

Jocchan
01-12-2005, 20:01
PS: se è tutto un modo per dire che preferisci la soluzione di TigerShark dillo chiaramente :sob:

Non posso preferire quella se non ho visto la tua ;)
Se sapessi settare il classpath, potrei far partire la tua soluzione con un bat, come ho fatto per quella di tiger :stordita:

71104
01-12-2005, 20:06
Non posso preferire quella se non ho visto la tua ;)
Se sapessi settare il classpath, potrei far partire la tua soluzione con un bat, come ho fatto per quella di tiger :stordita: scusa, eh: hai Eclipse 3.1? hai fatto come ti ho descritto? io il bat mi spiace ma non lo so fare!!! :cry:
non ho mai capito come cavolo si usa il comando java :|

Jocchan
03-12-2005, 11:08
Ho testato entrambe le soluzioni e sono comunque molto, molto simili, se non identiche :)
Entrambe riconoscono i comandi dai parametri, e consentono allo script una sintassi praticamente identica (l'unica eccezione riguarda i dialoghi, in cui la soluzione di Tiger mi sembra migliore... ma suppongo che anche dal codice di 71104 si possa implementare una soluzione identica con un paio di modifiche).
L'unico criterio di scelta per una soluzione o l'altra, quindi, è la complessità del parser: dato che i risultati sono più o meno identici, sceglieremo quello con il codice meno complesso (e qui deve valutare qualcuno più ferrato di me), e lo svilupperemo parallelamente al gioco vero e proprio.

^TiGeRShArK^
03-12-2005, 13:21
secondo me l'ideale sarebbe sviluppare un parser qualsiasi in TDD che si ricavi comando, parametri(come stringa unica o direttamente come array di stringhe che forse sarebbe meglio), testo da passare poi alle varie classi dei comandi che gestiscono internamente e separatamente la logica di ogni comando.
Tanto visto il ridotto numero di comandi non credo che avremo molte classi... e quando (e se) aggiungeremo comandi nuovi sarà sufficiente aggiungere la classe corrispondente senza modificare il parser generale vero e proprio....
poi la parola credo spetti a fek per decidere... è lui il coach :Prrr:

fek
03-12-2005, 13:29
Voglio attendere lo spike di Cesare per capire se e' piu' comodo scriverlo in ANTLR o a mano. Poi ovviamente si riparte daccapo in TDD storia per storia.

cdimauro
04-12-2005, 05:59
Entro domani spero di finirlo.

In futuro magari dovremmo definire un'interfaccia che la classe Parser dovrà implementare, e che riporti i metodi da richiamare quando viene riconosciuta un'istruzione.
In questo modo passare da un parser all'altro dovrebbe essere immediato.

71104
04-12-2005, 12:16
Ho testato entrambe le soluzioni e sono comunque molto, molto simili, se non identiche :)
Entrambe riconoscono i comandi dai parametri, e consentono allo script una sintassi praticamente identica (l'unica eccezione riguarda i dialoghi, in cui la soluzione di Tiger mi sembra migliore... ma suppongo che anche dal codice di 71104 si possa implementare una soluzione identica con un paio di modifiche). infatti si può: ho notato che TigerShark ha messo i nomi dei personaggi nel set dei comandi, e poi ha implementato una apposita classe per svolgere quei comandi particolari; da me volendo si può fare lo stesso, anzi lo faccio adesso ;)
l'unica differenza è che mentre lui per implementare i comandi ha usato intere classi, io ho usato una interfaccia (CommandImpl) da implementare con vari metodi che corrispondono ai vari comandi.

EDIT: faccio la modifica dopo pranzo :p

fek
04-12-2005, 12:29
infatti si può: ho notato che TigerShark ha messo i nomi dei personaggi nel set dei comandi, e poi ha implementato una apposita classe per svolgere quei comandi particolari; da me volendo si può fare lo stesso, anzi lo faccio adesso ;)
l'unica differenza è che mentre lui per implementare i comandi ha usato intere classi, io ho usato una interfaccia (CommandImpl) da implementare con vari metodi che corrispondono ai vari comandi.

EDIT: faccio la modifica dopo pranzo :p

Voglio essere molto chiaro su questo punto per evitare malintesi futuri: tutto il codice che scrivete in questo Spike sara' buttato alla fine del prototipo. La soluzione che implementeremo sara' molto probabilmente una fusione del vostro lavoro e sara' implementata da tutti quanti test-driven.

In altre parole, non attaccatevi troppo sentimentalmente al codice che state scrivendo ora :)

71104
04-12-2005, 12:54
lo so lo so, non ti preoccupare :)
anzi, direi che a questo parser ci ha dedicato più fatiche TigerShark che io ^^
poi non so, magari è solo una sensazione...

^TiGeRShArK^
04-12-2005, 17:23
io ho faticato abbastanza per la parte di gestione della logica per arrivare alla sintassi comando + parametro + testo...
il resto per dividere i comandi in classi è venuto da solo :p

cdimauro
05-12-2005, 09:56
ma che puttane e che repository, casomai se vuoi stare sicuro fai il checkout solamente della cartella extras/Spikes/71104/,
Scusate ma, pur effettuando l'update diverse volte in questi giorni, non m'è mai apparsa la cartella extras in Eclipse: da dove ci arrivo?

Jocchan
05-12-2005, 09:59
Si trova fuori dalla cartella trunk (infatti anche io, che avevo settato Tortoise su trunk, non riuscivo a visualizzarla :D ), nella directory base diamonds ;)

cdimauro
06-12-2005, 09:32
Ho rifatto il checkout mettendo come url la cartella superiore, come dicevi, e finalmente è andato tutto bene. Grazie! :)

Per quanto riguarda il parser, l'ho quasi finito: c'è soltanto una regoletta del lexer che devo sistemare (va in conflitto la definizione di INTEGER e di REAL), ma stasera conto di risolverlo.

Volevo chiederti alcune cose su come dovrebbe funzionare il parser (come riferimento ho preso tutti i comandi elencati dal tuo post a pagina 3), che mi sono venute in mente lavorando alla sua implementazione.

1) Per quanto riguarda "show text (coordinate) (font) (testo)", ho messo come parametro font una lista con dei nomi; per il momento sono arial e times, quindi un esempio sarebbe il seguente: show text 320 240 arial "Prova!".

2) Per quanto riguarda "flash screen (colore) (durata)", ho cannato (non avevo visto il tuo esempio che precedeva la sintassi: mi sono fissato soltanto su quest'ultima. :( ) e ho messo come parametro colore anche qui una lista di nomi: red, green e blue. Stasera correggo e permetto anche l'inserimento del colore come tripletta RGB, come avevi indicato (#FFFFFF), ma vorrei sapere se il parser dovrà accettare soltanto quest'ultima sintassi, oppure anche una lista (e in tal caso quale e con quali valori RGB) come ho fatto io.
Quindi "flash screen #FF0080 2" oppure "flash screen red 2".
In ogni caso usando il # assumero che la seguenza sia RGB (quindi #FF0080 -> Rosso = 255, Verde = 0, Blu = 128).

3) Per adesso il parser si deve limitare a riconoscere soltanto il testo o deve fare qualcos'altro, come la valutazione degli argomenti e la loro visualizzazione, o altro ancora.

Nel primo caso il parser semplicemente non darà errore se si trova davanti a un testo corretto, e solleverà un'eccezione altrimenti.

Nel secondo caso è da valutare cosa si vuole ottenere, perché potrei semplicemente prendere i parametri dei comandi come se fossero delle stringhe e stamparli a video con un commento.
Oppure potrei valutarli ponendo attenzione a ciò che rappresentano, quindi se è un intero lo valuto e lo restituisc come intero, se è una stringa idem, se è un character, potrei anche cercare l'istanza della classe che lo implementa e ritornarla, ecc.
E' chiaro che il secondo caso comporta un certo lavoro, che in parte ho già fatto comunque.
Dimmi tu come dovrei procedere.


Infine, penso che la sintassi del linguaggio potrebbe essere "migliorata", a mio avviso.
Ad esempio "show character 2 Kathy 525 248" potrebbe diventare "show character Kathy 525 248"; se ho capito bene il 2 è il "codice" di Kathy, e siccome entrambe le informazioni sono presenti, magari scegliamo di specificare quella che più "umanamente comprensibile".
La sintassi potrebbe anche diventare "show Kathy 525 248" (o "show Kathy at 525 248"), perché show + Kathy permettono di determinare l'azione che si vuol compiere.

Comunque su queste cose decideremo dopo la realizzazione del parser: per adesso penso a completarlo con la sintassi che hai già specificato. ;)

cdimauro
07-12-2005, 10:33
Ho finito il parser e ho creato la cartella Spike.Cesare (o Spikes.Cesare adesso non ricordo bene), contenente la grammatica del parser (diamonds.g) e un file Main.java.

Il file diamonds.g, una volta "compilato" col tool di ANTR, genera una serie di file .java contenenti lexer, parser e token, che vanno poi usati (da Main.java, appunto), ma ho problemi con Eclipse a far vedere le librerie di ant (c'è un import ant.* da fare).
C'è qualcuno che mi può spiegare come fare, se ci sono dei parametri da settare con Eclipse?
C'è un file antlr.jad, se non ricordo: va messo da qualche parte?

Scusatemi, ma con Eclipse e l'ambiente Java sono un po' imbranato. :(

Così vediamo se posso finire di testare il parser. :)

cionci
07-12-2005, 10:38
Non credo che tu lo debba far vedere ad ANT, basta che lo veda Eclipse...

fek
07-12-2005, 11:04
Ho finito il parser e ho creato la cartella Spike.Cesare (o Spikes.Cesare adesso non ricordo bene), contenente la grammatica del parser (diamonds.g) e un file Main.java.

Il file diamonds.g, una volta "compilato" col tool di ANTR, genera una serie di file .java contenenti lexer, parser e token, che vanno poi usati (da Main.java, appunto), ma ho problemi con Eclipse a far vedere le librerie di ant (c'è un import ant.* da fare).
C'è qualcuno che mi può spiegare come fare, se ci sono dei parametri da settare con Eclipse?
C'è un file antlr.jad, se non ricordo: va messo da qualche parte?

Scusatemi, ma con Eclipse e l'ambiente Java sono un po' imbranato. :(

Così vediamo se posso finire di testare il parser. :)

Allora, io direi di mettere Antlr dentro le lib di Diamonds (nel tuo spike adesso) e fare la stessa cosa che ho fatto con altri task all'interno di build.xml. Poi ci sono i task di integrazione di Antlr. Ma in realta' per ora non ti serve fare tutto cio', basta sapere che la soluzione e' fattibile. Poi se decidiamo di usare Antlr ci penso io all'integrazione.

71104
07-12-2005, 16:32
cavolo :eek:
ho visto lo spike di Cesare con ANTLR, e ce so rimasto un po' male O_O
era sufficiente scrivere un file di testo contenente la grammatica...
credo che convenga usare quello piuttosto che il mio parser o quello di TigerShark (da un centinaio di righe l'uno... :mc: )

cdimauro
07-12-2005, 17:10
Finché non lo testo è tutto lavoro inutile, e comunque mi ha richiesto molto più tempo del previsto: voi avete già finito da un pezzo.

Comunque gli ho già aggiunto la valutazione degli argomenti in base al loro tipo, altrimenti il file con la grammatica sarebbe stato anche più corto. :angel:

Per adesso mi dedico ai task, e poi vedo di testarlo: prima il dovere e poi il piacere... :p

Grazie a tutti per le preziose info. :)

Jocchan
07-12-2005, 17:20
Finché non lo testo è tutto lavoro inutile, e comunque mi ha richiesto molto più tempo del previsto: voi avete già finito da un pezzo.

Comunque gli ho già aggiunto la valutazione degli argomenti in base al loro tipo, altrimenti il file con la grammatica sarebbe stato anche più corto. :angel:

Per adesso mi dedico ai task, e poi vedo di testarlo: prima il dovere e poi il piacere... :p

Grazie a tutti per le preziose info. :)

Sei stato grandissimo ;)

71104
07-12-2005, 18:26
mi ha richiesto molto più tempo del previsto: voi avete già finito da un pezzo. ma solo perché hai dovuto studiare ANTLR: adesso sicuramente ci metteresti molto di meno.

cdimauro
04-01-2006, 07:06
L'altro iera sera ho effettuato il commit del parser sviluppato con ANTLR. Si trova nella cartella Extras / src: ho dovuto creare quest'ultima e infilargli tutto, perché ho avuto non poche difficoltà per compilare e testare il tutto con Eclipse (mi spiace, ma non ci trovo affatto bene e perdo parecchio tempo).

diamonds.g è il file che contiene tutta la grammatica. Su Windows, una volta installato ANTLR, è sufficiente scrivere c:antlr diamonds.g (con C: che "punta" a C:\Programmi\ANTLR\bin" per tirare fuori i 4 file, che rappresentano il Lexer (analizzatore lessicale), il Parser vero e proprio, l'interfaccia che entrambi usano per i token, e un file di testo che contiene i token. Questi 4 file li ho comunque inseriti nel commit, così risparmio la fatica a tutti. ;)

In src c'è anche il file Main.java che fa uso del Lexer e del Parser: sono poche righe e mostra come usarli. Lanciandolo basta digitare da console i comandi. Il file Test.txt contiene un elenco di comandi, che potete usare con copia & incolla, per testarne il funzionamento.

Mi sono permesso di estendere la grammatica per supportare anche altre sintassi per gli stessi "comandi", per mostrare come sia molto semplice quest'operazione. Lo potete vedere dal file Test.txt, e dalla grammatica stessa, analizzando l'implementazione dei comandi.

La grammatica è abbastanza completa: include parecchi casi, specialmente per il lexer, che mostrano come utilizzare tanti strumenti che ANTLR mette a disposizione per "disambiguarla". Me ne sono servito, ad esempio, per riconoscere gli interi (e le percentuali) dai reali, oppure per riconoscere i diversi terminatori di riga (per Windows, Unix, e Macintosh, che usano CR+LF, LF e CR rispettivamente) e per i commenti (sia a singoli che multilinea).

Insomma, per chi è interessato, c'è un bel po' di carne sul fuoco. :p

Fatemi sapere se anche a voi funziona, e magari qualche commento. :)