MOV3D Technical Reference INTRODUZIONE MOV3D e' un programma grafico che permette la gestione di oggetti tridimensionali grazie a un linguaggio di controllo semplice e potente. Il nucleo del linguaggio si basa sui principi del linguaggio PL/0, molto simile al Pascal, descritti nel capitolo 5 del libro di Niklaus Wirth dal titolo 'Algoritmi + Strutture Dati = Programmi'. Il PL/0, come il Pascal, prevede una parte riservata alle dichiarazioni e una per le istruzioni. Prevede l'utilizzo di costanti, variabili e procedure, ma gestisce solo numeri interi, non prevede il passaggio di parametri e non prevede le funzioni. Il linguaggio MOV3D prevede in aggiunta la gestione di numeri in virgola mobile, il passaggio di parametri sia per valore che per indirizzo, l'utilizzo di funzioni ma soprattutto la gestione e la stampa grafica di strutture nello spazio tridimensionale. Dalla lista delle produzioni della grammatica si nota che le definizioni prevedono la ricorsione (per esempio la catena ESPRESSIONE TERMINE FATTORE). E' quindi necessario che il compilatore MOV3D sia scritto in un linguaggio che disponga della ricorsione. Il compilatore Turbo Pascal della Borland oltre a prevedere la ricorsione, possiede anche varie routine per la gestione dello schermo in modo grafico, ed e' per questi motivi che e' stato scelto. FILES SORGENTE Il codice di MOV3D e' stato suddiviso in 6 files .PAS (per un totale di circa 150Kb di codice sorgente) : FILE FUNZIONE run.pas programma principale data.pas unit contenente le strutture di dati globali comp.pas unit compilatore inter.pas unit interprete obj3d.pas unit gestione oggetti 3D trlib.pas unit utility varie PRINCIPIO DI FUNZIONAMENTO GENERALE Il programma MOV3D richiede in ingresso un file contenente il codice in linguaggio MOV3D avente suffisso .PRG . Durante l'esecuzione viene creato un file avente lo stesso nome con suffisso .OUT contenente tutti i passi compiuti durante l'esecuzione. In un primo momento la unit comp.pas compila le istruzioni del file di ingresso trasformandole in codice per un processore ideale che lavora su uno stack. La unit inter.pas e' una implementazione in Turbo Pascal del processore ideale. Sara' quindi questa unit a interpretare le istruzioni compilate, chiamando, se necessario, le routine grafiche presenti nella unit obj3d.pas . STRUTTURE DI DATI Le strutture di dati globali sono inserite nella unit data.pas, mentre le strutture locali sono definite all'interno di ciascuna unit. File data.pas - type TIPI La struttura TIPI e' il veicolo di informazioni piu' usato lungo il programma. E' costituita da una variabile che ne determina il tipo di contenuto. La struttura e' utilizzata principalmente come contenitore di indirizzi, costanti, puntatori. E' utilizzata come elemento di base dello stack dell'interprete, in questo modo gli indirizzi, le costanti e tutti gli altri elementi presenti sullo stack occupano un solo elemento, eliminando i problemi di calcolo delle dimensioni a scapito di un'occupazione maggiore di memoria. La presenza contemporanea di tutti i tipi di variabili in una unica struttura (interi,reali,punti,facce,oggetti 3d) agevola una eventuale estensione dei tipi di variabili. - type ISTRUZIONE E' l'insieme dei simboli associati alle istruzioni del processore ideale. - type COMANDO E' un elemento della lista a puntatori del codice compilato. Contiene il simbolo di una funzione (tipo ISTRUZIONE) e un operando (tipo TIPI). Contiene, ovviamente, anche un puntatore a una stessa struttura per il collegamento all'elemento successivo nella lista (unidirezionale). A ogni elemento della lista e' associato un numero intero a partire dalla prima istruzione compilata (indirizzo). Durante l'interpretazione l'indirizzo dell'istruzione corrente sara' contenuto nella variabile PC (program counter). - var ISTR_P Puntatore al primo elemento della lista. - array ER , RER Sono due array contenenti le stringhe dei messaggi di errore. In ER vi sono i messaggi degli errori di compilazione (circa 60), mentre in RER vi sono i messaggi degli errori run-time (circa 10). Il sistema di rivelazione degli errori prevede l'uscita immediata dal programma in caso di errore. Prima di uscire viene stampato il messaggio di errore sia sullo schermo che nel file .OUT . Il file .OUT rappresenta uno strumento di debugging molto particolareggiato. File comp.pas - type SIMBOLI A ognuno di questi simboli verra' associata o una parola riservata o un carattere speciale. - type OGGETTO E' l'insieme di simboli associati alle varie entita' costituenti i programmi (costanti,variabili,funzioni,procedura,parametri). - type TAB E' l'elemento base dell'albero a puntatori degli oggetti dichiarati. Ogni elemento di questo albero contiene un oggetto dichiarato (vedi tipo OGGETTO). Ogni elemento contiene la stringa dell'identificatore dell'oggetto, il livello di profondita' nell'albero e in piu', a seconda del tipo di oggetto: costante: valore della costante (intera o reale); variabile,parametro: tipo della variabile e indirizzo di offset; procedura: indirizzo iniziale del codice; funzione: indirizzo iniziale del codice e tipo del risultato. Ogni elemento contiene anche 3 puntatori (pl,pr,pd) per realizzare la struttura ad albero a doppia catena. Questa struttura e' caratterizzata dal fatto che da ogni punto dell'albero si puo' arrivare a tutti gli altri. Il principio di costruzione utilizzato prevede che se si crea una procedura tutti i suoi parametri vengono collegati in lista al puntatore pd (la lista di oggetti allo stesso livello e' costruita in modo che pr punti all'oggetto a destra e pl a quello a sinistra). Esempio di struttura: liv ---------- ---------- ---------- ---------- | proc | | proc | | func | | proc | |--------| |--------| |--------| |--------| ..--|pl|pd|pr|---><---|pl|pd|pr|--....--|pl|pd|pr|--....--|pl|pd|pr|-->NIL ---------- ---------- ---------- ---------- ^ | | | liv+1 | | ---------- ---------- ---------- ---------- | \-->| param | | param | | var | | proc | | |--------| |--------| |--------| |--------| \-----|pl|pd|pr|---><---|pl|pd|pr|--....--|pl|pd|pr|--....--|pl|pd|pr|.. ---------- ---------- ---------- ---------- | | | | NIL NIL NIL | liv+2 - array PAROLA Array contenente le stringhe delle parole riservate. - array SIMP Array contenente i simboli associati alle parole riservate. - array SIMS Array contenente i simboli associati ai caratteri. - array MNEMONICO Array contenente le stringhe delle istruzioni mnemoniche per il processore ideale. - var LAST_PUNT Puntatore all'ultimo elemento aggiunto all'albero. - var SIM Ultimo simbolo letto. File inter.pas - type STACK Elemento dello stack dell'interprete. Contiene, oltre al puntatore all'elemento seguente, una variabile di tipo TIPI in grado di contenere indirizzi, costanti, e collegamenti dinamici e statici per ogni procedura attivata. La catena dei puntatori e' costruita in modo che l'ultimo elemento creato punti al penultimo e cosi' via (unidirezionale), e' quindi necessario avere un puntatore all'ultimo elemento aggiunto. A ogni elemento e' associato un numero intero crescente a partire dal primo. - var P_TOP Puntatore all'ultimo elemento aggiunto allo stack. - var SP Numero associato all'ultimo elemento dello stack. - var PC Nella procedura interprete e' il numero associato all'istruzione di codice compilato attualmente in esecuzione. - var BASE Nella procedura interprete e' il numero associato all'elemento dello stack in cui iniziano i dati di link dinamico e statico della procedura corrente. - var LEVEL Nella procedura interprete e' il livello della procedura attualmente in esecuzione. File obj3d.pas - type POINT Punto tridimensionale costituito dalle coordinate x,y,z. - type FACE Faccia tridimensionale, cioe' un triangolo nello spazio. Per determinarla sono necessari 3 punti 3D. Contiene anche una word per il colore interno, e altre 3 per i colori di ciascun lato del triangolo. - type OBJECT Oggetto tridimensionale costituito da un'insieme di triangoli 3D. I triangoli costituiscono una lista a puntatori collegata alla variabile pf. La posizione dell'oggetto nello spazio e' contenuta nel punto p. Tutte le coordinate dei triangoli di un oggetto si ritengono riferite al sistema di riferimento che ha origine in p. In questo modo e' estremamente semplice traslare un oggetto in qualsiasi direzione dello spazio. Sono previste anche alcune variabili per la rotazione dell'oggetto attorno a un asse (tipo ROT). E' presente anche la variabile di tipo boolean vis che permette di rendere invisibile un oggetto, cioe' di non considerarlo durante la stampa. - var OBJ_PNT E' un puntatore alla catena di oggetti da stampare. Infatti la procedura di stampa considera solo gli oggetti presenti nella catena bidirezionale puntata da obj_pnt. - var OBS_LOC Punto 3D che individua il luogo dell'osservatore. - var OBS_LOOKAT Punto 3D dove l'osservatore guarda. - type EL All'interno della procedura draw e' l'elemento costituente l'array T. - array T All'interno della procedura draw contiene i dati principali di ogni faccia (triangolo) da stampare. In un primo tempo vengono visitati tutti gli oggetti della lista puntata da obj_pnt e viene calcolata per ogni faccia la distanza del suo baricentro dall'osservatore. Successivamente la distanza e alcune variabili che contengono la posizione della faccia in memoria, vengono memorizzate in questo array. A questo punto viene attivata una procedura di sort (Quick Sort) che riordina l'array in base alla distanza. In questo modo percorrendo l'array nella direzione delle distanze decrescenti si stampano tutti i triangoli da quello avente il baricentro piu' lontano a quello piu' vicino. L'effetto finale non e' sempre perfetto in quanto si tiene conto di un solo punto per ogni triangolo. DESCRIZIONE DELLE PROCEDURE File comp.pas Contiene il compilatore del linguaggio MOV3D. La struttura delle procedure del compilatore e' ricorsiva in modo da avere una corrispondenza fra simboli non terminali e procedure. E' quindi molto facile riconoscere le procedure corrispondenti a ogni produzione della grammatica. Le procedure di compilazione utilizzano la procedura LEGGISIM per la lettura del file contenente il programma da compilare. Questa procedura costituisce un filtro in grado di riconoscere le parole chiave, i numeri interi e f.p., gli identificatori e i caratteri speciali saltando gli spazi e gli eventuali commenti racchiusi tra parentesi graffe. Durante la compilazione le procedure di questo file generano un file di uscita sul quale vengono riportati tutti i passaggi di compilazione. Le procedure di compilazione creano un albero a puntatori contenente tutte le risorse dichiarate nel programma compilato. La procedura principale e' COMPILA che inizializza l'albero delle risorse e inizia la compilazione partendo dallo scopo della grammatica (vedi nelle produzioni) che prevede la parola riservata PROGRAM seguita dal nome del programma. Le procedure BLOCCO, ISTRUZIONE, ESPRESSIONE, CONDIZIONE, FATTORE, TERMINE seguono esattamente le regole di produzione omonime. Le procedure ESPRESSIONE, FATTORE e TERMINE trasformano la notazione infissa in postfissa semplicemente generando prima le istruzioni di caricamento sullo stack degli operandi e poi generando l'istruzione corrispondente all'operatore. procedure leggica Legge un carattere alla volta dal file di input saltando gli end of line e verificando l' EOF (il risultato e' nella variabile globale ca). procedure leggisim Legge il simbolo seguente dal file di input e lo stampa nel file output; la variabile sim contiene il tipo di simbolo letto; un simbolo puo' essere: - una parola chiave; - un identificatore; - un carattere speciale o di punteggiatura; - un numero intero o f.p. (in questo caso il valore del numero e' disponibile in una di queste variabili: Numint , Numflp ). procedure gen Aggiunge una istruzione compilata alla lista dei codici compilati. procedure verifica Verifica se il simbolo attuale appartiene all'insieme dei simboli seguenti. procedure blocco Compila la parte delle dichiarazioni delle risorse e chiama la procedura ISTRUZIONE per la parte delle istruzioni. function ric Ricerca un oggetto nell'albero nell'insieme di visibilita' della procedura puntata da pproc. function ric_dup Ricerca eventuali oggetti con lo stesso identificatore allo stesso livello dell'oggetto in fase di dichiarazione. function ver_parent Verifica la parentela diretta in caso di assegnamento a identificatore di funzione; infatti il valore di una funzione si puo' assegnare solo se l'istruzione e' contenuta all'interno della funzione o in una delle procedure al suo interno. procedure open_lib Interruzione della compilazione del file input per passare a una libreria. procedure close_lib Ritorno al file input principale (allo stesso punto), dopo aver compilato una libreria. procedure installa Installazione e calcolo indirizzi di un oggetto. procedure leggidichiarapar Lettura di una dichiarazione di parametri di una procedura o funzione. procedure gen_var_loc Genera le istruzioni per allocare spazio per le variabili locali di una procedura. procedure stampacodice Stampa sul file di output i codici mnemonici e gli argomenti delle istruzioni compilate nel blocco della procedura corrente. procedure leggiparam Legge i parametri di una procedura o funzione nel caso di una sua attivazione. procedure leggipoint Leggi un tipo punto: cioe' o un identificatore di una variabile di tipo punto o la terna di espressioni (x,y,z). procedure leggiface Leggi un tipo faccia: cioe' o un identificatore di faccia oppure i tre vertici e i colori. procedure leggiobject Leggi un tipo oggetto: cioe' o un identificatore di oggetto oppure tutti gli elementi che compongono un oggetto (punto di riferimento, asse e angolo di rotazione, flag di visibilita' e lista delle facce). File inter.pas La procedura principale del file e' INTERPRETA. Essa infatti costituisce il nucleo dell'interprete contenuto in questo file. In ogni ciclo di istruzione aggiorna i registri di controllo e chiama la procedura corrispondente all'istruzione da eseguire. Infatti a ogni tipo istruzione corrisponde una procedura che ne svolge le funzioni. Le istruzioni lavorano su uno stack grazie a una serie di procedure che gestiscono l'accesso allo stack. La lettura e la scrittura di un elemento dello stack non e' limitata al solo all'elemento in cima, ma si puo' effettuare su qualsiasi elemento interno in base al suo indirizzo. procedure push Aggiunta di un elemento in cima allo stack. procedure pop Preleva l'ultimo elemento sullo stack. procedure set_el Modifica di un elemento interno allo stack. procedure get_el Lettura di un elemento interno allo stack. function get_liv Restituisce il livello della procedura corrente. procedure to_float Trasforma il numero x in un float se d e' un float. procedure direct_load Caricamento diretto sullo stack di un numero o di un indirizzo. procedure allocate Alloca lo spazio sullo stack per una variabile o per il link dinamico e l'indirizzo di ritorno. procedure load Carica una variabile tramite il suo indirizzo di offset e livello. procedure store Memorizza il contenuto di una variabile nella sua posizione nello stack individuata dall'indirizzo di offset e dal livello. procedure jump Salto incondizionato. procedure jump_cond Salto condizionato dall'ultimo valore inserito sullo stack. procedure call Attivazione di una procedura. procedure return Ritorno da una call. procedure operation Insieme di operazioni predefinite, alcune utilizzate solo in questo programma altre utilizzabili dalle librerie tramite l'istruzione OPR. function conv Se uno dei due numeri x o y e' di tipo float allora viene convertito anche l'altro in float e ritorna true, altrimenti false. function ver_in Verifica se n e' compreso tra n1 e n2. Seguono poi le procedure che lavorano prelevando gli operandi dallo stack (pop) e riponendo i risultati ancora sullo stack. Le procedure per le operazioni elementari trasformano il risultato in un float se almeno un dei due operandi e' di quel tipo, altrimenti il risultato rimane di tipo intero. procedure meno Moltiplica l'ultimo numero sullo stack (pop) per -1 riponendo il risultato ancora sullo stack (push). procedure somma Preleva dallo stack gli ultimi due numeri, li somma e ripone il risultato ancora sullo stack. procedure differenza Differenza di due numeri (il penultimo meno l'ultimo sullo stack). procedure prodotto Prodotto dei due numeri sullo stack. procedure quoziente Quoziente tra due numeri sullo stack (il penultimo fratto l'ultimo) (risultato sempre float). procedure uguale Test x=y tra due numeri sullo stack (x=penultimo y=ultimo). procedure diverso Test x<>y tra due numeri sullo stack (x=penultimo y=ultimo). procedure minore Test x=y tra due numeri sullo stack (x=penultimo y=ultimo). procedure maggiore Test x>y tra due numeri sullo stack (x=penultimo y=ultimo). procedure minore_uguale Test x<=y tra due numeri sullo stack (x=penultimo y=ultimo). procedure to_point Crea un punto in memoria HEAP prelevando le coordinate dallo stack nell'ordine z,y,x e inserisce un suo puntatore sullo stack. procedure to_face Crea una faccia in memoria HEAP prelevando i dati dallo stack e inserisce un suo puntatore sullo stack. procedure to_obj Crea un oggetto in memoria HEAP prelevando i dati dallo stack e inserisce un suo puntatore sullo stack. Seguono poi le procedure utilizzabili all'esterno le cui descrizioni si trovano nei file libreria MATH.LIB e OBJ.LIB. File data.pas Questo file contiene le procedure globali utilizzate da tutti gli altri file. procedure info Stampa l'info. procedure termina Ritorna al dos a causa di un errore. procedure errore Stampa codice e stringa di un errore di compilazione. procedure runerror Stampa codice e stringa di un errore run-time. procedure add_com Aggiunge un elemento alla lista dei codici compilati. function goto_n Restituisce il puntatore all'elemento della lista a cui e' associato il numero passato come parametro. function get_dat Restituisce l' argomento dell' n-esima istruzione della lista. function get_funz Restituisce il tipo dell' n-esima istruzione della lista. function get_ist Restituisce il tipo e l'argomento dell' n-esima istruzione della lista. procedure set_ind Modifica la parte indirizzo dell'argomento dell' n-esima istruzione della lista. File obj3d.pas Le procedure di questo file sono indipendenti dai dati e dalle procedure negli altri file. Esse gestiscono gli oggetti tridimensionali. La procedura principale e' DRAW, che stampa sullo schermo grafico tutti gli oggetti 3D. function distanza Calcola la distanza tra due punti. procedure Pol_Cart Trasforma coordinate polari in cartesiane. procedure Cart_Pol Trasforma coordinate cartesiane in polari. procedure somma Somma ordinata delle coordinate di 2 punti. procedure calc_coord Calcolo delle coordinate assolute di un punto in un oggetto 3D. procedure rotazione Calcolo della rotazione di un punto. procedure baricentro Calcolo delle coordinate del baricentro di una faccia. procedure posiz Calcolo delle coordinate grafiche di un punto dalle sue coordinate assolute. function init_graph Inizializzazione schermo grafico. procedure init_point Allocazione nell' HEAP di un punto. procedure init_face Allocazione nell' HEAP di una faccia. procedure init_obj Allocazione nell' HEAP di un oggetto. procedure quit_point Deallocazione di un punto. procedure quit_face Deallocazione di una faccia. procedure quit_obj Deallocazione di un oggetto. procedure link_obj Inserimento di un oggetto nella lista oggetti. procedure unlink_obj Disinserimento di un oggetto dalla lista oggetti. function copy_point Copia di un punto. function copy_face Copia di una faccia. function copy_obj Copia di un oggetto. procedure set_coord Modifica di una coordinata di un punto. procedure set_point Modifica di un punto di una faccia. function get_coord Ritorna una coordinata di un punto. procedure get_point Ritorna un punto di una faccia. function ric_face Ricerca della faccia n-esima in un oggetto; ritorna il puntatore alla faccia se esiste, altrimenti ritorna NIL. function get_num_face Ritorna il numero di facce di un oggetto. procedure add_face Aggiunge una faccia a un oggetto in coda alla lista. function set_face Modifica l' n-esima faccia dell' oggetto. function del_face Cancella l' n-esima faccia dell'oggetto. function get_face Ritorna l' n-esima faccia dell'oggetto. procedure move Cambia il valore del punto di riferimento dell'oggetto. procedure move_rel Aggiunge un valore al punto di riferimento dell'oggetto. procedure get_pos Ritorna il punto di riferimento dell'oggetto. procedure rotate Modifica l'angolo di rotazione dell'oggetto. procedure rotate_rel Incrementa l'angolo di rotazione dell'oggetto. procedure get_rot Ritorna l'angolo di rotazione dell'oggetto. procedure set_vis Modifica il flag di visibilita' dell'oggetto. function get_vis Ritorna il flag di visibilita' dell'oggetto. procedure set_side Modifica il colore di un lato di una faccia. function get_side Ritorna il colore di un lato di una faccia. procedure set_color Modifica il colore di una faccia. function get_color Ritorna il colore di una faccia. procedure set_color_obj Modifica il colore di tutte le facce di un oggetto (esclusi i lati). procedure set_side_obj Modifica il colore di tutti i lati di tutte le facce di un oggetto. procedure set_bk_color Modifica il colore di background. function get_bk_color Ritorna il colore di background. procedure set_obs Modifica i punti di osservazione e dell'osservatore. procedure get_obs Ritornano i punti di osservazione e dell'osservatore. procedure draw Stampa tutti gli oggetti nella lista. 1) scansione di tutte le facce di tutti gli oggetti nella lista, calcolo delle distanze dei loro baricentri dall'osservatore e inserimento in un array di: - puntatore all' oggetto a cui appartiene la faccia; - distanza del baricentro della faccia dall'osservatore; 2) QuickSort dell'array in base alle distanze in ordine crescente; 3) stampa delle facce dalla piu' lontana alla piu' vicina. function scan Scansione facce, calcolo distanza, inserimento in array. procedure QuickSort QuickSort in ordine di distanza crescente. procedure stampa Stampa in modo grafico delle facce ordinate dalla piu' lontana alla piu' vicina. MESSAGGI E CODICI DI ERRORE Errori di compilazione 1 Sostituire := con = 2 Atteso numero 3 Atteso = 4 Atteso identificatore (dichiarazione) 5 Attesa , o ; 6 Simbolo scorretto dopo dichiarazione di procedura o funzione 7 Attesa istruzione 8 Simbolo scorretto dopo la parte istruzione di un blocco 9 Atteso . 10 Atteso ; tra due istruzioni 11 Identificatore non dichiarato 12 Assegnamento a costanti,procedure o funzioni non permesso 13 Atteso := 14 CODICE ANNULLATO (Atteso identificatore) 15 CODICE ANNULLATO (Chiamata di costante o variabile non permessa) 16 Atteso THEN 17 Atteso ; o END 18 Atteso DO 19 Simbolo scorretto dopo un'istruzione 20 Atteso operatore relazionale 21 Identificatore di procedura non permesso in un'espressione 22 Attesa ) 23 Il fattore precedente non puo'essere seguito da questo simbolo 24 Un'espressione non puo' iniziare con questo simbolo 25 Attesa cifra 26 Attesa , 27 Atteso ; 28 NON USATO 29 NON USATO 30 CODICE ANNULLATO (Numero troppo grande) 31 Attesi : 32 Atteso identificatore di tipo 33 Attesa parte decimale 34 Atteso segno dell'esponente 35 Atteso esponente 36 CODICE ANNULLATO (Esponente troppo grande) 37 I parametri passati per valore possono essere solo numeri 38 Atteso parametro 39 I parametri passati per indirizzo non possono essere costanti,procedure o funzioni 40 Attesa ( 41 Tipo errato 42 Non e' possibile inglobare librerie in una libreria 43 Identificatore duplicato 44 Atteso nome di libreria 45 Variabile di tipo non permesso in un'espressione 46 Atteso PROGRAM 47 Non e' possibile assegnare una procedura 48 Attesa definizione di POINT 49 Attesa definizione di FACE 50 Attesa definizione di OBJECT 51 Attesa espressione di tipo INTEGER 52 Atteso LIBRARY 53 PROGRAMMA INCOMPLETO 54 LIVELLO OGGETTO TROPPO ALTO 55 MEMORIA (HEAP) INSUFFICIENTE 56 PROGRAMMA TROPPO LUNGO 57 Non si puo' assegnare il valore di una funzione esternamente al suo blocco 58 Atteso UNTIL 59 Codice operazione errato Errori run-time 1 STACK OVERFLOW 2 MEMORIA (HEAP) INSUFFICIENTE 3 Divisione per zero 4 Argomento del logaritmo minore o uguale a zero 5 Argomento radice negativo 6 Codice colore errato 7 Numero di coordinata non compreso fra 1 e 3 8 Numero di vertice non compreso fra 1 e 3 9 Numero di lato non compreso fra 1 e 3 10 Numero di faccia non compreso fra 1 e lunghezza della lista di facce 11 Scheda grafica o driver non presente PRODUZIONI DELLA GRAMMATICA MOV3D Simbologia della notazione: ( ) racchiudono un sottoinsieme di simboli; [ ] racchiudono un sottoinsieme di simboli che puo' essere saltato; + indica che il sottoinsieme a sinistra puo' essere considerato una o piu' volte; | separa diverse possibilita'; < > racchiudono il nome di un simbolo non terminale (in lettere maiuscole); eventuali commenti sul simbolo non terminale sono presenti all'interno di parentesi tonde; = separa un simbolo non terminale dalla sua definizione. Tutti i restanti caratteri, comprese le lettere minuscole e le cifre, sono simboli terminali; in piu' lo sono anche: '(' ')' '<' '>' '[' ']' '|' '=' ':=' '+' 'E' Produzioni del linguaggio MOV3D : = program ; . = [ const ( '=' ; )+ ] [ var ( : [ , ]+ ; )+ ] [ lib ; ]+ ( [ procedure ; ; ] [ function : ; ; ] )+ = library ( ( procedure ; ; ) | ( function : ; ; ) ) ( [ procedure ; ; ] [ function : ; ; ] )+ end . = ( ':=' ) | ( ':=' ) | ( ':=' ) | ( ':=' ) | ( ) | ( if then else ) | ( begin [ ; ]+ end ) | ( while do ) | ( repeat [ ; ]+ until ) | ( opr '(' ')' ) = [ '(' [var] [ , ]+ [ ; [var] [ , ]+ ]+ ')' ] = [ '(' ( | | | | ) [ , ( | | | | ) ]+ ')' ] = | ( '(' , , , , [ , '(' ( [,] )+ ')' ] ')' ) = | ( '(' , , , , '(' , , ')' ')' ) = | ( '(' , , ')' ) = ( '=' | '|' | '<' | '>' | '[' | ']' ) = ['+'|-] [ ('+'|-) ]+ = [ (*|/) ]+ = | ) | | | ( '(' ')' ) = [-] ( | ) = [ . ] [ ('E'|e) ('+'|-) ] = + = [ | ]+ = a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z = 0|1|2|3|4|5|6|7|8|9