Lexikální analýza

Post on 02-Jan-2016

32 views 0 download

description

Lexikální analýza. Miroslav Beneš Dušan Kolář. Rozhraní lexikálního analyzátoru. Úkoly. Čtení zdrojového textu Sestavování symbolů Odstranění mezer a poznámek Normalizace symbolů (velká/malá písmena, spec. znaky, ...) Interpretace direktiv překladače Uchovávání informací pro hlášení chyb - PowerPoint PPT Presentation

transcript

Lexikální analýza

Miroslav Beneš

Dušan Kolář

Lexikální analýza 2

Rozhraní lexikálního analyzátoru

Lexikální analýza 3

Úkoly

Čtení zdrojového textu Sestavování symbolů Odstranění mezer a poznámek Normalizace symbolů (velká/malá písmena,

spec. znaky, ...) Interpretace direktiv překladače Uchovávání informací pro hlášení chyb Zobrazení protokolu o překladu

Lexikální analýza 4

Proč řešit lexikální analýzu samostatně?

Jednodušší návrh překladače Konvence pro mezery a poznámky

Vyšší efektivita Specializované algoritmy

Lepší přenositelnost Zvláštnosti vstupní abecedy ??( = [

Lexikální analýza 5

Základní pojmy

Lexém – slovo nad abecedou Kategorie symbolů – identifikátor, číslo,

relační operátor, levá závorka, ... Atributy symbolu – řetězec, hodnota, kód

operátoru, ... Reprezentace symbolu – dvojice (kategorie,

atribut)

Lexikální analýza 6

Příklady lexikálních symbolů

Symbol Lexém Vzor

const const const

relation <, <=, …, >= <>

id {ltr}({ltr}|{dig})* pi, D2

num {dig}+ 0, 123

Lexikální analýza 7

Reprezentace symbolů// kategorie symbolůenum Symbol { IdSym, NumSym, RelOpSym, DotSym, ... };

// kategorie operátorůenum Oper { LthOp, GthOp, LeqOp, ... };

// atributy symbolůunion LexAttr { char* id; int num; Oper relop; ...};

// reprezentace lexikálního symbolustruct Token { Symbol sym; // kategorie LexAttr attr; // atribut};

Lexikální analýza 8

Problémy se zdrojovým jazykem

Pevný/volný formát (FORTRAN) 12 X=7 * +12*K C poznámka

Zpracování mezer (FORTRAN, Basic) DO5I=1.25 / DO5I=1,25

Klíčová slova (PL/I) IF THEN THEN THEN=ELSE; ELSE ELSE=THEN

Lexikální analýza 9

Příklad

1 INTEGER FUNCTIONA 2 PARAMETER(A=6,B=2) 3 IMPLICIT CHARACTER*(A-B)(A-B) 4 INTEGER FORMAT(10),IF(10),DO9E1 5 100 FORMAT(4H)=(3) 6 200 FORMAT(4 )=(3) 7 DO9E1=1 8 DO9E1=1,2 9 IF(X)=1 ...

Lexikální analýza 10

Příklad (pokr.)

10 IF(X)H=1 11 IF(X)300,200 12 300 CONTINUE 13 END C this is a comment $FILE(1) 14 END

Lexikální analýza 11

Specifikace symbolů

Popis běžným jazykem ‘identifikátor je posloupnost písmen a číslic

začínající písmenem’ Regulární (lineární) gramatika

I -> p X X -> p X | c X | p | c

Regulární výrazy a definice p (p | c)*

Lexikální analýza 12

Specifikace symbolů

Graf přechodů konečného automatu (syntaktický graf)

Lexikální analýza 13

Specifikace symbolů

Lexikální symboly lze obvykle popsat regulárními jazyky (typ 3)

Co nedokážeme popsat? Zanořené konstrukce (závorky) Opakované konstrukce {wcw|w{a,b}*} Zadaný počet opakování

nHa1a2…an (FORTRAN)

Lexikální analýza 14

Regulární výrazy nad

RE označuje {} (prázdný řetězec) Je-li a, pak a označuje {a} Je-li a,b,c,…, pak [abc…] označuje

množinu {a, b, c, …} [aeiouy] [a-zA-Z] [^0-9] – všechno kromě [0-9]

Lexikální analýza 15

Regulární výrazy

Jsou-li s, t reg. výrazy označující jazyky L(s) a L(t), pak (s) | (t) L(s) L(t) (s) (t) L(s) L(t) (s)* (L(s))* (s)+ (L(s))+ = L(s) (L(s))* (s)? L(s) {} (s) L(s)

Lexikální analýza 16

Příklad

[A-Z]([A-Z]|[0-9])* [A-Z][A-Z0-9]* [0-9]+.[0-9]+(E[-+]?[0-9]+)?

| [0-9]+E[-+]?[0-9]+

Lexikální analýza 17

Regulární definice

Pojmenované regulární výrazy d1 -> r1

d2 -> r2

...

dn -> rn

různá reg. výrazy nadjména {d1, d2,…, di-1}

Lexikální analýza 18

Regulární definice

letter -> [A-Za-z] digit -> [0-9] id -> letter (letter | digit)*

Použití: konstruktory lex. analyzátorů

Lexikální analýza 19

Konečné automaty

(Q, , f, q0, F) Q – konečná množina stavů - vstupní abeceda f – přechodová funkce q0 – počáteční stav F – množina koncových stavů

f: Q x ( {e}) -> 2Q rozšířený NKA f: Q x -> Q DKA

Lexikální analýza 20

Konečné automaty

desítkové číslo

šestnáctkové číslo

Lexikální analýza 21

Konečné automaty

NKA

Lexikální analýza 22

Konečné automaty

deterministický konečný automat

Lexikální analýza 23

Algoritmy pro transformaci

Reg. gramatika ↔ konečný automat korespondence pravidel gramatiky a přechodové

funkce Reg. výraz → konečný automat

skládání primitivních KA, převod na DKA, minimalizace

stromová reprezentace důležité pro konstruktory lex. analyzátorů

Lexikální analýza 24

Algoritmy pro transformaci

Konečný automat → reg. výraz soustava algebraických rovnic

X = a X + b X = a* b derivace reg. výrazu

Lexikální analýza 25

Konečný automatpro lexikální analýzu

Zpracování začíná vždy prvním dosud nezpracovaným znakem ze vstupu

Zpracování končí, je-li automat v koncovém stavu a pro další vstupní znak již neexistuje žádný přechod (maximal match): 123 není 12 následované 3

Není-li v nekoncovém stavu přechod možný, vrací se automat do posledního dosaženého koncového stavu nebo je chyba: < <= << 1. 1.2 1..5

Lexikální analýza 26

Speciální případy

akce po přijetí symbolu samostatný koncový stav pro každou kategorii výpočet hodnot atributů z lexému

klíčová slova koncový stav pro každé klíčové slovo – mnoho

stavů obvykle jako id, pak následuje rozlišení tabulkou

klíč. slov

Lexikální analýza 27

Speciální případy

komentáře uzavřená cesta procházející poč. stavem diagnostika – neukončený komentář dokumentační komentář – Javadoc zanořené komentáře

znakové řetězce escape sekvence ‘\n’ ukončení řádku v řetězci je obvykle chyba Unicode

Lexikální analýza 28

Implementace lexikálního analyzátoru Přímá

Efektivita na úkor složitosti návrhu Stav je reprezentován pozicí v programu

Simulace konečného automatu Vhodné spíš pro konstruktory

Využití konstruktoru Snadná modifikovatelnost Především v počátečních fázích implementace

Lexikální analýza 29

Přímá implementace

char text[256];

int leng, ival;

int lex(void) {

int ch;

START:

while((ch=getchar())==‘ ‘) ;

/* odstranění mezer */

Lexikální analýza 30

Přímá implementace

if( isalpha(ch) ) {

leng = 0;

do {

text[leng++] = ch;

} while( isalnum(ch=getchar()) );

text[leng] = ‘\0’;

ungetc(ch,stdin);

return(IDENT);

}

Lexikální analýza 31

Přímá implementace

else if( isdigit(ch) ) { ival = 0; do { ival = 10*ival+(ch-’0’); } while( isdigit(ch=getchar()) );

ungetc(ch,stdin); return(NUM); }

Lexikální analýza 32

Přímá implementace

else if (ch==‘{‘) {

while( (ch=getchar())!=‘}’ && ch!=EOF);

if( ch==EOF ) {

error(“Missing end of comment”);

return(EOF);

}

goto START;

}

else return(ch); /* ostatní znaky */

}

Lexikální analýza 33

Přímá implementace

getchar() čte znaky ze vstupu udržuje aktuální číslo řádku kopie zdrojového textu do protokolu správa vyrovnávacích pamětí makrogenerátor (např. C, C++)

ungetc() vrací zpět jeden nebo více znaků Java: java.io.PushbackInputStream

Lexikální analýza 34

Implementace konečného automatu

Tabulka + Přechodová funkce + Interpret výhodné jako výstup konstruktoru

Přímý přepis do programu

Lexikální analýza 35

Implementace konečného automatu

static int state;

int next(int newstate) { state = newstate; return getchar();}

int lex(void) { int ch = next(0);

Lexikální analýza 36

Implementace konečného automatu

for(;;) switch(state) { case 0: if (ch==‘ ‘) ch = next(0); else if( isalpha(ch) ) { leng = 0; text[leng]=ch; ch = next(1); }

Lexikální analýza 37

Implementace konečného automatu

/* case 0: */ else if (isdigit(ch)) { ival = ch-’0’; ch = next(2); } else if (ch==‘{‘) ch = next(3);

else return(ch); break;

Lexikální analýza 38

Implementace konečného automatu

case 1:

if (isalnum(ch)) {

text[++leng] = ch;

ch = next(1);

}

else {

text[++leng] = ‘\0’;

unget(ch,stdin);

return(IDENT);

}

break;

Lexikální analýza 39

Implementace konečného automatu

Lexikální analýza 40

Implementace konečného automatu

case 3:

if (ch==EOF) {

error(“Missing end of comment”);

return(EOF);

}

else if (ch==‘}‘) ch = next(0);

else ch = next(3);

break;

}

}

Lexikální analýza 41

Konstruktor LEX / FLEX

%{

#include <stdlib.h>

#define IDENT 256

#define NUM 257

int yyival;

%}

Lexikální analýza 42

Konstruktor LEX / FLEX

space [ \t\n]

ws {space}+|\{[^}]*\}

letter [A-Za-z]

digit [0-9]

id {letter}({letter}|{digit})*

number {digit}+

%%

Lexikální analýza 43

Konstruktor LEX / FLEX

{ws} {/* no action, no return */}

{id} return(IDENT);

{number} {

yyival=atoi(yytext);

return(NUM);

}

. return(yytext[0]);