+ All Categories
Home > Documents > Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (»...

Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (»...

Date post: 20-Dec-2020
Category:
Upload: others
View: 1 times
Download: 0 times
Share this document with a friend
40
Analisi Sintattica Top-down Corrispondente a una derivazione canonica sinistra Predittiva: senza backtracking necessario computare gli insiemi guida FIRST e FOLLOW LL(1): in generale LL(K) Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 1 Top-down Backtracking Predittiva L = left to right scanning L = leftmost derivation K = numero di simboli di lookahead necessari per decidere Discesa ricorsiva LL(1)
Transcript
Page 1: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica Top-down

Corrispondente a una derivazione canonica sinistra

Predittiva: senza backtracking necessario computare gli insiemi guida FIRST e FOLLOW

LL(1): in generale LL(K)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 1

Top-down

Backtracking Predittiva

L = left to right scanningL = leftmost derivationK = numero di simboli di lookahead necessari per decidere

Discesaricorsiva

LL(1)

Page 2: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica Top-down (ii)

Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di:

1) Al nodo n marcato da A seleziona una produzione di A ed appendi ad n la sua parte destra;

2) Scegli il prossimo nodo (da espandere).

Per qualche G: generazione dell'albero con un singolo scanning dell'input

In generale necessario backtracking

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 2

type simple | ^ id | array [ simple ] of type simple integer | char | num dots num

criticità

array [ num dots num ] of integer type

array [ simple ] of type

num dots num simple

integer

lookahead (simbolo corrente)

Page 3: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica a Discesa Ricorsiva Analisi dell'input mediante procedure ricorsive:

nonterminale associazione con una procedura (in generale) ricorsiva

Discriminazione delle alternative (produzioni) sulla base del simbolo di lookahead

alternativa scanning della parte destra (lista di simboli grammaticali):

1. Terminale matching del simbolo di lookahead

2. Nonterminale chiamata della procedura corrispondente

Struttura della procedura associata alla regola A 1 | 2 | … | n :

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 3

procedure A()begin if lookahead FIRST(1) then scan 1

else if lookahead FIRST(2) then scan 2

... else if lookahead FIRST(n) then scan n

else error()end;

Insieme dei simboli lessicali che iniziano le istanze di 1

Omesso quando A è una alternativa

(in generale, quando: FIRST(i))

Page 4: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica a Discesa Ricorsiva (ii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 4

var lookahead: Symbol;

procedure match(s: Symbol)begin if lookahead = s then lookahead := next() else error()end;

lookahead

procedure type()begin if lookahead in {integer, char, num} then simple() else if lookahead = '^' then begin match('^'); match(id) end else if lookahead = array then begin match(array); match('['); simple(); match(']'); match(of); type() end else error()end;

procedure simple()begin if lookahead = integer then match(integer) else if lookahead = char then match(char) else if lookahead = num then begin match(num); match(dots); match(num) end else error()end;

type simple | ^ id | array [ simple ] of type simple integer | char | num dots num

array [ num dots num ] of integer

Page 5: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica a Discesa Ricorsiva (iii)

Estensione alle EBNF:

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 5

stat if expr then stat [ else stat ]

procedure stat() match(IF); expr(); match(THEN); stat(); if lookahead = ELSE then match(ELSE); stat() endifend;

expr term { + term }

procedure expr() term(); while lookahead = PLUS do match(PLUS); term() endwhileend;

stat-list { stat ; }+

stat id := expr

procedure stat_list() do stat(); match(SEMICOLON) while lookahead = IDend;

Page 6: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Parsing a Discesa Ricorsiva: Linguaggio per Tabelle

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 6

program stat { stat } stat def-stat | assign-statdef-stat def id ( def-list )def-list id : domain {, id: domain }domain integer | string | booleanassign-stat id := { { tuple-const } }tuple-const ( simple-const {, simple-const } )simple-const intconst | strconst | boolconst

def R (A: integer, B: string, C: boolean)def S (D: integer, E: string)R := {(3, "alpha", true)(5, "beta", false)}S := {(125, "sun")(236, "moon")}

Page 7: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Parsing a Discesa Ricorsiva: Linguaggio per Tabelle (ii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 7

void parse(){ next(); program();}

void program(){ stat(); while (lookahead == DEF || lookahead == ID) stat();}

void stat(){ if (lookahead == DEF) def_stat(); else if (lookahead == ID) assign_stat(); else parserror();}

void def_stat(){ match(DEF); match(ID); match('('); def_list(); match(')');}

void def_list(){ match(ID); match(':'); domain(); while(lookahead == ',') { next(); match(ID); match(':'); domain(); }}

program stat { stat } stat def-stat | assign-statdef-stat def id ( def-list )def-list id : domain {, id: domain }

Page 8: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Parsing a Discesa Ricorsiva: Linguaggio per Tabelle (iii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 8

domain integer | string | booleanassign-stat id := { { tuple-const } }tuple-const ( simple-const {, simple-const } )simple-const intconst | strconst | boolconst

void domain(){ if (lookahead == INTEGER || lookahead == STRING || lookahead == BOOLEAN) next(); else parserror();}

void assign_stat(){ match(ID); match(ASSIGN); match('{'); while ( lookahead == '(') tuple_const(); match('}');}

void tuple_const(){ match('('); simple_const(); while ( lookahead == ',') { next(); simple_const(); } match(')');}

void simple_const(){ if (lookahead == INTCONST || lookahead == STRCONST || lookahead == BOOLCONST) next(); else parserror();}

int main(){ parse(); return(0);}

Page 9: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Analisi Sintattica LL(1)

Gestione diretta di una pila col supporto di una tabella per scegliere le produzioni da espandere

Programma (controllore del processo di parsing): basato su (X, a) azione da eseguire:

1. X = a = $: accetta 2. X = a $: pop(X); avanza 3. Terminale(X), X a: errore 4. Nonterminale(X): M[X,a] =

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 9

Pogramma diParsing Predittivo

Tabella diParsing M

a + b - c $

XYZW$

outputpila

input (sequenza di simboli)

(simboli grammaticali)

produzione di X, es: X AbC sostituisci X con CbA errore (chiamata della routine di recovery)

top

Page 10: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Algoritmo di Parsing LL(1)

Input: w = stringa di terminali, M = tabella di parsing di G Output: w L(G) derivazione sinistra di w (o messaggio di errore)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 10

pila := ; input := w$; pc punta al primo simbolo di w$;

repeat X := simbolo grammaticale in cima alla pila; a := simbolo terminale puntato da pc; if Terminale(X) or X = $ then if X = a then pop(); pc++ else errore() else if M[X,a] = X Y1Y2...Yn then pop(); push(Yn, Yn-1, ..., Y1); /* Y1 in cima alla pila */ print "XY1Y2...Yn" else errore()until X = $.

S$

Page 11: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Parsing LL(1): Esempi

(linguaggio delle parentesi bilanciate)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 11

( ) $

S S ( S ) S S S

w = ( )

M (funzione di "riscrittura")

Pila Input Azione

S$ ()$ S ( S ) S

(S)S$ ()$ match

S)S$ )$ S

)S$ )$ match

S$ $ S

$ $ accetta

S ( S ) S |

Page 12: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Parsing LL(1): Esempi (ii)

Note:

LL(1) » parsing a discesa ricorsiva Tabella di parsing: guida l'analisi sintattica Differenza: generalità di LL(1) Invarianza del problema della ricorsione sinistra

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 12

E E + T | TT T * F | FF ( E ) | num

E T E’E’ + T E’ | T F T’T’ * F T’ | F ( E ) | num

num + * ( ) $

E E T E’ E T E’

E’ E’ + T E’ E’ E’

T T F T’ T F T’

T’ T’ T’ * F T’ T’ T’

F F num F ( E )

w = ( num + num ) * num

Pila Input AzioneE$ (n+n)*n$ E TE’

TE’$ (n+n)*n$ T FT’

FT’E’$ (n+n)*n$ F (E)

(E)T’E’$ (n+n)*n$ match

E)T’E’$ n+n)*n$ E TE’

TE’)T’E’$ n+n)*n$ T FT’

FT’E’)T’E’$ n+n)*n$ F num

nT’E’)T’E’$ n+n)*n$ match

T’E’)T’E’$ +n)*n$ T’

E’)T’E’$ +n)*n$ E’ +TE’

+TE’)T’E’$ +n)*n$ match

TE’)T’E’$ n)*n$ T FT’

FT’E’)T’E’$ n)*n$ F num

nT’E’)T’E’$ n)*n$ match

T’E’)T’E’$ )*n$ T’

E’)T’E’$ )*n$ E’

)T’E’$ )*n$ match

T’E’$ *n$ T’ *FT’

* FT’E’$ *n$ match

FT’E’$ n$ F num

nT’E’$ n$ match

T’E’$ $ T’

E’$ $ E’

$ $ accetta

Page 13: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Istanziazione della Tabella di Parsing: FIRST

Concettualmente: FIRST() { a | a }; if , then FIRST().

Induttivamente:

a) Dato X = simbolo grammaticale o , FIRST(X) = { terminale [+ ] } così definito:

1. Se X è un terminale o , allora FIRST(X) = { X }

2. Se X è un nonterminale, allora alternativa X ( FIRST(X) FIRST() )

b) Data = X1X2...Xn = stringa di simboli grammaticali, FIRST() è così definita:

FIRST() FIRST(X1) {}

Se in (FIRST(X1), FIRST(X2), ..., FIRST(Xi)) then FIRST() FISRT(Xi+1) {}

Se i [1..n] ( FIRST(Xi) ), allora FIRST()

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 13

**

Page 14: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

FIRST: Esempi

1.

2.

3.

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 14

E T E’E’ + T E’ | T F T’T’ * F T’ | F ( E ) | id

FIRST(E) = FIRST(T) = FIRST(F) = { (, id }

FIRST(E’) = { +, }

FIRST(T’) = { *, }

stat if-stat | otherif-stat if expr then stat else-partelse-part else stat | expr true | false

FIRST(stat) = { if, other }

FIRST(if-stat) = { if }

FIRST(else-part) = { else, }

FIRST(expr) = { true, false }

stat-list stat stat-list’stat-list’ ; stat stat-list’ | stat s

FIRST(stat-list) = FIRST(stat) = { s }

FIRST(stat-list’) = { ;, }

Page 15: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Istanziazione della Tabella di Parsing: FOLLOW

Insieme guida: necessario sia in LL(1) che nel parsing a discesa ricorsiva

FIRST non sufficiente necessario FOLLOW quando A ,

Concettualmente: FOLLOW(A) { a | S Aa }

Anche: se S A, allora $ FOLLOW(A).

Induttivamente: Dato un nonterminale A, FOLLOW(A) = { terminali [+ $] } definito dalle seguenti regole:

Se A = assioma, allora $ FOLLOW(A);

Se produzione B A, allora FOLLOW(A) FIRST() { };

Se produzione B A tale che FIRST(), allora FOLLOW(A) FOLLOW(B).

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 15

*

*

*

Page 16: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

FOLLOW: Esempi

1.

2.

3.

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 16

E T E’E’ + T E’ | T F T’T’ * F T’ | F ( E ) | id

FIRST(E’) = { +, }FIRST(T’) = { *, }

FOLLOW(E) = { ), $ }

FOLLOW(E’) = { ), $ }

FOLLOW(T) = { +, ), $ }

FOLLOW(T’) = { +, ), $ }

FOLLOW(F) = { *, +, ), $ }

stat-list stat stat-list’stat-list’ ; stat stat-list’ | stat s

FOLLOW(stat-list) = { $ }

FOLLOW(stat-list’) = { $ }

FOLLOW(stat) = { ;, $ }

FIRST(stat-list) = FIRST(stat) = { s }FIRST(stat-list’) = { ;, }

stat if-stat | otherif-stat if expr then stat else-partelse-part else stat | expr true | false

FIRST(stat) = { if, other }FIRST(if-stat) = { if }FIRST(else-part) = { else, }FIRST(expr) = { true, false }

FOLLOW(stat) = { $, else }

FOLLOW(if-stat) = { $, else }

FOLLOW(else-part) = { $, else }

FOLLOW(expr) = { then }

Page 17: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Algoritmo per Costruire la Tabella di Parsing M[A,a]

Def : G è LL(1) se e solo se la tabella di parsing M non è ambigua.

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 17

for each nonterminale A do for each alternativa A do for each a FIRST(), a do Inserisci A in M[A,a] end-for if FIRST() then for each a FOLLOW(A) do Inserisci A in M[A,a] end-for end-if end-forend-for.

Page 18: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Costruzione della Tabella di Parsing: Esempi

1.

Poiché M non è ambigua, G è LL(1)Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 18

E T E’E’ + T E’ | T F T’T’ * F T’ | F ( E ) | id FOLLOW(E) = FOLLOW(E’) = { ), $ }

FOLLOW(T) = FOLLOW(T’) = { +, ), $ }

FOLLOW(F) = { *, +, ), $ }

FIRST(E) = FIRST(T) = FIRST(F) = { (, id }

FIRST(E’) = { +, }

FIRST(T’) = { *, }

FIRST(TE’) = { (, id }

FIRST(+TE’) = { + }

FIRST(FT’) = { (, id }

FIRST(*FT’) = { * }

FIRST((E)) = { ( }

FIRST(id) = { id }

id + * ( ) $

E E T E’ E T E’

E’ E’ + T E’ E’ E’

T T F T’ T F T’

T’ T’ T’ * F T’ T’ T’

F F id F ( E )

Page 19: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Costruzione della Tabella di Parsing: Esempi (ii)

2.

Poiché M è ambigua, G non è LL(1)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 19

if then else other true false $

stat stat if-stat stat other

if-stat if-stat if expr then stat else-part

else-part else-part else statelse-part

else-part

expr expr true expr false

stat if-stat | otherif-stat if expr then stat else-partelse-part else stat | expr true | false

FIRST(stat) = { if, other }

FIRST(if-stat) = { if }

FIRST(else-part) = { else, }

FIRST(expr) = { true, false }

FIRST(other) = { other }

FOLLOW(stat) = { $, else }

FOLLOW(if-stat) = { $, else }

FOLLOW(else-part) = { $, else }

FOLLOW(expr) = { then }

Page 20: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Costruzione della Tabella di Parsing: Esempi (iii)

3.

Poiché M non è ambigua, G è LL(1)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 20

stat-list stat stat-list’stat-list’ ; stat stat-list’ | stat s

FOLLOW(stat-list) = FOLLOW(stat-list’) = { $ }

FOLLOW(stat) = { ;, $ }

FIRST(stat-list) = FIRST(stat) = { s }

FIRST(stat-list’) = { ;, }

FIRST(stat stat-list’) = { s }

FIRST(; stat stat-list’) = { ; }

; s $

stat-list stat-list stat stat-list’

stat-list’ stat-list’ ; stat stat-list’ stat-list’

stat stat s

Page 21: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Costruzione Top-down dell'Albero Sintattico Astratto

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 21

program stat { stat } stat def-stat | assign-statdef-stat def id ( def-list )def-list id : domain {, id: domain }domain integer | string | booleanassign-stat id := { { tuple-const } }tuple-const ( simple-const {, simple-const } )simple-const intconst | strconst | boolconst

def R (A: integer, B: string, C: boolean)def S (D: integer, E: string)R := {(3, "alpha", true)(5, "beta", false)}S := {(125, "sun")(236, "moon")}

program

stat stat stat stat

def-stat def-stat assign-stat assign-stat

def id ( def-list )

id : domain id : domain

integer string

,

Page 22: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Costruzione Top-down dell'Albero Sintattico Astratto (ii)

Regole dello “stato” del nodo:

1.

2.

3. Identificatore

4. Nonterminale

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 22

typedef union{ int ival; char *sval; enum {FALSE, TRUE} bval;} Value;

typedef struct snode{ Typenode type; Value value; struct snode *child, *brother;} Node;

type value child brother

keywordcarattere specialeoperatore

type = costante identificativa (DEF, LEFT, ASSIGN, ...)

zucchero sintattico: può mancare nell'albero

costante intera

costante stringa

costante booleana

type = T_INTCONSTvalue.ival

type = T_STRCONSTvalue.sval

type = T_BOOLCONSTvalue.bval

type = T_IDvalue.sval

type = T_NONTERMINALvalue.ival

Page 23: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

def.h

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 23

#include <stdio.h>#include <stdlib.h>

#define DEF 258#define INTEGER 259#define STRING 260#define BOOLEAN 261#define ID 262#define INTCONST 263#define STRCONST 264#define BOOLCONST 265#define ASSIGN 266#define ERROR 267

typedef enum{ T_INTEGER, T_STRING, T_BOOLEAN, T_INTCONST, T_BOOLCONST, T_STRCONST, T_ID, T_NONTERMINAL} Typenode;

typedef enum { NPROGRAM, NSTAT, NDEF_STAT, NDEF_LIST, NDOMAIN, NASSIGN_STAT, NTUPLE_CONST, NSIMPLE_CONST} Nonterminal;

typedef union{ int ival; char *sval; enum {FALSE, TRUE} bval;} Value;

typedef struct snode{ Typenode tipo; Value value; struct snode *child, *brother;} Node;

typedef Node *Pnode;

void match(int), next(), parserror(), treeprint(Pnode, int);

char *newstring(char*);

Pnode nontermnode(Nonterminal), idnode(), keynode(Typenode), intconstnode(), strconstnode(), boolconstnode(), newnode(Typenode), program(), stat(), def_stat(), def_list(), domain(), assign_stat(), tuple_const(), simple_const();

Page 24: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

lexer.lex

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 24

%{ #include "def.h"int line = 1; Value lexval;%} %option noyywrap

spacing ([ \t])+letter [A-Za-z]digit [0-9]intconst {digit}+strconst \"([^\"])*\"boolconst false|trueid {letter}({letter}|{digit})*sugar [(){}:,]%%{spacing} ;\n {line++;}def {return(DEF);}integer {return(INTEGER);}string {return(STRING);}boolean {return(BOOLEAN);}{intconst} {lexval.ival = atoi(yytext); return(INTCONST);}{strconst} {lexval.sval = newstring(yytext); return(STRCONST);}{boolconst} {lexval.bval = (yytext[0] == 'f' ? FALSE : TRUE); return(BOOLCONST);}{id} {lexval.sval = newstring(yytext); return(ID);}{sugar} {return(yytext[0]);}":=" {return(ASSIGN);}. {return(ERROR);}%%

char *newstring(char *s){ char *p; p = malloc(strlen(s)+1); strcpy(p, s); return(p);}

program stat { stat } stat def-stat | assign-statdef-stat def id ( def-list )def-list id : domain {, id: domain }domain integer | string | booleanassign-stat id := { { tuple-const } }tuple-const ( simple-const {, simple-const } )simple-const intconst | strconst | boolconst

Page 25: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

scanner.c

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 25

#include "def.h"

#define NUM_KEYWORDS 6#define MAXIDENT 100

FILE *yyin;int line = 1; char *yytext = NULL; Value lexval;int i, k;

struct {char* name; int keyword;}keywords[NUM_KEYWORDS] = { "def", DEF, "integer", INTEGER, "string", STRING, "boolean", BOOLEAN, "false", BOOLCONST, "true", BOOLCONST};

int yylex(){ int cc, keyword; if(yytext == NULL) yytext = malloc(MAXIDENT+1); do { cc = fgetc(yyin); if(cc == '\n') line++; } while(cc == ' ' || cc == '\t' || cc == '\n'); if(cc == '(' || cc == ')' || cc == '{' || cc == '}' || cc == ',') return(cc); else if(cc == ':') { if((cc = fgetc(yyin)) == '=') return(ASSIGN); else { ungetc(cc, yyin); return(':'); } } else if(isalpha(cc)) { i = 0; yytext[i++] = cc; while(isalnum(cc = fgetc(yyin))) yytext[i++] = cc; ungetc(cc, yyin); yytext[i] = '\0'; if(keyword = lookup(yytext)) { if(keyword == BOOLCONST) lexval.bval = (yytext[0] == 'f' ? FALSE : TRUE); return (keyword); } else { lexval.sval = newstring(yytext); return(ID); } }...

spaziatura

id, keyword, boolconst

Page 26: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

scanner.c (ii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 26

...else if(isdigit(cc)) { i = 0; yytext[i++] = cc; while(isdigit(cc = fgetc(yyin))) yytext[i++] = cc; ungetc(cc, yyin); yytext[i] = '\0'; lexval.ival = atoi(yytext); return(INTCONST); } else if(cc == '"') { i = 0; yytext[i++] = cc; while((cc = fgetc(yyin)) != '"') yytext[i++] = cc; yytext[i++] = cc; yytext[i] = '\0'; lexval.sval = newstring(yytext); return(STRCONST); } else if(cc==EOF) return(EOF); else return(ERROR);}

int lookup(char *id){ for(k = 0; k < NUM_KEYWORDS; k++) if(strcmp(id, keywords[k].name) == 0) return(keywords[k].keyword); return(0);}

char *newstring(char *s){ char *p; p = malloc(strlen(s)+1); strcpy(p, s); return(p);}

Page 27: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 27

#include "def.h"

extern char *yytext;extern Value lexval;extern int line;extern FILE *yyin;

int lookahead;

Pnode root = NULL;

void next(){ lookahead = yylex();}

void match(int symbol){ if(lookahead == symbol) next(); else parserror();}

void parserror(){ fprintf(stderr, "Line %d: syntax error on symbol \"%s\"\n", line, yytext); exit(-1);}

Page 28: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (ii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 28

Pnode newnode(Typenode tnode){ Pnode p;

p = (Pnode) malloc(sizeof(Node)); p->type = tnode; p->child = p->brother = NULL; return(p);}

Pnode nontermnode(Nonterminal nonterm){ Pnode p;

p = newnode(T_NONTERMINAL); p->value.ival = nonterm; return(p);}

Pnode keynode(Typenode keyword){ return(newnode(keyword));}

Pnode idnode(){ Pnode p;

p = newnode(T_ID); p->value.sval = lexval.sval; return(p);}

Pnode intconstnode(){ Pnode p; p = newnode(T_INTCONST); p->value.ival = lexval.ival; return(p);}

Pnode strconstnode(){ Pnode p; p = newnode(T_STRCONST); p->value.sval = lexval.sval; return(p);}

Pnode boolconstnode(){ Pnode p; p = newnode(T_BOOLCONST); p->value.bval = lexval.bval; return(p);}

int main(){ yyin = stdin; parse(); treeprint(root, 0); return(0);}

Page 29: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (iii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 29

void parse(){ next(); root = nontermnode(NPROGRAM); root->child = program();}

Pnode program(){ Pnode head, p; head = p = nontermnode(NSTAT); p->child = stat(); while (lookahead == DEF || lookahead == ID) { p->brother = nontermnode(NSTAT); p = p->brother; p->child = stat(); } return(head);}

program stat { stat }

program

root

stat stat stat stat

head p

Page 30: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (iv)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 30

stat def-stat | assign-statPnode stat(){ Pnode p;

if (lookahead == DEF) { p = nontermnode(NDEF_STAT); p->child = def_stat(); return(p); } else if (lookahead == ID) { p = nontermnode(NASSIGN_STAT); p->child = assign_stat(); return(p); } else parserror();}

stat

def-stat

stat

assign-stat

p p

Page 31: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (v)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 31

Pnode def_stat(){ Pnode p;

match(DEF); if (lookahead == ID) { p = idnode(); next(); match('('); p->brother = nontermnode(NDEF_LIST); p->brother->child = def_list(); match(')'); return(p); } else parserror();}

def-stat def id ( def-list )

def-stat

id def-list

p

Page 32: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (vi)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 32

Pnode def_list(){ Pnode head, p;

if (lookahead == ID) { head = p = idnode(); next(); match(':'); p->brother = nontermnode(NDOMAIN); p = p->brother; p->child = domain(); while(lookahead == ',') { next(); if ( lookahead == ID) { p->brother = idnode(); p = p->brother; next(); match(':'); p-> brother = nontermnode(NDOMAIN); p = p->brother; p->child = domain(); } else parserror(); } return(head); } else parserror();}

def-list id : domain { , id : domain }

def-list

id domain id domain

head

Page 33: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (vii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 33

domain integer | string | booleanPnode domain(){ Pnode p;

if (lookahead == INTEGER || lookahead == STRING || lookahead == BOOLEAN) { p = keynode( lookahead == INTEGER ? T_INTEGER : ( lookahead == STRING ? T_STRING : T_BOOLEAN)); next(); return(p); } else parserror();}

integer

domain

string

domain

boolean

domain

p p p

Page 34: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (viii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 34

Pnode assign_stat(){ Pnode head, p;

if (lookahead == ID) { head = p = idnode(); next(); match(ASSIGN); match('{'); while ( lookahead == '(') { p->brother = nontermnode(NTUPLE_CONST); p = p->brother; p->child = tuple_const(); } match('}'); } else parserror(); return(head);}

assign-stat id := { { tuple-const } }

assign-stat

id tuple-const tuple-const

head

Page 35: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (ix)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 35

Pnode tuple_const(){ Pnode head, p;

match('('); head = p = nontermnode(NSIMPLE_CONST); p->child = simple_const(); while (lookahead == ',') { next(); p->brother = nontermnode(NSIMPLE_CONST); p = p->brother; p->child = simple_const(); } match(')'); return(head);}

tuple-const ( simple-const {, simple-const } )

tuple-const

simple-const simple-const

head

Page 36: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

parser.c (x)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 36

simple-const intconst | strconst | boolconst

Pnode simple_const(){ Pnode p;

if (lookahead == INTCONST) { p = intconstnode(); next(); return(p); } else if (lookahead == STRCONST) { p = strconstnode(); next(); return(p); } else if (lookahead == BOOLCONST) { p = boolconstnode(); next(); return(p); } else parserror();}

intconst

simple-const

strconst

simple-const

boolconst

simple-const

p p p

Page 37: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

tree.c

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 37

#include "def.h"

char* tabtypes[] ={"INTEGER","STRING","BOOLEAN","INTCONST","BOOLCONST","STRCONST", "ID","NONTERMINAL"};

char* tabnonterm[] ={ "PROGRAM", "STAT", "DEF_STAT", "DEF_LIST", "DOMAIN", "ASSIGN_STAT", "TUPLE_CONST", "SIMPLE_CONST"};

void treeprint(Pnode root, int indent){ int i; Pnode p; for(i=0; i<indent; i++) printf(" "); printf("%s", (root->type == T_NONTERMINAL ? tabnonterm[root->value.ival] : tabtypes[root->type])); if(root->type == T_ID || root->type == T_STRCONST) printf(" (%s)", root->value.sval); else if(root->type == T_INTCONST) printf(" (%d)", root->value.ival); else if(root->type == T_BOOLCONST) printf(" (%s)", (root->value.ival == TRUE ? "true" : "false")); printf("\n"); for(p=root->child; p != NULL; p = p->brother) treeprint(p, indent+1);}

valore lesicale

Page 38: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

makefile

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 38

syntax: syntax.occ -g -o syntax syntax.o

tds: scanner.o parser.o tree.occ -g -o tds scanner.o parser.o tree.o

tdl: lexer.o parser.o tree.occ -g -o tdl lexer.o parser.o tree.o

lexer.o: lexer.c def.hcc -g -c lexer.c

scanner.o: scanner.c def.hcc -g -c scanner.c

syntax.o: syntax.c def.hcc -g -c syntax.c

parser.o: parser.c def.hcc -g -c parser.c

tree.o: tree.c def.hcc -g -c tree.c

lexer.c: lexer.lex def.hflex -o lexer.c lexer.lex

Page 39: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Esecuzione

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 39

PROGRAM STAT DEF_STAT ID (R) DEF_LIST ID (A) DOMAIN INTEGER ID (B) DOMAIN STRING ID (C) DOMAIN BOOLEAN STAT DEF_STAT ID (S) DEF_LIST ID (D) DOMAIN INTEGER ID (E) DOMAIN STRING STAT ASSIGN_STAT ID (R) TUPLE_CONST SIMPLE_CONST INTCONST (3) SIMPLE_CONST STRCONST ("alpha") SIMPLE_CONST BOOLCONST (true) TUPLE_CONST SIMPLE_CONST INTCONST (5) SIMPLE_CONST STRCONST ("beta") SIMPLE_CONST BOOLCONST (false) STAT ASSIGN_STAT ID (S) TUPLE_CONST SIMPLE_CONST INTCONST (125) SIMPLE_CONST STRCONST ("sun") TUPLE_CONST SIMPLE_CONST INTCONST (236) SIMPLE_CONST STRCONST ("moon")

def R (A: integer, B: string, C: boolean)def S (D: integer, E: string)R := {(3, "alpha", true)(5, "beta", false)}S := {(125, "sun")(236, "moon")}

Page 40: Analisi Sintattica Top-down...Analisi Sintattica Top-down (ii) Generazione dell'albero (» derivazione): iniziando dalla radice = assioma, ripetizione di: 1) Al nodo n marcato da A

Esecuzione (ii)

Tecnologie dei Linguaggi Artificiali 5. Analisi sintattica top-down 40

def People (name: string, surname: string, age: integer)People := {("Ann", "White", 24)("Louis", "Red", 40)("Lisa", "Green", 56)}

PROGRAM STAT DEF_STAT ID (People) DEF_LIST ID (name) DOMAIN STRING ID (surname) DOMAIN STRING ID (age) DOMAIN INTEGER STAT ASSIGN_STAT ID (People) TUPLE_CONST SIMPLE_CONST STRCONST ("Ann") SIMPLE_CONST STRCONST ("White") SIMPLE_CONST INTCONST (24) TUPLE_CONST SIMPLE_CONST STRCONST ("Louis") SIMPLE_CONST STRCONST ("Red") SIMPLE_CONST INTCONST (40) TUPLE_CONST SIMPLE_CONST STRCONST ("Lisa") SIMPLE_CONST STRCONST ("Green") SIMPLE_CONST INTCONST (56)


Recommended