• Save
UnimiB :: Informatica LT2 :: Linguaggi e Computabilità :: Esercitazioni
Upcoming SlideShare
Loading in...5
×
 

UnimiB :: Informatica LT2 :: Linguaggi e Computabilità :: Esercitazioni

on

  • 1,463 views

Grammatiche Formali ed Elementi di Compilatori e Linguaggi d Marcatura (v. 5)

Grammatiche Formali ed Elementi di Compilatori e Linguaggi d Marcatura (v. 5)

Statistics

Views

Total Views
1,463
Views on SlideShare
584
Embed Views
879

Actions

Likes
0
Downloads
0
Comments
0

2 Embeds 879

http://elearning.unimib.it 877
https://www.facebook.com 2

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

CC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike LicenseCC Attribution-NonCommercial-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • La cardinalità di alpha |alpha| = 1

UnimiB :: Informatica LT2 :: Linguaggi e Computabilità :: Esercitazioni UnimiB :: Informatica LT2 :: Linguaggi e Computabilità :: Esercitazioni Presentation Transcript

  • Linguaggi e Computabilità Esercitazioni A. A. 2013-14 Applicazioni delle Grammatiche Formali Dott. Ing. Federico Cabitza, PhD cabitza@disco.unimib.it Stanza 2063 II p. U 14 ricevimento su appuntamento
  • Cosa c‟è di più meraviglioso e sorprendente della Vita?
  • Sintesi proteica: Quattro basi azotate. Un meccanismo di trascrizione. View slide
  • Nel ‟56 un ragazzo di 28 anni rimase colpito anche da un altro fenomeno… View slide
  • Come fa un bambino di due, tre anni ad imparare così velocemente a parlare…
  • Come fa un bambino di due, tre anni ad imparare così velocemente a parlare… … nonostante i genitori gli parlino tutto il tempo in “motherese”!
  • Marx Lenin Shakespeare La Bibbia Cicerone Freud Hegel Platone Aristotele e…
  • Marx Lenin Shakespeare La Bibbia Cicerone Freud Hegel Platone Aristotele e… Noam Chomsky (1928)
  • L‟idea di una grammatica universale.
  • L‟idea di una grammatica universale e innata. <sentence> → <subject> <predicate> <period> <subject> → <noun> <predicate> → <intransitive verb> <predicate> → <transitive verb> <object> <object> → <noun> <noun> → Mary <noun> → John <intransitive verb> → believes <transitive verb> → likes <transitive verb> → believes <period> → .
  • Ma cos‟è una grammatica? (ai nostri scopi)
  • Ma cos‟è una grammatica? α→β
  • Ma cos‟è una grammatica? α→β Poche regole come questa, che generano tutto ciò che può essere detto o scritto (linguaggi)
  • Grammatica formale generativa: L‟idea di una grammatica universale. Formalismo che descrive e genera tutti i linguaggi, sia umani, che di macchine e di cyborg… Ma cos‟è una grammatica? α→β αeβ sono stringhe di simboli (non vuote).
  • α→β
  • α→β αAβ → αγβ
  • α→β αAβ → αγβ A→γ
  • α→β αAβ → αγβ A→γ A → a|aB|ϵ
  • α→β αAβ → αγβ A→γ A → a|aB|ϵ Tipo 2 Tipo 3 Tipo 0 Tipo 1
  • α→β αAβ → αγβ A→γ A → a|aB|ϵ unrestricted0 Tipo Sensibili 1 Tipo al contesto Tipo Context free 2 (ma con una condizione in più ;) regolari Tipo 3 tutti
  • α→β αAβ → αγβ A→γ A → a|aB|ε  α, β, γ: stringhe di simboli ϵ (T U V)* | α| ≤ | β|  AϵV  aϵ T
  • E’ una quadrupla:  T alfabeto terminale di token di un linguaggio,  V, insieme di simboli non terminali, o metaL‟idea di una grammatica universale. variabili che rappresentano costrutti sintattici (e.g., espressioni, statements, assignments)  S, simbolo di start o simbolo linguaggio Ma cos‟è una grammatica?  P, insieme di produzioni (o regole di riscrittura) del tipo: α→β
  • E’ una quadrupla:  T alfabeto terminale di token di un linguaggio,  V, insieme di simboli non terminali, o metaL‟idea di una grammatica universale. variabili che rappresentano costrutti sintattici (e.g., espressioni, statements, assignments)  S, simbolo di start o simbolo linguaggio Ma cos‟è una grammatica?  P, insieme di produzioni (o regole di riscrittura) del tipo: α→β  α ϵ V, β ϵ (T U V)*, …?
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {a, b, c…, z } L‟idea di una grammatica universale. Ma cos‟è una grammatica?
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {a, b, c…, z } L‟idea di una grammatica universale.  Stringa: Ma cos‟è una grammatica? una sequenza finita (anche vuota, ε) di simboli dell‟alfabeto. (e.g., “parole”)
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {a, b, c…, z } L‟idea di una grammatica universale.  Stringa: Ma cos‟è una grammatica? una sequenza finita (anche vuota, ε) di simboli dell‟alfabeto. (e.g., “parole”)  Linguaggio: Un insieme (anche vuoto od infinito) di stringhe, sottoinsieme di T* (chiusura di Kleene di T, cioè l‟insieme di tutte le stringhe finite, che si formano concatenando zero o più
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {„try‟, „catch‟, „if‟, „else‟, … } L‟idea di una grammatica universale. Grammatica come descrizione/specifica finita di un linguaggio (per non dover enumerare…).  Stringa: Ma cos‟è una grammatica? una sequenza finita (anche vuota) di simboli Anche come formalismo che genera un linguaggio dell‟alfabeto attraverso le sue produzioni. (“parole”). (e.g., “parole)  Linguaggio: Un insieme (anche vuoto od infinito) di stringhe, sottoinsieme di T*
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {„try‟, „catch‟, „if‟, „else‟, … } L‟idea di una grammatica universale.  Stringa: siamo interessati ai Linguaggi Noi Ma cos‟è una grammatica? una sequenza finita (anche vuota) diG, L(G): generati da una Grammatica simboli dell‟alfabeto (“parole”). ϵ T*, S =>* s} L(G) = {s | s (e.g., “parole” o “programmi”) dove =>* indica una derivazione, cioè una sequenza di riscritture (in questo caso dalla forma sentenziale S alla sentenza s). Linguaggio:  p.s. la sentenza è una forma sentenziale formata da soli terminali Un insieme (anche vuoto od infinito) di stringhe,sottoinsieme di T*
  • Embè?!
  • L‟idea delle grammatiche formali generative di linguaggi sono alla base della nostra società moderna basata sui calcolatori.
  • Ci permettono di: tradurre un programma da un linguaggio ad un altro (e.g., compilazione).
  • Ci permettono di: tradurre un programma da un linguaggio ad un altro (e.g., compilazione). descrivere un documento elettronico.
  • Ci permettono di:  tradurre un programma da un linguaggio ad un altro (e.g., compilazione). Sono usate nel componente di un compilatore detto parser, per capire se un programma è legale in un certo linguaggio e (ri)costruirne la struttura sintattica.  descrivere un documento elettronico.  Sono usate in un DTD per specificare classi di documenti XML nella comunicazione tra macchine (e.g., server e client Web)
  •  Alfabeto: insieme finito e non vuoto di simboli. T = {„try‟, „catch‟, „if‟, „then‟, „else‟, … L‟idea di una grammatica universale. }  Stringa: Ma cos‟è una grammatica? una sequenza finita (anche vuota) di simboli dell‟alfabeto. (e.g., “parole” “programmi”, “documenti”)
  • L‟idea di una grammatica universale. Ma cos‟è una grammatica? Ogni linguaggio di programmazione è caratterizzato da due grammatiche.
  • L‟idea di una grammatica universale. Ma cos‟è una grammatica? Ogni linguaggio di programmazione è caratterizzato da due grammatiche. Una grammatica lessicale (o morfologica), che trasforma dai simboli di T (charset UNICODE) agli “input elements” o tokens.
  • identifiers (e.g., variabili, costanti), keywords (nomi riservati: new, for if,...), literals L‟idea di una grammatica universale. (valori assegnati alle variabili), separators ((,),{,},[,],;,.,,), Ma cos‟è una grammatica? operators (=, >,!,~,?,:,==,!=,&&, ...) Ogni linguaggio di programmazione è caratterizzato da due grammatiche. Una grammatica lessicale (o morfologica), che trasforma dai simboli di T (charset UNICODE) agli “input elements” o tokens.
  • L‟idea di una grammatica universale. Ma cos‟è una grammatica? Ogni linguaggio di programmazione è caratterizzato da due grammatiche. Una grammatica sintattica (phrase structure g.) che trasforma dai token in T a tutti i possibili programmi legali (ma non necessariamente funzionalmente corretti…).
  • Ad esempio, per JAVA “S” è denotato come L‟idea di una grammatica universale. “compilation unit”… ;) Ma cos‟è una grammatica? Ogni linguaggio di programmazione è caratterizzato da due grammatiche. Una grammatica sintattica (phrase structure g.) che trasforma dai token in T a tutti i possibili programmi legali (ma non necessariamente funzionalmente corretti…).
  • Sia tradurre programmi software che abilitare la comunicazione tra macchine richiede di verificare la sintassi, cioè la  legalità di una sentenza (stringa generata a partire da una grammatica = programma) per un compilatore.  validità di un documento (che sia well formed e conforme ad un DTD).
  • Il primo problema che ci poniamo è quindi questo: la sentenze „X = 1‟ e „x = for 1‟ sono legali*, ad esempio, in C o in Java? *: corrette sintatticamente: verrebbero compilate? Verrebbero eseguite?
  • Le nostre grammatiche (context-free) saranno una cosa del genere: program → statements ‘.’ statements → statement ‘;’ statements statements → statement statement → ID ‘=‘ expression expression → NUM expression → expression ‘+’ NUM
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2.’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Tale derivazione è associata al seguente parse tree (albero sintattico concreto):
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2.’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5, cioè: Tale derivazione è associata al seguente parse tree (albero sintattico concreto): program => statements. => statement. => ID = expression. => ID = expression + NUM. => ID = NUM + NUM.
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2.’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5, cioè: Tale derivazione è associata al seguente parse tree (albero sintattico concreto): program => statements. => statement. => ID = expression. => ID = expression + NUM. => ID = NUM + NUM.
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2.’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto):
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS STATEMENT EXPRESSION EXPRESSION ID (a) = NUM (1) + NUM (2) .
  • Vi ricordate cos‟è un albero, vero?
  • Un grafo aciclico diretto (orientato) con relazione di precedenza (discendenza) in cui un solo nodo non ha padre (la radice/root) e tutti gli altri nodi hano un solo padre, zero o più figli, a cui è collegato sempre e solo con un arco.
  • Se l‟albero è sintattico: ogni foglia è etichettata con un token o ε. il suo prodotto è una sentenza. ogni nodo interno è etichettato con una meta-variabile. ogni nodo interno è la testa di una (sola) produzione e i suoi figli formano il corpo della produzione (se letti da sinistra a destra).  la radice è etichettata con il simbolo start, S.      rappresenta la derivazione da S alla sentenza secondo G.  rappresenta la struttura sintattica della sentenza secondo G.  è l‟output di un parser (parse tree).
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS .
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS STATEMENT .
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS STATEMENT EXPRESSION ID (a) = ;
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS STATEMENT EXPRESSION EXPRESSION ID (a) = + NUM (2) .
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS STATEMENT EXPRESSION EXPRESSION ID (a) = NUM (1) + NUM (2) .
  • 1 program → statements ‘.’ 2 statements → statement ‘;’ statements 3 statements → statement 4 statement → ID ‘=‘ expression 5 expression → NUM 6 expression → expression ‘+’ NUM Come arriviamo a scrivere ‘ID = NUM + NUM.’ (che è la stringa associata alla istruzione o stream di caratteri ‘a = 1 + 2. ’) applicando le regole della grammatica sopra riportata? Con una derivazione: sequenza di riscritture attuate, nell’ordine, dalle produzioni 1, 3, 4, 6 e 5. Ogni derivazione può essere rappresentata per mezzo di un albero sintattico (concreto): PROGRAM STATEMENTS Esempio di top-down parsing. STATEMENT EXPRESSION EXPRESSION ID (a) = NUM (1) + NUM (2) .
  • Per il progetto dovrete realizzare un “scatola”…
  • Per il progetto dovrete realizzare un “scatola”… … ovviamente che produca un output a fronte di un input in ingresso!
  • Cosa c‟è dentro questa scatola? IN LEXER ID = NUM + NUM; PARSER OUT
  • a = 1 + 2; LEXER ID = NUM + NUM; PARSER
  • a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) uno stream di token (codice tokenizzato) PARSER Analizzatore sintattico parse tree (codice parsato)
  • Produzioni di una grammatica Context-Free Espressioni regolari a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) uno stream di token (codice tokenizzato) PARSER Analizzatore sintattico parse tree (codice parsato)
  • riconoscitori di Espressioni di un stringhe regolari linguaggio regolare a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) uno stream di token (codice tokenizzato) Produzioni di una grammatica Context-Free PARSER Analizzatore sintattico parse tree (codice parsato)
  • riconoscitori di Espressioni di un stringhe regolari linguaggio regolare a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) Produzioni di una grammatica Context-Free PARSER I lexemi sono stringhe che “mecciano” il pattern di un token, e quindi sono identificati uno stream Analizzatore come istanze del token. di token sintattico Tale “pattern” è una funzione che ci dice (codice quando una stringa rappresenta parse tree un token. tokenizzato) (codice Per noi sono espressioni regolari. parsato)
  • riconoscitori di Espressioni di un stringhe regolari linguaggio regolare a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) Produzioni di una grammatica Context-Free PARSER Un token è una singola entità logica sintattica; anche, classe di lexemi che sono uno stream Analizzatore riconosciuti dallo stesso pattern, regex. di token sintattico Concretamente una coppia chiave (nome, o (codice parse tree ID), tokenizzato) valore (opzionale, solitamente un (codice numero o codice numerico). parsato)
  • riconoscitori di Espressioni di un stringhe regolari linguaggio regolare a = 1 + 2; uno stream di caratteri (codice sorgente) LEXER ID = NUM + NUM; Analizzatore lessicale (scanner) che fa SPLITTING (riconosce i lexemi) ed EVALUATION (crea coppie lexemi e token) Produzioni di una grammatica Context-Free PARSER Quindi un lexer crea accoppiamenti lexema – token del tipo: uno stream ‘if’ -> Analizzatore IF di token sintattico ‘<=‘ -> COMPARISON (codice ‘score’ -> ID parse tree tokenizzato) ‘6.2’ -> NUM (codice (isomorfismi tra un alfabeto e un altro) parsato)
  • a = 1 + 2; LEXER ID = NUM + NUM; PARSER Questo parser (ocio alla sineddoche) è solo una parte di un compilatore, ma è tra le più importanti. Ecco perché è una sineddoche!
  • LINERECONSTRUCTION PARSER LEXER SEMANTIC CHECKER PP PARSER CODE GENERATOR
  • LINERECONSTRUCTION Prepara l’ingresso per l’analisi lessicale (stropping, sigilling) PARSER LEXER PARSER Riconosce i token e ricostruisce la struttura sintattica del codice in ingresso (parse tree) SEMANTIC CHECKER Arricchimento del parse tree, Type checking, object binding, inizializzazione variabili, costruzione della symbol table PP CODE GENERATOR Depth first analysis del parse tree così arricchito ed eventuali ottimizzazioni.
  • Noi ci focalizzeremo sui LALR(1) cioè un Bottom Up Shift Reduce Look Ahead (one token) Left Right Parser…
  • Le parole sono importanti!!!!
  • Bottom Up Shift Reduce Look Ahead (one token) Left Right Parser
  • I Bottom Up Parsers sono complessi ma Bottom Up efficienti; per fortuna di solito sono generati Shift Reduce semiautomaticamente, con un Look Ahead (one token) “generatore di parser” in sulla base di CFG. base ad una una CFG. Left Right Parser Voi ne farete uno per il progetto... ;)
  • Bottom Up Shift Reduce Look Ahead (one token) Left Right Parser OK, lo sappiamo cosa fa…
  • Si parte dalla stringa di token (prodotto) e si costruisce il parse tree dalle Shift Reduce foglie su su per i vari padri, fino alla root, simbolo del Look Ahead (one token) linguaggio (start symbol). Bottom Up Left Right Parser
  • Legge la stringa di token da sinistra a destra (Left –right) Bottom Up (concettualmente!), dall‟alto in basso. Shift Reduce Cerca le sottostringhe che meccino il corpo di una produzione e la applica al Look Ahead (one token) contrario (reverse Rightmost derivation), cioè la riduce Left Right (Reduce), sostituendo la sottostringa (il corpo) con la Parser testa (meta-variabile o costrutto sintattico).
  • Questi parser fanno sostanzialmente due cose: Bottom Up  Shift: legge un nuovo token dall‟input (e lo mette Shift Reduce nel parse stack).  Reduce: applica una (sola) Look Ahead (one token) produzione p (al contrario) ad una porzione dello stack (che Left Right rappresenta un parse tree) e genera un nuovo stack (un nuovo parse tree con la radice Parser denotata con la testa di p).
  • Vi ricordate cos‟è uno stack, vero?
  • Tipo di dato astratto per riferirsi a strutture dati le cui modalità d'accesso ai dati in esse contenuti sono conformi alla logica LIFO (Last In First Out), ovvero secondo cui i dati sono estratti (letti/consumati – pop) in ordine inverso rispetto a quello in cui sono stati inseriti (scritti – push).
  • I LR (Shift Reduce) Parsers sono i più Bottom Up flessibili e potenti della categoria. Shift Reduce Nello stack mettono stati nello “shift”, e li Look Ahead (one token) tolgono nel “reduce”. Left Right Parser Gestiscono grammatiche context-free deterministiche.
  • Due scelte ad ogni passo: 1) Quali simboli Bottom Up contenuti nel parse stack riscrivere nella Shift Reduce forma sentenziale di testa: i più a destra (gli ultimi) o i più a Look Ahead (one token) sinistra (i primi)? Left Right Parser Nel nostro caso “rightmost”! Quelli aggiunti più di recente.
  • Due scelte ad ogni passo: 1) Quali simboli Bottom Up contenuti nel parse stack riscrivere nella Shift Reduce forma sentenziale di testa. Look Ahead (one token) 2) Con quale produzione riscriverlo. Left Right Parser
  • Bottom Up Shift Reduce Due scelte ad ogni passo: 1) Quali simboli riscrivere. 2) Con quale produzione riscriverli. Look Ahead (one token) LA(1) ci dice quanti token guardare “avanti” nell‟input per evitare Left Right conflitti reduce-reduce al passo 2 e ridurre Parser esigenze di memoria.
  • I Bottom Up Parsers Quindi: sono complessi ma fa uso un parser LALR(1) Bottom Up efficienti; perper tener di uno stack fortuna di solito sonoprocesso traccia del generati Shift Reduce semi- di una parsing parsing, automaticamente, con un table per capire cosa fare Look Ahead (one token) “generatore didi ad ogni passo parser” sulla base diguardando un esecuzione una CFG. simbolo avanti nell‟input Left Right a disposizione. Parser
  • La cosa difficile è cercare le sottostringhe che “meccino” (siano riconosciute/descritte da) il corpo di una produzione A -> w‟, cioè cercare nel parse stack qw‟, e riconoscere w‟ come “handle” della riduzione. Una volta trovata la produzione, la si applica (al contrario: riduzione) al parse stack che contiene qw‟ per portarlo a contenere qA.
  • Se tutto va bene alla fine tutto l‟input è stato processato, e il parser ha messo nello stack una sequenza che riconosciamo come il corpo di una produzione che riscrive lo start symbol (cioè a cui essa può essere ridotta) e ha scritto in output una rappresentazione dell‟albero sintattico concreto.
  • Se tutto va bene alla fine tutto l‟input è stato processato, e il parser ha messo nello stack una sequenza che riconosciamo come il corpo di una produzione che riscrive lo start symbol (cioè a cui essa può essere ridotta) e ha scritto in output una rappresentazione dell‟albero sintattico concreto. Il parser Accetta (ACCEPT) l‟input (lo stream è legale/valido) se lo stack contiene solo il simbolo di start quando non c‟è più input da parsare.
  • Input Action 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Un esempio di SR parsing
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Input 0: Goal → Sums eof 1: Sums → Sums + Products 2: Sums → Products 3: Products → Products * Value 4: Products → Value 5: Value → int 6: Value → id Action
  • Un esempio di LR parsing (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 PARSER 0 0 0 0 0 0 0 0 0 0 Action Table Goto Table 0 0 0 0 0
  • Un esempio di LR parsing (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 + 1 $ 0 0 0 0 PARSER 0 0 0 0 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 + 1 $ 0 0 0 0 PARSER 0 0 0 0 0 Action Table 0 0 0 0 Goto Table Capire come costruire una parsing table è fuori dai nostri scopi (ci pensa il generatore di parser nella realtà), ma lo studente interessato può consultare la Wikipedia sui Parser LR, alla pagina: http://goo.gl/pOYXFO (in italiano). (c’entrano gli automi a pila!)
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 Possibili azioni  Shift: s# (# è un numero): 1. Scrivi PARSER il numero # nello stack 0 0 1 + 1 $ 0 0 0 (esso contiene stati, quindi); 0 0 0 0 2. rimuovi il primo simbolo nell’input. 0 Goto  Reduce: Actionè un numero) r# (# 0 Table Table 1. Scrivi # nell’output. 0 2. Conta il numero di simboli nel corpo 0 della regola #-esima; 3. Togli dallo stack quel numero di stati. Ora trovi un nuovo numero in cima allo stack. Questo numero è il tuo stato temporaneo. 4. Prendi il simbolo dalla testa della regola #-esima. Trattalo come se fosse il prossimo simbolo nell’input e metti in cima allo stack lo stato corrispondente nella GOTO table.  Accept: L‟input è legale.  Errore: errore sintattico.
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 + 1 $ 0 0 0 0 PARSER 0 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 + 1 $ 0 0 0 0 PARSER 0 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 + 1 $ 0 0 0 0 PARSER 0 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 2 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 2 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 2 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 2 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 4 0 Action Table Goto Table 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 4 0 Action Table Goto Table 5 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 4 0 Action Table Goto Table 5 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 4 0 Action Table Goto Table 5 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 4 0 Action Table Goto Table 5 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 0 Action Table Goto Table 5 0 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 + 1 $ 0 0 0 0 PARSER 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 $ 0 0 0 0 PARSER 6 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 1 $ 0 0 0 0 PARSER 6 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 2 6 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 2 6 3 0 Action Table Goto Table 5 3 0 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 8 6 3 0 Action Table Goto Table 5 3 5 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 8 6 3 0 Action Table Goto Table 5 3 5 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 8 6 3 0 Action Table Goto Table 5 3 5 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 8 6 3 0 Action Table Goto Table 5 3 5 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 0 Action Table Goto Table 5 3 5 0 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 3 0 Action Table Goto Table 5 3 5 2 0
  • (1) E → E * B (2) E → E + B (3) E → B (4) B → 0 (5) B → 1 0 0 0 PARSER $ 0 3 0 Action Table 5 3 5 2 0 Goto Table Non sembra proprio un parse tree!! :) E’ la sequenza di produzioni applicate per ridurre la stringa al simbolo iniziale. Ogni produzione è associata ad un oggetto della classe della meta-variabile corrispondente (E e B), il cui costruttore prende in ingresso gli oggetti riferiti nel corpo della produzione. Comunque, conoscere la derivazione è conoscere il parse tree (vedi sopra), cioè la struttura sintattica dell’input.
  • Un altro esempio
  • Un parsing di esempio (assegnamento) Grammatica Parse Table
  • Le grammatiche ci permettono di: tradurre un programma da un linguaggio ad un altro (e.g., compilazione). descrivere un documento elettronico.  Sono usate in un DTD per specificare classi di documenti XML nella comunicazione tra macchine (e.g., server e client Web)
  • Sia tradurre programmi software che abilitare la comunicazione tra macchine richiede di verificare la sintassi, cioè la  legalità di una sentenza (stringa generata a partire da una grammatica = programma) per un compilatore.  validità di un documento (che sia well formed e conforme ad un DTD).
  • Sia tradurre programmi software che abilitare la comunicazione tra macchine richiede di verificare la sintassi, cioè la Well-formed (ben formato).  legalità di una sentenza (stringa generata a partire da una grammatica = programma) per un compilatore.  Senso comune: conforme alle regole di una grammatica.  Senso informatico: “ben annotato”, ben “parentesizzato”…  validità di un documento (che sia well formed e conforme ai requisiti strutturali e di tipo definiti in un DTD).
  • Sia tradurre programmi software che abilitare la comunicazione tra macchine richiede di verificare la sintassi, cioè la Well-formed (ben formato).  legalità di una sentenza (stringa generata a partire da una grammatica = programma) per un compilatore.  Senso comune: conforme alle regole di una grammatica.  Senso informatico: “ben annotato”, ben “parentesizzato”…  validità di un documento (che sia well formed e conforme ai requisiti strutturali e di tipo definiti in un DTD).
  • Markup languages L‟idea di una grammatica universale. servono I linguaggi di annotazione (mark up) per… Ma cos‟è una grammatica? … annotare il testo di un documento elettronico.
  • Markup languages L‟idea di una grammatica universale. servono I linguaggi di annotazione (mark up) per… Ma cos‟è una grammatica? … annotare il testo di un documento elettronico. Cosa? E perché?
  • Annotare il testo permette di creare  Strutture non gerarchiche.  (e.g., commenti e tag) L‟idea di una grammatica universale. Ma cos‟è una grammatica?  Strutture gerarchiche.  In questo caso parliamo di “container languages” o di “serializzazione basata sul testo”.  E.g., XML, JSON,YAML (67‟ IBM GML, „91 HTML)
  • Perchè si annota (serializza) un documento elettronico/file/testo?
  • Perchè si annota (serializza) un documento elettronico/file/testo? Per dire alla macchina cosa fare con quel testo
  • <a href="http://goo.gl/ZGCAf">First</a> <price>9,99</price>
  • <a href="http://goo.gl/ZGCAf">First</a> PRESENTATION OR DESCRIPTIVE MARKUP LANGUAGE? <price>9,99</price>
  • PRESENTATION OR DESCRIPTIVE MARKUP LANGUAGE? Qual è la differenza tra <p> e <i>?
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. Questa definizione specifica quali marcature (o elementi/tag) sono ammissibili, e quali valori essi possono contenere (vedi avanti)
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. Cioè ci sono dei contenitori che contengono del testo e lo caratterizzano…
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. Ogni marcatore aperto deve essere chiuso. e prima che se ne chiuda uno più esterno (altrimenti che contenitori sono?)
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. Ogni marcatore aperto deve essere chiuso. e prima che se ne chiuda uno più esterno WELL FORMED (altrimenti che contenitori sono?)
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. Ad esempio ad una Document Type Definition, o DTD. VALID
  • UN DTD  Può essere rappresentato (è?) da una grammatica particolare.  Ha forma: <!DOCTYPE nome-del-DTD [ elenco-di-definizioni-di-elementi ]>
  • UN DTD  Può essere rappresentato (è?) da una grammatica particolare.  Ha forma: <!DOCTYPE nome-del-DTD [ elenco-di-definizioni-di-elementi ]> <!ELEMENT nome-elemento ( modello del contenuto dell’elemento ) >
  • UN DTD  Può essere rappresentato (è?) da una grammatica particolare.  Ha forma: nient‟altro che simboli… <!DOCTYPE nome-del-DTD [ elenco-di-definizioni-di-elementi ]> <!ELEMENT nome-elemento ( modello del contenuto dell’elemento ) >
  • UN DTD  Può essere rappresentato (è?) da una grammatica particolare.  Ha forma: Espressione regolare su nomi-elemento. <!DOCTYPE nome-del-DTD [ elenco-di-definizioni-di-elementi ]> <!ELEMENT nome-elemento ( modello del contenuto dell’elemento ) >
  • ESPRESSIONI REGOLARI Una notazione per esprimere stringhe. © XKCD
  • ESPRESSIONI REGOLARI Una notazione per esprimere stringhe. © XKCD
  • ESPRESSIONI REGOLARI … cioè linguaggi! Una notazione per esprimere stringhe. © XKCD
  • ESPRESSIONI REGOLARI … cioè linguaggi REGOLARI! Una notazione per esprimere stringhe. © XKCD
  • ESPRESSIONI REGOLARI Una RE è costituita da simboli costanti e simboli operatori per denotare insiemi di stringhe che siano il risultato della loro composizione. © XKCD
  • ESPRESSIONI REGOLARI Una RE è costituita da simboli costanti e simboli operatori per denotare insiemi di stringhe che siano il risultato della loro composizione. © XKCD
  • ESPRESSIONI REGOLARI Una RE è costituita da simboli costanti e simboli operatori per denotare insiemi di stringhe che siano il risultato della loro composizione. Una RE si dice “definita sull‟alfabeto A” e “appartenente a A*”. © XKCD
  • ESPRESSIONI REGOLARI Una RE è costituita da simboli costanti e simboli operatori per denotare insiemi di stringhe che siano il risultato della loro composizione. Una RE si dice “definita sull‟alfabeto A” e “appartenente a A*”. Una RE è o una stringa vuota, o un simbolo di A, o il risultato di una alternazione (o unione) di RE, o di una concatenazione di RE o di una ripetizione (o chiusura) di RE. © XKCD
  • Linguaggi RE formali DTD POSIX Regex
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab Denotiamo stringhe vuote o elementi L(F) un XML F+G (tag) di U L(G) che non devono (a | b) avere contenuto. (L(F))* F* (a)* (a)+ (a)? L[(F)] = L(F) (F) (a|b) a* a+ a? a{min, max} (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • ORDINE DI PRIORITÀ Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali Esempi: aL = denota {a} ab= { } denota {ab} L DTD POSIX Regex EMPTY [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex Esempi: aL = denota {a} ab= { } denota {ab} L EMPTY [^.]* L = pippo cosa denota? a ( …e {a} (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= DTD Concatenazione EMPTY L={ } POSIX Regex [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi L= L={ } RE formali DTD POSIX Regex a e b devono esserci ed esattamente in questo ordine. EMPTY [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= DTD POSIX Regex Alternazione / Unione EMPTY [^.]* L={ } L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= DTD POSIX Regex Uno solo tra a e b deve occorrere. EMPTY [^.]* L={ } L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= L={ } Esempi: L= a a|b {a} denota {a, b} ( |a denota { F G a} L(F) L(G) a|b|a denota {a, b} EMPTY [^.]* (a) a (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= L={ } Esempi: L= a a|b {a} denota {a, b} ( |a denota { F G a} L(F) L(G) a|b|a denota {a, b} EMPTY [^.]* (a) a (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= L={ } EMPTY Ricorda: L = {a} (a) a ( • ( ) è un “gruppo”, indica un simbolo (a, L(F)solo e l‟eventuale operazione b) L(G) F G successiva si applica a tale simbolo. L(F) U L(G) F+G (a | b) • [ ] è una “classe”, e identifica un (L(F))* elemento. F* solo (a)* (a)+ (a)? Se A è ordinato, [a-z] indica un (1) L[(F)] = L(F) (F) simbolo tra a e z… (#PCDATA) ^ indica la negazione; fuori dalla classe indica inizio stringa. ANY NB: F e G sono RE Attenzione a “scherzi” come [-az] [a-z] (a-z) a-z [^.]* a ab (a|b) [ab] a* a+ a? a{min, max} (F) (.)* (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } Esempi: L = {a} ab (a|b)(c|d) L(F) L(G) a(b| ) L(F) U L(G) a ( [^.]* (a) a denota {ab} denota {ac, ad, bc, bd} (a, b) F G denota {ab, a} ab F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } Esempi: L = {a} ab (a|b)(c|d) L(F) L(G) a(b| ) L(F) U L(G) a ( [^.]* (a) a denota {ab} denota {ac, ad, bc, bd} (a, b) F G denota {ab, a} ab F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= DTD POSIX Regex Ripetizione / Chiusura EMPTY [^.]* L={ } L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi L= L={ } L = {a} RE formali DTD POSIX Regex Esempi: a* denota { ,EMPTYaaa, …}. a, aa, [^.]* (ab)* denota { , ab, abab, ababab, …}. a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi L= L={ } L = {a} RE formali DTD POSIX Regex Esempi: a* denota { ,EMPTYaaa, …}. a, aa, [^.]* (ab)* denota { , ab, abab, ababab, …}. a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi L= L={ } L = {a} RE formali DTD POSIX Regex Esempi: a* denota { ,EMPTYaaa, …}. a, aa, [^.]* (ab)* denota { , ab, abab, ababab, …}. a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } QuiL si {a} la vera differenza tra le(a) = gioca a ( RE formali e le Regex [^.]* a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi L= L={ } L = {a} RE formali DTD Ricorda: a* (a zero o più volte) EMPTY a+ (= aa*, cioè a almeno una volta) (a) a? (= a a,(cioè a o una o zero volte) POSIX Regex [^.]* a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } Avrei potuto scrivere a ( ma (a) L((F)), L = {a} volevo specificare meglio: il linguaggio (a, b) L(F) da F G denotatoL(G) (F)… [^.]* a ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= L={ } L = {a} a ( L(F) L(G) DTD POSIX Regex Ricorda: a{n, m}, EMPTY a un numero di volte tra n e m. [^.]* a{n}, a esattamente n volte. (a) a F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali L= DTD POSIX Regex L = {a} a ( Questo ci dice semplicemente che I metacaratteri ( ) creano gruppi e EMPTY [^.]* facilitano la lettura dell‟espressione, (a) a non cambiano il linguaggio. L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) L={ } (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (L(F))* F* L[(F)] = L(F) (F) Ricorda: (a | b) Una qualunque stringa (a|b) [ab] (a)* (a)+anche vuota a+ a? a{min, max} (a)? a* (F) (.)* (#PCDATA) ANY NB: F e G sono RE (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (L(F))* F* (a)* (a)+ (a)? L[(F)] = L(F) (F) Ricorda: (a|b) [ab] Un (1) qualunque carattere. a* a+ a? a{min, max} (F) (.)* (#PCDATA) ANY NB: F e G sono RE (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* L = {a} a ( (a) a L(F) L(G) F G (a, b) ab L(F) U L(G) F+G (a | b) (L(F))* F* (a)* (a)+ (a)? L[(F)] = L(F) (F) Ricorda: (a|b) La stringa vuota a* a+ a? a{min, max} (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } [^.]* Ricorda: a Una qualunque sequenza di caratteri. ab L = {a} a ( (a) L(F) L(G) F G (a, b) L(F) U L(G) F+G (a | b) (a|b) (L(F))* F* (a)* (a)+ (a)? a* a+ a? a{min, max} L[(F)] = L(F) (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE [ab] (.)* [^.]*
  • Linguaggi RE formali DTD POSIX Regex L= EMPTY L={ } L = {a} a ( L(F) L(G) F G L(F) U L(G) F+G (L(F))* F* L[(F)] = L(F) [^.]* Ricorda: (a) a Qualsiasi elemento definito nelab DTD. (a, b) #PCDATA è invece (a | b) qualsiasi stringa di [ab] (a|b) (a)* (a)+caratteri. a* a+ a? a{min, max} (a)? (F) (F) (.)* (#PCDATA) ANY NB: F e G sono RE (.)* [^.]*
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. La definizione definisce la struttura sintattica di una classe di documenti XML.
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. La definizione definisce la struttura sintattica di una classe di documenti XML. Ma allora un DTD può essere visto come una sottoclasse di una grammatica formale particolare…
  • UN DOCUMENTO XML E‟ una stringa a marcatori (o tag) accoppiati che è conforme ad una definizione. La definizione definisce la struttura sintattica di una classe di documenti XML. Ma allora un DTD può essere visto come una sottoclasse di una grammatica formale particolare… …può cioè essere visto come una XML-grammar, che è una sottoclasse di una extended context-free grammar.
  • EXTENDED CF GRAMMARS  Sono delle particolari CF grammars (eCFG), particolari non nella loro “natura” ma nella loro “capacità di generare linguaggi”.
  • EXTENDED CF GRAMMARS  Sono delle particolari CF grammars (eCFG), particolari non nella loro “natura” ma nella loro “capacità di generare linguaggi”.  L(CFG) L(eCFG), entrambi CF V γ vs. V LR  L‟estensione è “notazionale”. in una eCFG una sola produzione rappresenta una combinazione di produzioni…
  • EXTENDED CF GRAMMARS  Sono delle particolari CF grammars (eCFG), particolari non nella loro “natura” ma nella loro “capacità di generare linguaggi”.  L(CFG) L(eCFG), entrambi CF V γ vs. V LR  L‟estensione è “notazionale”. in una eCFG una sola produzione rappresenta una combinazione di produzioni… Esempio: G1: S U SU1T T TU1S eG1: S *(10*10*)* (5 produzioni) (1 produzione)
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 1: G: T = {l, x, r}, V = {S, B}, P = {S lBr, B lBr | x} Crea stringhe bilanciate rispetto alla coppia l - r .
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 1: G: T = {l, x, r}, V = {S, B}, P = {S lBr, B lBr | x} Crea stringhe bilanciate rispetto alla coppia l - r . l e r sono marcatori! Quindi G genera linguaggi a marcatori accoppiati!
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 2: G: P = {E P(BP)*, P id | num | lpar E rpar | -P, B +| - | * | / | < |= |>, S C*, C id = E | put E | get id | if E then B (else B | ) end| while E do B end}
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 2: G: P = {E P(BP)*, P id | num | lpar E rpar | -P, B +| - | * | / | < |= |>, S C*, C id = E | put E | get id | if E then B (else B | ) end| while E do B end} Ricordatevi il teorema di Jacopini – Boehm (1966): «qualunque algoritmo può essere implementato utilizzando tre sole strutture di controllo: la sequenza, la selezione ed il ciclo (iterazione)»
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 2: G: P = {E P(BP)*, P id | num | lpar E rpar | -P, B +| - | * | / | < |= |>, S C*, C id = E | put E | get id | if E then B (else B | ) end| while E do B end} Ricordatevi il teorema di Jacopini – Boehm (1966): «qualunque algoritmo può essere implementato utilizzando tre sole strutture di controllo: la sequenza, la selezione ed il ciclo (iterazione)» che corrispondono alla concatenazione, unione e chiusura delle RE...
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 2: G: P = {E P(BP)*, P id | num | lpar E rpar | -P, B +| - | * | / | < |= |>, S C*, C id = E | put E | get id | if E then B (else B | ) end| while E do B end} Immaginate di avere il seguente codice in ingresso ad un lexer: get i if i < 0 then put –i else put I end LEXER get id if id < num then put –id else put id end
  • EXTENDED CF GRAMMARS  eCFG = (V, T, P, S). P : V RE cioè il corpo è un “content model”, una RE quindi V LR, linguaggio regolare su (V U T)  : ogni elemento di V appare nella testa di una sola produzione. Esempio 2: G: P = {E P(BP)*, P id | num | lpar E rpar | -P, B +| - | * | / | < |= |>, S C*, C id = E | put E | get id | if E then B (else B | ) end| while E do B end} La derivazione: 4 , 5, 5, … S CC get id C get id if E then B else B end get id if P(BP)* then B else B end get i if i < 0 then put –i else put I end LEXER get id if id < num then put –id else put id end
  • XML GRAMMARS  eCFG = (V, T, P, S), ma T e P sono un po‟ particolari…
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); Á l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); Á l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); Á l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     Variabile che appartiene a V, testa della produzione, che corrisponde ad un a in A. A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     Espressione regolare su V ( V*). Quindi il corpo della produzione è più specifico di V R che avevamo visto per le eCFG. A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione con 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.     Espressione regolare su V ( V*). Quindi il corpo della produzione è più specifico di V R che avevamo visto per le eCFG. Quindi L(XMLG) L(eCFG) A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.      Sintatticamente (cioè ignorando il testo) un documento XML è una stringa (parola) su T. A}
  • XML GRAMMARS eCFG = (V, T, P, S), T=ÁUÀ A alfabeto base di simboli marcatori Á e À sono alfabeti accoppiati t.c. Á = {á | a A}, À = {à | a Á è l‟insieme degli start-tag (tag di apertura); À l‟insieme degli end-tag (tag di chiusura);  V insieme di variabili in associazione 1 a 1 con A.  P ha la stessa cardinalità di A, cioè: a A: Xa á Ra à.      Sintatticamente (cioè ignorando il testo) un documento XML è una stringa (parola) su T.  A, Á, À,V e P sono “accoppiati”. A}
  • XML GRAMMARS  eCFG = (V, T, P, S),  T = Á U À, P: Xa á Ra à. Esempio di DTD: <!DOCTYPE a * … <!ELEMENT a ((a|e),(a|e))> <!ELEMENT e (e)*> ]>
  • XML GRAMMARS  eCFG = (V, T, P, S),  T = Á U À, P: Xa á Ra à. Esempio di DTD: <!DOCTYPE a * … <!ELEMENT a ((a|e),(a|e))> <!ELEMENT e (e)*> ]> QuestoDTD è rappresentato dalla XML grammar con P: Xa á (Xa | Xe)(Xa|Xe)à Xe é Xe*è con Xa e Xe variabili associate ad a ed e
  • XML GRAMMARS  eCFG = (V, T, P, S),  T = Á U À, P: Xa á Ra à. Esempio di DTD: <!DOCTYPE a * … <!ELEMENT a ((a|e),(a|e))> <!ELEMENT e (e)*> ]> QuestoDTD è rappresentato dalla XML grammar con P: Xa á (Xa | Xe)(Xa|Xe)à Xe é Xe*è con Xa e Xe variabili associate ad a ed e NB: Nulla si dice del contenuto, ma solo del contenitore!!! (cf. sintassi)
  • XML GRAMMARS  eCFG = (V, T, P, S),  T = Á U À, P: Xa á Ra à. Esempio di DTD: <!DOCTYPE a * … <!ELEMENT a ((a|e),(a|e))> <!ELEMENT e (e)*> ]> “a” potrebbe essere <sec> “e” potrebbe essere <par>. Cioè: A = {<sec>, <par>} Á = {<sec>, <par>} À = {</sec>, </par>} QuestoDTD è rappresentato dalla XML grammar con P: Xa á (Xa | Xe)(Xa|Xe)à Xe é Xe*è con Xa e Xe variabili associate ad a ed e NB: Nulla si dice del contenuto, ma solo del contenitore!!! (cf. sintassi)
  • XML GRAMMARS  eCFG = (V, T, P, S),  T = Á U À, P: Xa á Ra à. Esempio di DTD: <!DOCTYPE doc [ <!ELEMENT doc (sec)+> <!ELEMENT sec ((sec|par),(sec|par))> <!ELEMENT par (par)*> ]> Questo DTD è rappresentato dalla XML grammar con P: S <doc> Xsec+</doc> Xsec <sec> (Xsec | Xpar)(Xsec|Xpar)</sec> Xpar <par> Xpar*</par> con Xa e Xe variabili associate a <sec> ed <par> NB: Nulla si dice del contenuto, ma solo del contenitore!!! (cf. sintassi)
  • Una eCFG e il DTD corrispondente
  • Una eCFG e il DTD corrispondente (#PCDATA) >
  • SINTETIZZANDO… Un DTD è una XML grammar in cui
  • SINTETIZZANDO… Un DTD è una XML grammar in cui S è denotato come DOCTYPE e un suo elemento deve avere lo stesso nome (root dei documenti XML definiti da quel DTD).
  • SINTETIZZANDO… Un DTD è una XML grammar in cui S è denotato come DOCTYPE e un suo elemento deve avere lo stesso nome (root dei documenti XML definiti da quel DTD). P è l‟insieme di tutte le produzioni associate ai tag denotati con ELEMENT.
  • SINTETIZZANDO… Un DTD è una XML grammar in cui S è denotato come DOCTYPE e un suo elemento deve avere lo stesso nome (root dei documenti XML definiti da quel DTD). P è l‟insieme di tutte le produzioni associate ai tag denotati con ELEMENT. Ogni ELEMENT è composto da un tipo (testa della produzione) e da un content model, cioè una espressione regolare in notazione DTD.
  • SINTETIZZANDO… Un DTD è una XML grammar in cui S è denotato come DOCTYPE e un suo elemento deve avere lo stesso nome (root dei documenti XML definiti da quel DTD). P è l‟insieme di tutte le produzioni associate ai tag denotati con ELEMENT. Ogni ELEMENT è composto da un tipo (testa della produzione) e da un content model, cioè una espressione regolare in notazione DTD. Validare un (1!) documento XML significa decidere se esso è valido, cioè se 1) è well formed e 2) conforme ad un DTD.
  • SINTETIZZANDO… Un DTD è una XML grammar in cui S è denotato come DOCTYPE e un suo elemento deve avere lo stesso nome (root dei documenti XML definiti da quel DTD). P è l‟insieme di tutte le produzioni associate ai tag denotati con ELEMENT. Ogni ELEMENT è composto da un tipo (testa della produzione) e da un content model, cioè una espressione regolare. Validare un (1!) documento XML significa decidere se esso è valido, cioè se 1) è well formed e 2) conforme ad un DTD. E le due cose sono equivalenti a verificare che il tree il cui prodotto rappresenta il documento sia un parse tree della XML grammar rappresentata dal DTD.
  • SERIALIZATION AND DATA INTERCHANGE JSON & YAML
  • Data models • Flat Model – Single two-dimensional array of data elements. • Delimited fields or fixed-length records (“tracciati”) • Example: CSV • Hierarchical Model – Data organized into a tree-like structure. • Example: XML, YAML • Relational Model – Multiple tables with precisely defined relations. • Example: MySQL
  • JSON • JavaScript Object Notation (JSON, 2006) is a lightweight, text-based, languageindependent data interchange format. – Format: how data are arranged in a specific type of file. • JSON defines a small set of formatting rules for the portable representation of structured data.
  • Design goals • Data interchange that is based on: • • • • • • • Minimality (it has not even a validator, use YAML instead) Portability, Openness Flexibility (fields can be added without obsolescence problems) Text-based, and even more… …Human- readability “Safe” subset of JavaScript – It does not allow invocations and assignments. – It allows for obectivation throu eval() (but it’s deprecated). – It allows for representing records, lists and trees natively • Language independency (there are many fast parsers!). • It is the best known alternative to XML (it’s the new X in AJAX).
  • JSON is not • A document format (like XML) • A markup language (like HTML) • A fit-for-all serialization format – No cyclical/recursive data structures – No functions – No validator – Not extensible – No namespaces
  • Primitives • JSON can represent – four primitive types (strings, numbers, booleans, and null) and – two structured types (objects and arrays). • An object is an unordered collection of zero or more name/value pairs, – where a name is a string and – a value is a string, number, boolean, null, object, or array. • An array is an ordered sequence of zero or more values.
  • JSON Grammar • A JSON text is a serialized object or array. – (serialization is a sort of “compilation” of information into a different format than source) <Json> ::= <Object> | <Array> • Remember: – Whitespaces (after structural characters are allowed) – Case sensitive! – Encoding Unicode UTF-8 (preferable)
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | String Number <Object> <Array> true false null
  • (BNF a digression) • Backus-Naur Form (or notation) – Formal way to describe a language (cf ALGOL60) • • • • • Production: statement written in BNF (symbol := alternative1 | alternative2 ...) <> indicates variable (non terminal symbol), “a term” to be defined. Terms and symbols without angle brackets are literals (terminal symbols) and appear in the language being defined exactly as they are specified. ::= “must be written with" | “or” • Examples: – An id may be either a or b. • <id> ::= a | b – An id may consist of one or more letters. • <id> ::= <letter> | <letter><id> <letter> ::= a|b|c|d|e… | Z • <firstname> ::= <capletter><lowerletter>|<firstname><lowerletter>
  • (EBNF a digression) • Extended Backus-Naur Form – They manage recursion easily. Cf. Extended Context Free Grammars… – ? : which means that the symbol (or group of symbols in parenthesis) to the left of the operator is optional (it can appear zero or one times) – * : which means that something can be repeated any number of times (and possibly be skipped altogether) – + : which means that something can appear one or more times • Example: – S := '-'? D+ ('.' D+)? D := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' – This is a grammar (written in EBNF) that generates any kind of number (also fractional).
  • JSON Productions Start symbol • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | Begin-object, end-object String Number <Object> <Array> true false null Name-separator Begin-array, end-array Value-separator Six structural characters
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | Also zero members! Also zero members/elements! String Number <Object> <Array> true false null Unfortunately duplicates can exist, but should be avoided! An array can contain different types!
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | String Number <Object> <Array> true false null 1. Between “” 2. Escaping is allowed
  • Strings and numbers • Number = '-'?('0'|{Digit9}{Digit}*)('.'{Digit}+)?([Ee][+-]?{Digit}+)? • String = '"'({Unescaped}|''(["/bfnrt]|'u'{Hex}{Hex}{Hex}{Hex}))*'"‘ • Where: – {Unescaped} = {All Valid} - {&1 .. &19} - ["] – {Hex} = {Digit} + [ABCDEFabcdef] – {Digit9} = {Digit} - [0]
  • Objects and Arrays • Use objects when keys are arbitrary strings. • Use arrays when “keys” are sequential integers. – Remember JSON does not support indexing. • JSON objects represent – records, structs, dictionaries, hashes, associative arrays… • JSON arrays represent – Arrays, vectors, sequences, lists…
  • De-Encoding JSON • JSON is stable (since 2006). • No versioning. • Decoding is liberal: – Accepts JSON and non-JSON strings. • Encoding is strict: – Only JSON strings are generated. • Examples: – A javascript compiler is a JSON decoder. – A YAML decoder is a JSON decoder.
  • Example { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": 10021 }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] }
  • Eval in Javascript • var responseData = eval("(" + responseText + ")"); • It returns the described object. • Better to use a parser, usually. – responseData = responseText.parseJSON(); • Why: – There are some Unicode characters that are valid in JSON strings but invalid in JavaScript, so additional escaping would be needed before using a JavaScript interpreter. – var my_JSON_object = !(/[^,:{}[]0-9.-+Eaeflnr-u nrt]/.test(text.replace(/"(.|[^"])*"/g, ''))) && eval('(' + text + ')'); – Never really trust what a server could give you…
  • JSON Schema • describes your existing data format. • clear, human- and machine-readable documentation. • complete structural validation, useful for: – automated testing. – validating client-submitted data.
  • JSON Schema Example • { "name": "Product", "properties": { "id": { "type": "number", "description": "Product identifier", "required": true }, "name": { "type": "string", "description": "Name of the product", "required": true }, "price": { "type": "number", "minimum": 0, "required": true }, "tags": { "type": "array", "items": { "type": "string" } }, "stock": { "type": "object", "properties": { "warehouse": { "type": "number" }, "retail": { "type": "number" } } } } } • JSON - Rosetta Code
  • One simple JSON • [ { "title": "an example" }, { "content": [ [ "any", "string" ], { "section": "other string", "footer": "end of the example" } ] } ]
  • An even simpler YAML - title: an example - content: - [any, string] - {section: "other string", footer: "end of the example"}
  • From JSON to YAML • JSON is a subset of YAML – Simpler (faster to parse) – Better with Unicode escaping (e.g., t, n, …) – Easier to share data btw different programming languages, • BUT also – less easy to read by humans. – Also less powerful • YAML serializes every data structure. • A JSON file is a valid YAML file – (if keys are unique, i.e., duplicates are errors.)
  • YAML • • • • YAML: YAML Ain't Markup Language Version 1.2 http://yaml.org/ is a YAML page. YAML is a human friendly data serialization standard for all programming languages.
  • YAML Grammar • • • • • • • • • // Identity definitions <whitespace> ::= " " | "t" <in-line-whitespace> ::= <whitespace> | <whitespace> <in-line-whitespace> <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" <integer-number> ::= <digit> | <digit> <integer-number> <end-of-line> ::= "rn" | "r" | "n" <non-whitespace> ::= <non-whitespace-word> ::= <non-whitespace> | <non-whitespace> <non-whitespace-word> • • • • • • • • // Basic document structure <yaml-stream> ::= <yaml-document-list> <yaml-document-list> ::= <yaml-document> | <yaml-document> <yaml-document-list> <yaml-document> ::= <yaml-directive-list> <yaml-directives-end> <yaml-content-list> <yaml-document-end> <yaml-directive-list> ::= <yaml-directive> <yaml-directive-list> | "" <yaml-directive> ::= <yaml-directive-yaml> | <yaml-directive-tag> <yaml-directive-yaml> ::= "%YAML" <in-line-whitespace> <integer-number> "." <integer-number> <end-of-line> | "" <yaml-directive-tag> ::= "%TAG" <in-line-whitespace> <yaml-tag-handle> <in-line-whitespace> <yaml-tag-prefix> <end-ofline> <yaml-directive-tag> | "" <yaml-tag-handle> ::= "!" | "!!" | "!" <non-whitespace-word> "!" <yaml-tag-prefix> ::= "!" <non-whitespace-word> | <non-whitespace-word> <yaml-directives-end> ::= "---" | "" <yaml-content-list> ::= <yaml-content> <yaml-content-list> | <yaml-content> <end-of-line> <yaml-document-end> ::= "..." | "" • • • • • • • • // Internals of an individual document <yaml-content> ::=
  • Learning by doing: Sequences --- # List of languages languages: - Ruby - Python - Perl --- # Flow style for lists languages: [Ruby, Python, Perl]
  • Mappings --- # User record - username: smithj uid: 11387 gcos: John Smith --- # flow style for dictionaries/JSONobjects - {username: smithj, uid: 11387, gcos: John Smith}
  • Nesting • In YAML “sequences” and “mappings” (arrays and objects, lists and dictionaries, arrays and associative arrays…) can be nested arbitrarily. --- name: Xavier country: Australia age: 24 - name: Don country: US • Don’t use tabs, indent by only (one or more) space. • Like JSON, case sensitive!
  • Strings • Regular strings need no punctuation. • Long strings use --- beginning. --- | This section preserves newlines just as they appear. --- > This section ignores newlines, and their only purpose is to make text readable.
  • Rosetta stone
  • Data models • Flat Model – Single two-dimensional array of data elements. • Delimited fields or fixed-length records (“tracciati”) • Example: CSV • Hierarchical Model – Data organized into a tree-like structure. • Example: XML, YAML • Relational Model – Multiple tables with precisely defined relations. • Example: MySQL
  • JSON • JavaScript Object Notation (JSON, 2006) is a lightweight, text-based, languageindependent data interchange format. – Format: how data are arranged in a specific type of file. • JSON defines a small set of formatting rules for the portable representation of structured data.
  • Design goals • Data interchange that is based on: • • • • • • • Minimality (it has not even a validator, use YAML instead) Portability, Openness Flexibility (fields can be added without obsolescence problems) Text-based, and even more… …Human- readability “Safe” subset of JavaScript – It does not allow invocations and assignments. – It allows for obectivation throu eval() (but it’s deprecated). – It allows for representing records, lists and trees natively • Language independency (there are many fast parsers!). • It is the best known alternative to XML (it’s the new X in AJAX).
  • JSON is not • A document format (like XML) • A markup language (like HTML) • A fit-for-all serialization format – No cyclical/recursive data structures – No functions – No validator – Not extensible – No namespaces
  • Primitives • JSON can represent – four primitive types (strings, numbers, booleans, and null) and – two structured types (objects and arrays). • An object is an unordered collection of zero or more name/value pairs, – where a name is a string and – a value is a string, number, boolean, null, object, or array. • An array is an ordered sequence of zero or more values.
  • JSON Grammar • A JSON text is a serialized object or array. – (serialization is a sort of “compilation” of information into a different format than source) <Json> ::= <Object> | <Array> • Remember: – Whitespaces (after structural characters are allowed) – Case sensitive! – Encoding Unicode UTF-8 (preferable)
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | String Number <Object> <Array> true false null
  • (BNF a digression) • Backus-Naur Form (or notation) – Formal way to describe a language (cf ALGOL60) • • • • • Production: statement written in BNF (symbol := alternative1 | alternative2 ...) <> indicates variable (non terminal symbol), “a term” to be defined. Terms and symbols without angle brackets are literals (terminal symbols) and appear in the language being defined exactly as they are specified. ::= “must be written with" | “or” • Examples: – An id may be either a or b. • <id> ::= a | b – An id may consist of one or more letters. • <id> ::= <letter> | <letter><id> <letter> ::= a|b|c|d|e… | Z • <firstname> ::= <capletter><lowerletter>|<firstname><lowerletter>
  • (EBNF a digression) • Extended Backus-Naur Form – They manage recursion easily. Cf. Extended Context Free Grammars… – ? : which means that the symbol (or group of symbols in parenthesis) to the left of the operator is optional (it can appear zero or one times) – * : which means that something can be repeated any number of times (and possibly be skipped altogether) – + : which means that something can appear one or more times • Example: – S := '-'? D+ ('.' D+)? D := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' – This is a grammar (written in EBNF) that generates any kind of number (also fractional).
  • JSON Productions Start symbol • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | Begin-object, end-object String Number <Object> <Array> true false null Name-separator Begin-array, end-array Value-separator Six structural characters
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | Also zero members! Also zero members/elements! String Number <Object> <Array> true false null Unfortunately duplicates can exist, but should be avoided! An array can contain different types!
  • JSON Productions • • <Json> ::= <Object> | <Array> • • <Object> ::= '{' '}' | '{' <Members> '}' • • <Members> ::= <Pair> | <Pair> ',' <Members> • <Pair> ::= String ':' <Value> • • <Array> ::= '[' ']' | '[' <Elements> ']' • • <Elements> ::= <Value> | <Value> ',' <Elements> • • • • • • • <Value> ::= | | | | | | String Number <Object> <Array> true false null 1. Between “” 2. Escaping is allowed
  • Strings and numbers • Number = '-'?('0'|{Digit9}{Digit}*)('.'{Digit}+)?([Ee][+-]?{Digit}+)? • String = '"'({Unescaped}|''(["/bfnrt]|'u'{Hex}{Hex}{Hex}{Hex}))*'"‘ • Where: – {Unescaped} = {All Valid} - {&1 .. &19} - ["] – {Hex} = {Digit} + [ABCDEFabcdef] – {Digit9} = {Digit} - [0]
  • Objects and Arrays • Use objects when keys are arbitrary strings. • Use arrays when “keys” are sequential integers. – Remember JSON does not support indexing. • JSON objects represent – records, structs, dictionaries, hashes, associative arrays… • JSON arrays represent – Arrays, vectors, sequences, lists…
  • De-Encoding JSON • JSON is stable (since 2006). • No versioning. • Decoding is liberal: – Accepts JSON and non-JSON strings. • Encoding is strict: – Only JSON strings are generated. • Examples: – A javascript compiler is a JSON decoder. – A YAML decoder is a JSON decoder.
  • Example { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": 10021 }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] }
  • Eval in Javascript • var responseData = eval("(" + responseText + ")"); • It returns the described object. • Better to use a parser, usually. – responseData = responseText.parseJSON(); • Why: – There are some Unicode characters that are valid in JSON strings but invalid in JavaScript, so additional escaping would be needed before using a JavaScript interpreter. – var my_JSON_object = !(/[^,:{}[]0-9.-+Eaeflnr-u nrt]/.test(text.replace(/"(.|[^"])*"/g, ''))) && eval('(' + text + ')'); – Never really trust what a server could give you…
  • JSON Schema • describes your existing data format. • clear, human- and machine-readable documentation. • complete structural validation, useful for: – automated testing. – validating client-submitted data.
  • JSON Schema Example • { "name": "Product", "properties": { "id": { "type": "number", "description": "Product identifier", "required": true }, "name": { "type": "string", "description": "Name of the product", "required": true }, "price": { "type": "number", "minimum": 0, "required": true }, "tags": { "type": "array", "items": { "type": "string" } }, "stock": { "type": "object", "properties": { "warehouse": { "type": "number" }, "retail": { "type": "number" } } } } } • JSON - Rosetta Code
  • One simple JSON • [ { "title": "an example" }, { "content": [ [ "any", "string" ], { "section": "other string", "footer": "end of the example" } ] } ]
  • An even simpler YAML - title: an example - content: - [any, string] - {section: "other string", footer: "end of the example"}
  • From JSON to YAML • JSON is a subset of YAML – Simpler (faster to parse) – Better with Unicode escaping (e.g., t, n, …) – Easier to share data btw different programming languages, • BUT also – less easy to read by humans. – Also less powerful • YAML serializes every data structure. • A JSON file is a valid YAML file – (if keys are unique, i.e., duplicates are errors.)
  • YAML • • • • YAML: YAML Ain't Markup Language Version 1.2 http://yaml.org/ is a YAML page. YAML is a human friendly data serialization standard for all programming languages.
  • YAML Grammar • • • • • • • • • // Identity definitions <whitespace> ::= " " | "t" <in-line-whitespace> ::= <whitespace> | <whitespace> <in-line-whitespace> <digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" <integer-number> ::= <digit> | <digit> <integer-number> <end-of-line> ::= "rn" | "r" | "n" <non-whitespace> ::= <non-whitespace-word> ::= <non-whitespace> | <non-whitespace> <non-whitespace-word> • • • • • • • • // Basic document structure <yaml-stream> ::= <yaml-document-list> <yaml-document-list> ::= <yaml-document> | <yaml-document> <yaml-document-list> <yaml-document> ::= <yaml-directive-list> <yaml-directives-end> <yaml-content-list> <yaml-document-end> <yaml-directive-list> ::= <yaml-directive> <yaml-directive-list> | "" <yaml-directive> ::= <yaml-directive-yaml> | <yaml-directive-tag> <yaml-directive-yaml> ::= "%YAML" <in-line-whitespace> <integer-number> "." <integer-number> <end-of-line> | "" <yaml-directive-tag> ::= "%TAG" <in-line-whitespace> <yaml-tag-handle> <in-line-whitespace> <yaml-tag-prefix> <end-ofline> <yaml-directive-tag> | "" <yaml-tag-handle> ::= "!" | "!!" | "!" <non-whitespace-word> "!" <yaml-tag-prefix> ::= "!" <non-whitespace-word> | <non-whitespace-word> <yaml-directives-end> ::= "---" | "" <yaml-content-list> ::= <yaml-content> <yaml-content-list> | <yaml-content> <end-of-line> <yaml-document-end> ::= "..." | "" • • • • • • • • // Internals of an individual document <yaml-content> ::=
  • Learning by doing: Sequences --- # List of languages languages: - Ruby - Python - Perl --- # Flow style for lists languages: [Ruby, Python, Perl]
  • Mappings --- # User record - username: smithj uid: 11387 gcos: John Smith --- # flow style for dictionaries/JSONobjects - {username: smithj, uid: 11387, gcos: John Smith}
  • Nesting • In YAML “sequences” and “mappings” (arrays and objects, lists and dictionaries, arrays and associative arrays…) can be nested arbitrarily. --- name: Xavier country: Australia age: 24 - name: Don country: US • Don’t use tabs, indent by only (one or more) space. • Like JSON, case sensitive!
  • Strings • Regular strings need no punctuation. • Long strings use --- beginning. --- | This section preserves newlines just as they appear. --- > This section ignores newlines, and their only purpose is to make text readable.
  • Rosetta stone
  • Linguaggi e Computabilità Esercitazioni A. A. 2013-14 Fine Dott. Ing. Federico Cabitza, PhD cabitza@disco.unimib.it Stanza 2063 II p. U 14 ricevimento su appuntamento