Wiki
Tools
Categorie
Help
Una pagina a caso
JavaBNF | |
Linguaggio: | Java |
Licenza: | Boh, non ci ho ancora pensato! Cmq se ci fate dei soldi datemente una parte. |
Autore: | Dario |
Questo programma serve per generare dei linguaggi a partire da definizioni scritte secondo una grammatica simil-BNF. Per maggiori informazioni sulla BNF seguire questo link su Wikipedia. Le si studiano sia col Ferrari che col Tetty?.
In poche parole, per chi non la conoscesse già, la Backus-Naur Form è un sistema per specificare un linguaggio, cioè un insieme di parole, a partire da delle regole predeterminate. Una volta specificate delle regole, è possibile generare un insieme di parole che rispettino quelle regole.
Questo programma fa esattemente ciò: si specifica una grammatica, e vengono generati degli insiemi di parole a partire da quella grammatica.
Le regole sono della forma
nomeregola::=produzione
in cui nomeregola è il nome della regola, e produzione è ciò che la regola effettivamente fa.
La produzione a sua volta può contenere il nome di un'altra regola, oppure delle altre parole, o infine dei metacomandi che sono specifici della mia implementazione delle BNF.
Per esempio, posso avere una situazione del genere:
scopo::=$nome $cognome nome::=Dario|Guido|Lara|Patrizia|Teto|Denis cognome::=Woodcock|Myers|Hitchcock|Nelson|Lewis|Hamilton
Partiamo dalla regola chiamata regola. Essa contiene $nome e $cognome. $nome serve al programma per capire che quello che segue potrebbe essere un'altra regola. In questo caso lo è: vede che nome è il nome di un'altra regola, quindi va ad esaminare quella specifica regola.
La regola nome è composta da nomi separati da |. Ciò sta a significare un'alternativa: il programma si trova di fronte a quelle alternative e casualmente ne sceglierà una.
Lo stesso discorso lo si può fare per $cognome e la regola cognome. Come risultato, il programma sceglierà un nome a caso tra quelli indicati da nome e un cognome a caso tra quelli indicati da cognome. Esempi di risultato possono essere Dario Hamilton, Denis Nelson, Patrizia Woodcock e così via.
La regola iniziale ho deciso essere quella che si chiama scopo. Quindi il programma partirà a generare frasi a partire dalla regola chiamata scopo, che sarà valutata per prima.
Una regola può avere una forma del genere:
regola::=alternativa 1 | alternativa 2 | alternativa 3 # finale 1 | finale 2
Il # serve per dividere la regola in due parti: quella che lo precede e quella che lo segue. Posso avere anche più di un # per riga, e ogni # divide la regola in una parte aggiuntiva.
Quello che succede è che il programma prima esamina la parte precedente il #, comprese le alternative, e poi esamina la parte che segue il #, indipendentemente.
L'esempio dei nomi e dei cognomi di prima può essere visto quindi così:scopo::=Dario |Denis |Teto |Patrizia #Woodcock|Hitchcock|Grandmarnier
Anche il $ può servire come separazione, nel caso in cui la parola che lo segue non sia una regola già esistente:
nome::=$quando$visita quando::=pre|post
Non esistendo la regola visita, il programma la interpreta come una parola normale.
Si potrebbe obiettare che il $ quando fa da separatore è come se si sostituisse al #, il cui scopo è proprio fare da separatore.
Invece no, per via delle precedenze. Una regola viene sempre divisa prima in base ai #, ed ogni parte in cui i # la suddividono sarà eseguita sicuramente ed indipendentemente. Poi è la volta dei |, tra cui si sceglie a random, ed infine si passa ad analizzare quello che accade tra i $. Una distinzione che può far comodo nel caso di grammatiche complesse.
Ho inserito per comodità alcuni metacomandi, così per facilitare un pochettino la generazione di testo. Sono tutti introdotti dal $.
$\n
manda a capo
$\t
crea una tabulazione
$MAIUS
rende maiuscolo il prossimo carattere
$MINUS
rende minuscolo il prossimo carattere
Un'altra aggiunta che ho inserito è quella delle variabili.
Se scrivo regole in questo modo:
scopo::=$%nome $%cognome abitava a $%paese#. $restodellafrase nome::=Dario|Denis|Teto cognome::=Johnson|Lancaster|Grant paese::=Somaglia|Casalpusterlengo|Caselle Landi|San Cthulhu|Monte Cremasco restodellafrase::=Il paese di $%paese non piaceva molto a $%nome e alla sua famiglia, i $%cognome#s.
il % dopo il dollaro mi assicura che quello che viene generato appena dopo di lui sarà memorizzato, e ogni volta che richiamerò quella stessa regola con un altro % mi riapparirà lo stesso nome che è stato generato precedentemente. Provare per credere.
È piuttosto facile ed intuitivo, i tooltip spiegano da soli quello che c'è da fare.
Alcune note: per ora, ogni volta che si cercherà di aprire o salvare un file, si tornerà sempre alla cartella in cui è stato salvato il programma. È un comportamento un po' fuori standard, ma non mi crea personalmente molto fastidio.
Inoltre, il programma non ha idea di quale file sia stato aperto in precedenza: ogni volta che si clicca su Salva, viene chiesto un nuovo nome.
Si può scaricare l'eseguibile direttamente o anche l'intero progetto, se volete compilarlo voi.
Alcune grammatiche di esempio.