Title: Leksine analize (skenavimas)
1Leksine analize (skenavimas)
DO 10 I 1,5 DO 10 I 1.5
- Pirmasis teksto supratimo
- žingsnis atpažinti žodžius
- Vienu iš pagrindiniu leksinio analizatoriaus
užduociu, yra išskirti programos tekste tokenus - tokenas yra leksemu rušis (tokenas gali buti
simboliu, operatoriumi, identifikatoriumi ar
raktiniu žodžiu), tai simboline konstanta. - komentarai ir tušti tarpai atmetami.
Leksinis analizatorius
Programos tekstas
Tokenu srautas
2Leksine analize (skenavimas)Pavyzdys
sum oldsum value / 100
Tokenas IDENTIFIER ASSIGN_OP IDENTIFIER SUBTRACT_O
P IDENTIFIER DIVISION_OP INIT_LITERAL SEMICOLON
Leksema sum oldsum - value / 100
3Kaip aprašyti tokenus?
- Šablonas tai taisykle aprašanti tokena
atitinkancias leksemas. - Šioms taisyklems aprašyti yra sukurtas specialus
žymejimas reguliarios išraiškos. - Programavimo kalbos atominiai vienetai tokenai
yra aprašomi reguliariomis išraiškomis - Tarp tokenu reikia moketi išskirti rezervuotus
žodžius, jei kalboje nera rezervuotu žodžiu,
leksine analize tampa labai sudetinga - Pavyzdžiui PL/I kalba
- IF THEN THEN THEN ELSE
- ELSE ELSE THEN
- FORTRAN kalba.
4Kalba (apibrežimai)
- Terminas alfabetas žymi bet kokia baigtine
simboliu aibe. - Aibe 0, 1 yra binarinis alfabetas
- ASCII, EBCDIC yra kompiuteriniai alfabetai
- Alfabeto eilute, tai baigtine alfabeto simboliu
seka. - Kalba, tai bet kokia alfabeto eiluciu aibe.
- tušcia aibe irgi kalba!
- tušciu eiluciu aibe e irgi kalba!
- visi lietuviu kalbos sakiniai irgi sudaro kalba.
5Operacijos su kalbomis
- Kalbu L ir M junginys LUMss?L arba s?M
- Kalbu L ir M konkatenacija LMsts?L ir t?M
- Kalbos L Kleene uždarinys LUi08Li
- tai nulis arba daugiau konkatenaciju
- Kalbos L teigiamas uždarinys LUi18Li
- tai viena arba daugiau konkatenaciju
- cia L0e, LiLi-1L.
6Kalbu kurimo pavyzdžiai
- Tegu LA,B,...,Z,a,b,...,z ir M0,1,2,...,9
- Kadangi simboli galima laikyti vienetinio ilgio
eilute, aibes L ir M yra baigtines kalbos. - LUM yra raidžiu ir skaiciu aibe
- LM yra aibe eiluciu sudarytu iš raides po kuria
seka skaicius - L4 tai visu keturraidžiu eiluciu aibe
- L aibe eiluciu iš visu raidžiu, tame tarpe ir
tušcia eilute e - L(LUM) aibe eiluciu iš raidžiu ir skaiciu
prasidedanti raide - M aibe eiluciu sudarytu iš vieno ir daugiau
simboliu
7Reguliarios išraiškos
- Daugumos programavimo kalbu leksine struktura
gali buti apibrežta reguliariomis išraiškomis. - Reguliarios išraiškos yra apibrežiamos virš tam
tikro (nustatyto) alfabeto S - Dauguma programavimo kalbu alfabetu naudoja ASCII
arba Unicode - Jei re yra reguliari išraiška, tuomet L(re ) yra
re sugeneruota kalba (simboliniu eiluciu rinkinys)
8Reguliarios išraiškos
- Reguliari išraiška apibrežiama tam tikromis
taisyklemis. - tušcia eilute e yra reguliari išraiška
- simbolis, pavyzdžiui a yra reguliari išraiška
- Jei R ir S yra reguliarios išraiškos, tai
reguliaria išraiška bus ir - RS (reiškia R arba S)
- RS (konkatenacija)
- R (nulis arba daug R tarpusavio konkatenaciju)
- (R) (reguliarias išraiškas galima grupuoti)
- Reguliarias išraiškas galima ivardinti vardas ?
r
9Kalbu generavimo taisykles
re L(re ) Pastabos
RS L(R)L(S) konkatenacija
RS L(R)UL(S) junginys
R L(R) Kleene uždarinys
10Pavyzdžiai (1)
- Reguliari išraiška ab reiškia aibe a,b
- Reguliari išraiška (ab)(ab) reiškia aibe
aa,ab,ba,bb aibe visu eiluciu iš a ir b,
kuriu ilgis 2. - Kita šiai aibei atitinkanti reguliari išraiška
aaabbabb - Reguliari išraiška a reiškia aibe
e,a,aa,aaa,... - Reguliari išraiška (ab) reiškia aibe visu
galimu eiluciu iš a ir b e,a,b,aa,ab,bb,... - Kita šiai aibei atitinkanti reguliari išraiška
(ab)
11Pavyzdžiai (2)
- Reguliari išraiška aab reiškia aibe turincia a
ir eilutes turincias nuli ar daugiau a ir
besibaigiancias b - Reguliari išraiška ba reiškia aibe
b,ba,baa,baaa,... - Reguliari išraiška ab reiškia aibe
b,e,a,aa,aaa,... - (01)1 reiškia aibe binariniu skaiciu
besibaigianciu 1
12Algebrines reguliariu išraišku savybes
- rssr operatorius komutatyvus
- r(st)(rs)t operatorius asociatyvus
- (rs)tr(st) konkatenacija asociatyvi
- r(st)rsrt, (st)rsrtr konkatenacija
distributyvi operatoriaus atžvilgiu - err, rer konkatenacijos atžvilgiu, e yra
vienetinis elementas - r(re) - ryšys tarp ir e
- rr
13Pavyzdžiai
- Paskalio identifikatoriu apibrežianti reguliari
išraiška - letter ? AB...Zab...z
- digit ? 0123456789
- id ? letter(letterdigit)
- Skaicius (pvz. 1.89E-4) apibrežianti reguliari
išraiška - digit ? 01...9
- digits ? digit digit
- optional_fraction ? .digitse
- optional_exponent ? (E(-e)digits)e
- num ? digits optional_fraction optional_exponent
14Sutrumpinimai
- R (vienas ar daugiau R)
- a aprašo visas eilutes sudarytas iš vieno ar
daugiau a simboliu a, aa, aaa, ... - r re, r rr
- R? (nulis arba vienas R)
- r? re
- a-z, A-Z, 0-9 (sutrumpintas simboliu klases
žymejimas) - abc abc
- a-z ab...z
- Paskalio identifikatorius A-Za-z A-Za-z0-9
15Pavyzdys
- Skaicius (pvz. 1.89E-4) apibrežianti reguliari
išraiška, naudojanti sutrumpinimus - digit ? 0-9
- digits ? digit
- optional_fraction ? (.digits)?
- optional_exponent ? (E(-)?digits)?
- num ? digits optional_fraction optional_exponent
16Prioritetai
- Operatoriai , ir ? turi aukšciausia
prioriteta. - Konkatenacijos prioritetas žemesnis.
- turi žemiausia prioriteta.
- Visi operatoriai yra asociatyvus iš kaires.
- Pavyzdžiui, šiu susitarimu deka išraiška
(a)((b)(c)) yra ekvivalenti abc - Tai aibe eiluciu kurias sudaro arba vienintelis
a, arba nulis arba keletas b, po kuriu seka
vienintelis c.
17Leksiniu analizatoriu istorija
- LEX
- Leksinis analizatorius sukurtas Lesk ir Schmidt
iš Bell Labs 1975 UNIX operacinei sistemai - Šiuo metu egzistuoja daugumoje operaciniu sistemu
- LEX generuoja leksini analizatoriu - C kalba
parašyta programa - LEX nurodytoms reguliarioms išraiškoms igalina
atlikti nurodytas veikas - JLex
- sukurtas Elliot Berk iš Princeton University 1996
- tai Lex generuojantis leksini analizatoriu - Java
kalba parašyta programa - JLex pats parašytas Java kalba
18JLexveikla
Tokenu apibrežimas Reguliarios Išraiškos
JLex
Java Failas Scanner Class (Yylex, leksine
analize atlieka metodas yylex()) Tokenu
atpažinimas
Regular expression? NFA? DFA? lexer
19JLex aprašymo failo struktura
- vartotojo kodas (user code)
-
- JLex direktyvos (JLex directives)
-
- reguliariu išraišku taisykles (regular expression
rules) - Komentarai
- prasideda //
- arba keletui eiluciu / / galimi tik pirmose
dvejose dalyse
20vartotojo kodas
- JLex suteikia vartotojui galimybe, esant
reikalui, panaudoti savo parašyta programini
koda. - Vartotojo kodas bus be pakeitimu irašytas i JLex
išvesties faila, pacioje jo pradžioje. - Dažniausiai tai buna
- paketu deklaracijos
- import deklaracijos
- Papildomos, vartotojo parašytos klases
21JLex direktyvos
- Šiame skyriuje pateikiami
- makrosu apibrežimai (macro definitions)
reguliariu išraišku sutrumpinti pavadinimai - naudojami apibrežti kas yra raides, skaiciai ir
tušti tarpai. - busenu deklaracijos
- analizatoriaus savybiu pasirinkimai
- standartines leksinio analizatoriaus klases
papildymai - Kiekviena JLex direktyva turi buti užrašoma
atskiroje eiluteje ir turi pradeti ta eilute.
22Reguliariu išraišku taisykles
- Ši skyriu sudaro taisykliu rinkinys nurodantis
kaip suskaidyti ivesties srauta i tokenus. - Reguliariu išraišku taisykles yra sudarytos iš
triju daliu - busenu sarašas (nebutinas)
- reguliari išraiška
- susieta veika (Java kodo fragmentai)
- Kiekviena veika turi gražinti reikšme apibrežta
type deklaracijoje esancioje antrojoje JLex
aprašo dalyje. - Jei veika nieko negražina, einamasis tokenas
atmetamas ir leksinis analizatorius dar karta
iškviecia pats save.
ltbusenosgt ltreg. išraiškagt ltveikagt
23JLex direktyvos (1)
- Direktyva ... leidžia vartotojui irašyti Java
koda tiesiai i leksinio analizatoriaus klase. - Direktyvos naudojimo pavyzdys
-
- ltkodasgt
-
- JLex irašys Java koda i sukuriama leksinio
analizatoriaus klase - class Yylex
- ... ltkodasgt ...
-
- Tai leidžia aprašyti papildomus vidinius leksinio
analizatoriaus klases kintamuosius ir metodus. - Pažymetina, kad negalima naudoti kintamuju vardu
prasidedanciu yy tokius vardus naudoja pati
leksinio analizatoriaus klase.
24JLex direktyvos (2)
- Direktyva init ... init leidžia vartotojui
irašyti Java koda tiesiai i leksinio
analizatoriaus klases konstruktoriu - init
- ltkodasgt
- init
- JLex irašys Java koda i sukuriama leksinio
analizatoriaus klases konstruktoriu - class Yylex
- Yylex ()
- ... ltkodasgt ...
-
- Ši direktyva leidžia atlikti papildoma leksinio
analizatoriaus klases inicializacija.
25JLex direktyvos (3)
- Makrosu paskirtis
- viena karta apibrežus reguliaria išraiška, toliau
atitinkamose vietose galima naudoti tik jos varda
(daugeli kartu). - Praktiškai butini didesnems reguliarioms
išraiškoms. - Makrosu apibrežimo formatas
- ltvardasgt ltapibrežimasgt
- Makroso vardas yra identifikatorius, t.y. gali
buti sudarytas iš raidžiu, skaitmenu ir apatiniu
brukšniu, bei turi prasideti raide arba apatiniu
brukšniu. - Makroso apibrežimas turi buti teisingai užrašyta
reguliari išraiška. - Makrosu apibrežimuose gali buti panaudoti kiti
makrosai - ltvardasgt
26JLex direktyvos (4)
- Leksiniu busenu pagalba kontroliuojamas
reguliariu išraišku atitikimas. - Leksiniu busenu deklaravimo formatas
- state state0, state1, state2, ...
- Leksines busenos vardas turi buti
identifikatorius. - Pagal nutylejima JLex pats deklaruoja viena
busena - YYINITIAL, kuria sukurtas leksinis
analizatorius pradeda leksine analize. - Jei busenu sarašas nenurodytas, reguliarios
išraiškos atitikimas neribojamas. - Jei busenu sarašas nurodytas, reguliariai
išraiškai bus leidžiama atitikti tik tuomet, jei
leksinis analizatorius bus vienoje iš nurodytu
busenu. - Busenu vardai turi buti unikalus tam tikslui
patartina juos pradeti didžiaja raide.
27JLex direktyvos (5)
- JavaCUP sintaksinio analizatoriaus generatorius
Java kalbai buvo sukurtas Scott Hudson iš Georgia
Tech universiteto, ir išvystytas Frank Flannery,
Dan Wang, ir C. Scott Ananian pastangomis. - Smulkiau apie ši iranki http//www.cs.princeton.e
du/appel/modern/java/CUP/ - Suderinamumas su JavaCUP aktyvuojamas sekancia
JLex direktyva - cup
28Simboliu ir eiluciu skaiciavimo direktyvos
- Kartais naudinga žinoti kur tekste yra tokenas.
Tokeno padetis nusakoma jo eilutes ir jo pirmojo
simbolio eiles numeriu tekste. - Simboliu skaiciavimas aktyvuojamas direktyva
char - Sukuriamas kintamasis yychar (leks.
analizatoriaus) - jo reikšme pirmojo atitikusioje šablona
leksemoje simbolio eiles numeris. - Eiluciu skaiciavimas aktyvuojamas direktyva
line - Sukuriamas kintamasis yyline
- jo reikšme atitikusios šablona simbolines
eilutes pirmosios eilutes eiles numeris. - Pavyzdys
- int return (new Yytoken(4,yytext(),yyline,yyc
har,yychar3))
29Reguliariu išraišku taisykles
- Jei nuskaitymo metu simbolinei eilutei atitinka
keletas taisykliu, jos skaidymas i tokenus vyksta
pagal ta taisykle, kuri atitinka ilgiausia
tokena. - Jei keletas taisykliu atitinka to pacio ilgio
simboline eilute, pasirenkama ta taisykle, kuri
JLex aprašyme yra pirmoji (ankstesnes taisykles
turi aukštesni prioriteta). - JLex aprašyme reikia numatyti reguliarias
taisykles visiems galimiems atvejams. - Jei leksinio analizatoriaus ivestis neatitiks
jokiai aprašytai taisyklei, leksinis
analizatorius nutrauks darba. - Galima apsidrausti, JLex aprašymo pabaigoje
patalpinus sekancia taisykle - . java.lang.System.out.println("Unmatched
input " yytext()) - Cia taškas (.) nurodo atitikima bet kokiai
ivesciai, išskyrus nauja eilute (newline).
30Reguliarios išraiškos (1)
- JLex alfabetas yra ASCII simboliai nuo 0 iki 127
imtinai. - Šie simboliai yra reguliarios išraiškos patys
sau. - Reguliariose išraiškose negalima tiesiogiai
naudoti tarpu - tarpas laikomas reguliarios
išraiškos pabaiga. - Jei tušcias tarpas reikalingas reguliarioje
išraiškoje, ji reikia nurodyti tarp dvigubu
kabuciu " " - Sekantys simboliai yra meta simboliai, turintys
JLex reguliariose išraiškose specialia reikšme - ? ( ) . " \
31Reguliarios išraiškos (2)
- ef viena po kitos einancios reguliarios išraiškos
reiškia ju konkatenacija. - ef vertikalus brukšnys nurodo kad atitikti
gali arba išraiška e arba f. - \b reiškia Backspace
- \n reiškia newline
- \t reiškia Tab
- \f reiškia Formfeed
- \r reiškia Carriage return
- \C reiškia Control character
- \c - bet koks simbolis po \ reiškia save pati.
32Reguliarios išraiškos (3)
- žymi eilutes pabaiga.
- Jei reguliari išraiška baigiasi jos atitikimas
tikrinamas tik eilutes pabaigoje (t.y. iš kito
galo). - . atitinka bet koki simboli išskyrus nauja
eilute. - Taigi, ši išraiška ekvivalenti \n.
- "..." metasimboliai tampa paprastais simboliais
dvigubose kabutese. - Pažymesime, kad \" reiškia simboli "
- vardas nurodo cia bus išskleistas makrosas su
nurodytu vardu. - pažymi Kleene uždarini nurodanti nuli ar
daugiau reguliarios išraiškos pasikartojimu. - nurodo viena ar daugiau reguliarios išraiškos
pasikartojimu.Taigi e yra ekvivalenti ee - ? nurodo, kad reguliari išraiška gali buti
taikoma arba ne.
33Reguliarios išraiškos (4)
- (...) skliaustai naudojami reguliariu išraišku
grupavimui. - ... pažymi simboliu klase - reguliari išraiška
atitinka visiems klases simboliams. - Jei pirmasis simbolis ... yra (), tai nurodo
kad reguliari išraiška atitinka visiems
simboliams išskyrus nurodytus skliaustuose. - Pavyzdžiui,
- a-z atitinka visas mažasias raides,
- 0-9 atitinka viska išskyrus skaicius,
- \-\\ atitinka -\,
- "A-Z" atitinka tris simbolius A-Z,
- - ir - atitinka ir -.
34Pavyzdžiai
- ab atitinka ab bet ne a arba b
- main atitiks leksema main tik tuomet kai ji
bus eilutes pradžioje. - main atitiks leksema main tik tuomet kai ji
bus eilutes pabaigoje. - a bc yra ekvivalentus a" "bc
35Susieta veika (action)
- Ši veika atliekama kai nurodytas šablonas yra
atpažystamas - Veika, tai Java sakiniai (standartiniai)
gražinantys tokenus.
36Leksinis analizatorius
- JLex taisyklingai parašyta apraša transformuoja i
java programa vardu Yylex. - Ši klase turi du konstruktorius turincius viena
argumenta - ivesties srauta (input stream) kuri
reikia išskaidyti i tokenus. - Ivesties srautas gali buti atitinkamai arba
java.io.InputStream, arba java.io.Reader
(pavyzdžiui StringReader). - Konstruktorius java.io.Reader naudojamas jei
ivesties sraute gali buti unicode simboliu. - Sekanti tokena iš ivesties srauto gražina
leksinio analizatoriaus metodas Yylex.yylex(). - Gražinamos reikšmes tipas yra Yytoken.
37Specialus JLex kintamieji/metodai
- yytext() gražina simboline eilute kuriai
leksinis analizatorius rado atitikmeni (galima
nustatyti šios simbolines eilutes semantine
reikšme) - t.y. tai tokeno, kuri gražina yylex() leksema
- yylength() gražina atitiktos simbolines eilutes
ilgi - yychar saugo atitiktos eilutes (matched string)
pradžios padeti faile - tokeno pradžia yychar
- tokeno pabaiga yychar yylength()
- yylex() paprastai gražina Yytoken klases
egzemplioriu, nors galima deklaruoti ir kita tipa
direktyva type
38Tokenai
- Paprastai kiekvienas tokenas yra klases Symbol iš
paketo - java_cup.runtime elementas. - Ši paketa eksportuoja analizatorius JavaCUP
- Symbol klaseje nustatomi sveiki skaiciai
atitinkantys kiekvienam tokenui. - Pavyzdžiui, cia aprašytos sveiko tipo konstantos,
tokios kaip sym.ID, sym.IF
39Reguliarios išraiškos pavyzdys
- reguliariIšraiška veika
- Pavyzdys
- IDENTIFIER System.out.println("ID is ..."
yytext()) - Prasme
- Pirmuosiuose skliaustuose šablonas, kurio
atitikmens ieškome - antruosiuose skliaustuose kodas, kuris bus
vykdomas jei atitikmuo bus rastas.
40Makrosu pavyzdžiai
- Apibrežimas (antroji JLex aprašymo dalis)
- IDENTIFIER a-zA-z_a-zA-Z0-9_
- LETTERA-Za-z_
- DIGIT0-9
- WHITESPACE \t\n
- ALPHA_NUMERICLETTERDIGIT
- Panaudojimas (trecioji JLex aprašymo dalis)
- IDENTIFIER return new Token(ID, yytext())
41Busenu deklaracijos (1)
- Kai kurioms simbolinems eilutems atitikmuo turi
buti ieškomas su skirtingomis reguliariomis
išraiškomis. - Taigi reikia tureti galimybe pervesti leksini
analizatoriu i ivairias busenas, kuriose jis
funkcionuotu skirtingai, t.y. naudotu kitas
reguliarias išraiškas. - Pradedamas darba leksinis analizatorius yra
busenoje YYINITIAL. - Jei norime naudoti savo busenas, aprašome jas
antrojoje JLex aprašo dalyje. - Pavyzdžiui state COMMENTS
- Perejimui tarp busenu naudojamas metodas
yybegin().
42Busenu deklaracijos (2)
- Pavyzdys
- ltYYINITIALgt "//" yybegin(COMMENTS)
- ltCOMMENTSgt \n
- ltCOMMENTSgt \n yybegin(YYINITIAL)
- Jei Yylex yra pradineje YYINITIAL busenoje ir
atpažysta //, tuomet jis pereina i busena
COMMENTS - Jei jis yra busenoje COMMENTS ir atpažysta bet
koki simboli išskyrus \n, tuomet jokia veika
neatliekama - Jei jis yra busenoje COMMENTS ir atpažysta \n,
tuomet jis grižta atgal i busena YYINITIAL
43minimal.lex
- package Example
- import java_cup.runtime.Symbol
-
- cup
-
- "" return new Symbol(sym.SEMI)
- "" return new Symbol(sym.PLUS)
- "" return new Symbol(sym.TIMES)
- "(" return new Symbol(sym.LPAREN)
- ")" return new Symbol(sym.RPAREN)
- 0-9 return new Symbol(sym.NUMBER, new
Integer(yytext())) - \t\r\n\f / ignore white space. /
- . System.err.println("Illegal character
"yytext())
44import java_cup.runtime.Symbol
- Ši eilute importuoja klase Symbol.
- Kai sintaksinis analizatorius iškviecia Yylex
sekanciam tokenui, Yylex objektas gražina Symbol
klases egzemplioriu.
45Symbol klase
- Symbol klases egzempliorius turi keleta
konstruktoriu. - "" return new Symbol(sym.PLUS)
- Paprasciausias naudoja tik tokeno eiles numeri
(t.y. viena iš sugeneruotos sym klases konstantu) - Šioms konstantoms vardus duodame mes patys, o
reikšmes priskiria JavaCUP generuodamas sym.java
faila. - 0-9 return new Symbol(sym.NUMBER,
- new Integer(yytext()))
- Sudetingesnis konstruktorius dar naudoja leksine
reikšme kuria apibrežia tam skirtas objektas - cia naudojamas Java objektas
- gali buti naudojamas ir musu sukurtos klases
objektas
46minimal.lex tokenams atitinkantys sveiki skaiciai
- //------------------------------------------------
---- - // The following code was generated by CUP v0.10k
- // Sat Oct 02 095656 EEST 2004
- //------------------------------------------------
---- - package Example
- / CUP generated class containing symbol
constants. / - public class sym
- / terminals /
- public static final int RPAREN 6
- public static final int error 1
- public static final int PLUS 3
- public static final int NUMBER 7
- public static final int SEMI 2
- public static final int LPAREN 5
- public static final int TIMES 4
- public static final int EOF 0
47Ivesties failo panaudojimas JLex/CUP
48Anglu kalbos gramatika
A sentence is a noun phrase, a verb, and a noun
phrase. A noun phrase is an article and a
noun. A verb is An article is A noun is...
ltSgt ltNPgt ltVgt ltNPgt ltNPgt ltAgt ltNgt ltVgt
loves hates eats ltAgt a theltNgt
dog cat rat
49Gramatikos taikymas
- Gramatika yra taisykliu rinkinys nusakantis kaip
sukonstruoti sintaksini medi a parse tree - Medžio šaknyje (root) patalpiname aukšciausia
hierarchijos elementa t.y. ltSgt - Gramatikos taisykles nusako kaip toliau yra
pridedami sekantys mazgai - vaikai. - Pavyzdžiui, taisykle ltSgt ltNPgt ltVgt ltNPgt parodo
kokia tvarka pridedami mazgai ltNPgt, ltVgt ir ltNPgt
t.y. ltSgt vaikai.
50start symbol
ltSgt ltNPgt ltVgt ltNPgt ltNPgt ltAgt ltNgt ltVgt
loves hateseats ltAgt a theltNgt
dog cat rat
a production
non-terminalsymbols
tokens
51A Parse Tree
ltSgt
ltNPgt ltVgt ltNPgt
ltAgt ltNgt
ltAgt ltNgt
loves
dog
cat
the
the
52Kontekstiškai laisva gramatika(Context free
grammar)
- Programavimo kalbu sintakse aprašoma
kontekstiškai laisvomis gramatikomis (CFG). - CFG taisykles yra daugumoje rekursyvios.
- Sintaksinis analizatorius tikrina, ar programa
tenkina CFG taisykles ar ne. Jei tenkina,
sintaksinis analizatorius kuria programai
sintaksini medi (parse tree) - CFG aprašomos (Backus Naur Form), pavyzdžiui
- assignment -gt identifier expression
- expression -gt identifier
- expression -gt number
- expression -gt expression expression
- T.y. sintaksinis analizatorius tikrina, ar
programa galima išvesti naudojantis nustatytos
gramatikos BNF
53Kontekstiškai laisvos gramatikos
- Kontekstiškai laisva gramatika sudaro
- V baigtinis neterminalu skaicius
- S baigtinis terminalu skaicius
- R Baigtinis taisykliu skaicius, kuriu bendra
forma neterminalas -gt neterminalas,
terminalas - S pradinis neterminalas
Dauguma programavimo kalbu yra kontekstiškai
laisvos
54Kontekstiškai laisvos gramatikos komponentai
Gramatika nusakoma išvardinant jos
produkcijas. Tokenu eilutes pagimdytos pradinio
simbolio sudaro gramatika apibrežta kalba.
- Tokenai (terminalai)
- Neterminalai
- Produkcijos
- Pradinis neterminalas
Pavyzdys list ? list digit list digit
digit digit ? 0123456789
55BNF gramatikos apibrežimas (1)
- BNF gramatika sudaro keturios dalys
- Tokenu rinkinys
- Non-terminal symbols rinkinys
- Pradinis simbolis (start symbol)
- Produkciju (productions) rinkinys
- Tokenai yra mažiausi (atominiai) sintakses
vienetai. - Neterminalai atstovauja stambesnius sintakses
vienetus - Vaizduojami nelygybiu skliaustuose
- gramatikos taisykles apibrežia kaip jie yra
išskleidžiami i tokenu literalus.
56BNF gramatikos apibrežimas (2)
- Satrtinis simbolis yra išskirtinis neterminalas
sudarantis atitnkamos gramatikos parse tree
šakni. - Produkcijos yra medžio konstravimo taisykles.
- Kiekviena turi kairiaja puse, skirtuka
(separator) ir dešiniaja puse. - Kairioji puse yra vienas neterminalas
- Dešiniaja puse gali sudaryti seka kurioje gali
buti kaip terminalai, taip ir neterminalai - Dešines puses nariu seka nusako kokia tvarka turi
buti konstruojamas parse tree.
57Hierarchines programos strukturos išreiškimo
rekursinemis taisyklemis pavyzdys
- Kiekvienas identifikatorius (identifier) yra
išraiška (expression). - Kiekvienas skaicius (number) yra išraiška
(expression). - Jei expression1 ir expression2 yra išraiškos, tai
išraiškomis yra ir - expression1 expression2
- expression1 expression2
- (expression1).
58Programavimo Kalbos Gramatika
ltexpgt ltexpgt ltexpgt ltexpgt ltexpgt ( ltexpgt
) a b c
- Išaiška gali buti (arba)
- dvieju išraišku suma
- dvieju išraišku sandauga
- apskliausta išraiška
- vienu iš kintamuju a, b arba c
59Pavyzdys
ltexpgt ltexpgt ltexpgt ltexpgt ltexpgt ( ltexpgt
) a b c
Šioje gramatikoje ištiesu yra šešios
produkcijos. T.y. viena ši produkcija yra
ekvivalenti šioms šešioms
ltexpgt ltexpgt ltexpgtltexpgt ltexpgt
ltexpgtltexpgt ( ltexpgt )ltexpgt altexpgt
bltexpgt c
60BNF Realiems skaiciams
ltreal-numbergt ltinteger-partgt .
ltfractiongt ltinteger-partgt ltdigitgt
ltinteger-partgt ltdigitgt ltfractiongt ltdigitgt
ltdigitgt ltfractiongt ltdigitgt 0 1 2
3 4 5 6 7 8 9
Realaus skaiciaus 21.89 išvedimas rašome
išraišku seka kuriose neterminalai žingsnis po
žingsnio keiciami keiciami terminalais
real-number ? integer-part . fraction ?
integer-part digit . fraction ? digit digit
. fraction ? 2 digit . fraction ? 2 1 .
fraction ? 2 1 . digit fraction ? 2 1 . 8
fraction ? 2 1 . 8 digit ? 2 1 . 8 9
61Empty
- Specialus neterminalas ltemptygt naudojamas kai
numanoma, kad gramatika toliau nebeturi nieko
daugiau generuoti. - Šio neterminalo panaudojimo pavyzdys if-then
konstrukcija su galima else dalimi
ltif-stmtgt if ltexprgt then ltstmtgt
ltelse-partgtltelse-partgt else ltstmtgt ltemptygt
62Sukonstruojame gramatikaJava primityviu tipu
deklaracijoms
float aboolean a,b,cint a1, b, c12
ltvar-decgt lttype-namegt ltdeclarator-listgt
lttype-namegt boolean byte short int
long char float double
ltdeclarator-listgt ltdeclaratorgt
ltdeclaratorgt , ltdeclarator-listgt
ltdeclaratorgt ltvariable-namegt
ltvariable-namegt ltexprgt
63EBNF
- papildoma sintakse supaprastinanti produkciju
žymejima - x reiškia nuli ar daugiau x pasikartojimu
- x reiškia, kad x yra papildomas (t.y. x
ltemptygt) - () naudojamas grupavimui
- reiškia pasirinkima tarp alternatyvu
- Šie meta simboliai kabutese reiškia atitinkamus
tokenus
64EBNF pavyzdžiai
ltif-stmtgt if ltexprgt then ltstmtgt else ltstmtgt
ltstmt-listgt ltstmtgt
ltthing-listgt (ltstmtgt ltdeclarationgt)
65Sintaksines analizes medis(Parse Tree)
- Kodel reikalingas sintaksines analizes medis?
- Sintaksinio medžio struktura išreiškia jo
generuojamos išraiškos semantika. - Konstruojant parse tree pradinis simbolis
talpinamas medžio šaknyje - Pridedant neterminalams vaiku mazgus sekama tam
neterminalui skirtomis gramatikos konstrukcijomis - Medis baigtas, kai visi jo lapai yra tokenai
- Medžio lapai skaitomi iš kaires i dešine tai
sakinys kuriam sukonstruotas medis
66Pavyzdys
ltexpgt
((ab)c)
( ltexpgt )
ltexpgt ltexpgt
( ltexpgt )
c
ltexpgt ltexpgt
a
b
67Sintaksines analizes medis
Sintaksinis analizatorius (parser) programai
kuria tam tikra sintaksine struktura sintaksini
medi (parse tree).
- Sintaksiniame medyje visi
- terminalai yra lapuose.
- Kontekstiškai laisvoje gramatikoje
- (context free grammar) visi vidiniai
- mazgai yra neterminalai.
position initial rate 60
assignment operator
identifier
expression
expression
expression
position
Sintaksiniame medyje yra daug nereikalingos inform
acijos
identifier
expression
expression
initial
number
identifier
60
rate
68Pavyzdys gramatika generuoja du medžius
ltexpgt ltexpgt ltexpgt ltmulexpgtltmulexpgt
ltmulexpgt ltmulexpgt (ltexpgt) a b c
a b c
Deja pirmasis medis neatitinka iprasto
sudeties operatoriaus asociatyvumo
69Asociatyvumo problema ištaisoma modifikuojant
gramatika taip, kad sudeciai medis augtu kairen
ir žemyn
ltexpgt ltexpgt ltmulexpgt ltmulexpgtltmulexpgt
ltmulexpgt ltrootexpgt ltrootexpgtltrootexpgt
(ltexpgt) a b c
Ši gramatika išraiškai abc generuoja teisinga m
edi
70Abstraktus sintaksinis medis
- Programavimo kalbos paprastai saugo supaprastinta
sintaksinio medžio versija vadinama abstrakciu
sintaksiniu medžiu (abstract syntax tree). - Tokiame medyje kiekvienam operatoriui skiriamas
atskiras mazgas, o kiekvienam operandui skiriamas
submedis.
71sintaksinis medis
abstraktus sintaksinis medis
72JavaCUP (Construct Useful Parser)YACC analogas
- JavaCUP tai Java kalba parašytas generatorius
(Bottom up Parser) sukuriantis Java kalba
parašyta sintaksini analizatoriu.
JavaCUP Specifikacija (cup failas)
JavaCUP
Sintaksinis analizatorius
73CUP aprašymo struktura
- package ir import specifikacija (papildoma)
- Vartotojo kodo komponentai (papildomi, leidžia
vartotojui deklaruoti koda, kuris bus itrauktas i
sugeneruota sintaksini analizatoriu) - Simboliu sarašai (terminalai ir neterminalai)
- Prioritetu deklaracijos (papildoma)
- Gramatika
74package ir import specifikacija
- Specifikacija prasideda papildomomis package ir
import deklaracijomis. - Deklaracijos turi ta pacia sintakse ir vaidina ta
pati vaidmeni kaip ir Java kalboje. - Deklaracija package nurodo kuriame pakete (ir
kataloge) bus patalpintos CUP sukurtos sym ir
parser klases. - Deklaracijoje import nurodyti paketai bus
deklaruoti parser klaseje, tuo paciu tais
paketais gales naudotis CUP specifikacijoje
patalpintas vartotojo Java kodas.
75Vartotojo kodo komponentai (1)
- action code ... Leidžia itraukti vartotojo
koda i CUPactions klase ir kuris savo ruožtu bus
naudojamas gramatikoje esanciu kodu. - Ši dalis dažniausiai skiriama darbui su simboliu
lentele. - parser code ... Ši dalis panaši i action
code, taciau kodas bus itrauktas i klase parser,
todel juo gales naudotis šios klases metodai
(pavyzdžiui, scan()). - Ši dalis dažnai skiriama standartinei ivesciai
aptarnauti.
76parser code ... pavyzdyje minimal.cup
parser code public static void main(String
args) throws Exception new parser(new
Yylex(System.in)).parse()
77Vartotojo kodo komponentai (2)
- init with ... Šioje dalyje pateikiamas
kodas, kuris bus atliekamas pats pirmas, dar
prieš analizatoriui užklausiant pirmojo tokeno. - Paprastai naudojama analizatoriui, ivairioms
lentelems ir strukturoms inicijuoti - scan with ... Nurodo kaip sintaksinis
analizatorius turi užklausti leksini analizatoriu
sekancio tokeno. - Šioje dalyje esantis kodas gražinimui turi
naudoti tipa java_cup.runtime.Symbol
78Simboliu sarašai
- Šioje dalyje deklaruojamas kiekvienas naudojamos
gramatikos terminalas ir neterminalas. - terminal name1, name2, ...
- terminal classname name1, name2, ...
- non terminal name1, name2, ...
- non terminal classname name1, name2, ...
- Klases naudojamos terminalu deklaracijose turi
buti klases java_cup.runtime.token poklases. - Klases naudojamos neterminalu deklaracijose turi
buti klases java_cup.runtime.symbol poklases.
79Terminalu ir neterminalu vardams negalima naudoti
CUP rezervuotus žodžius
"code", "action", "parser", "terminal",
"non", "nonterminal", "init", "scan", "with",
"start", "precedence", "left", "right",
"nonassoc", "import", "package"
80Prioritetu deklaracijos (1)
- Yra trys prioriteto/asociatyvumo deklaraciju
tipai - precedence left terminal, terminal...
- precedence right terminal, terminal...
- precedence nonassoc terminal, terminal...
- Deklaraciju saraše prioritetai auga iš viršaus i
apacia - Pavyzdžiui, jei nebus prioritetu, analizatorius
nežinos kuria tvarka apskaiciuoti išraiška 3 4
8 - Jei terminalo nera prioritetu deklaraciju saraše,
jo prioritetas laikomas mažiausiu.
81Prioritetu deklaracijos (2)
- Produkcijos prioritetas yra laikomas lygiu
žemiausio jos terminalu prioritetui. - Jei produkcija neturi terminalu, jos prioritetas
yra žemiausias. - Pavyzdžiui, produkcijos
- expr expr TIMES expr
- prioritetas lygus TIMES prioritetui
- Jei produkciju prioritetai lygus, toliau išraišku
vertinimo tvarka nustato terminalu asociatyvumas.
82Prioritetu deklaracijos (3)
- Yra trys asociatyvumo tipai left, right ir
nonassoc. - Pavyzdžiui, jei PLUS asociatyvumas nustatytas
left, tuomet 3 4 5 6 7 bus vertinama iš
kaires i dešine (pradedant 3 4) jei PLUS
asociatyvumas nustatytas right bus vertinama iš
dešines i kaire (pradedant 6 7) - Jei terminalas deklaruotas kaip nonassoc, tuomet
sekantys vienas po kito jo taikymai su vienodu
prioritetu bus interpretuojami kaip klaida. - Pavyzdžiui, jei asociatyvumas nustatytas
nonassoc, tuomet 6 7 8 9 reikš klaida.
83Gramatikos produkcijos (1)
- non_terminal symbol actions, terminal
symbols, non_terminal symbols - actions iterpiamos tarp skirtuku ...
- action vykdoma tuomet, kai analizatorius
atpažista jai atitinkancia produkcijos dali. - Kaip terminalai, taip ir neterminalai saraše gali
buti pažymeti vardu atskirtu dvitaškiu. - Šis vardas atstovauja kode jo pažymeta objekta.
84Gramatikos produkcijos (2)
- Jei neterminalas turi keleta produkciju, jos
deklaruojamos kartu ir atskiriamos iš dešines ()
simboliu. - Galima nurodyti analizatoriui kuriuo neterminalu
jis turi pradeti darba - start with non_terminal
- Jei tokios deklaracijos nera, analizatorius
pradeda darba pirmaja produkcija.
85Aritmetiniu išraišku su sveikais skaiciais
interpretatorius
- Interpretatorius turi nuskaityti aritmetines
išraiškas (besibaigiancias kabliataškiu) iš
standartines ivesties (standard input). - Interpretatorius turi apskaiciuoti išraiškas ir
resultata išvesti i standartine išvesti (standard
output).
86Aritmetiniu išraišku su sveikais skaiciais
gramatika
- expr_list expr_list expr_part expr_part
- expr_part expr ''
- expr expr '' expr expr '-' expr expr
'' expr - expr '/' expr expr '' expr '(' expr ')'
- '-' expr number
87Terminalu ir neterminalu deklaracija
- Pirmasis žingsnis aprašant sintaksini
analizatoriu (kuriant jo specifikaciju faila) yra
deklaruoti naudojamus terminalus ir neterminalus. - Neterminalai
- expr_list, expr_part ir expr
- Terminalai
- SEMI, PLUS, MINUS, TIMES, DIVIDE, MOD, NUMBER,
LPAREN, ir RPAREN - Šiuos terminalu vardus mes pasirinkome patys JLex
specifikaciju faile. - Jei terminalui nenurodome tipo, tai jis negali
igyti reikšmes.
88Terminalu ir neterminalu deklaracijapavyzdyje
minimal.cup
- terminal SEMI, PLUS, TIMES, LPAREN, RPAREN
- terminal Integer NUMBER
- non terminal expr_list, expr_part
- non terminal Integer expr
89Operatoriu prioritetai ir asociatyvumas
- Musu naudojama gramatika nera vienareikšme.
- Gramatika taps vienareikšme nustacius operatoriu
prioritetus ir asociatyvumo taisykles. - Pavyzdžiui
- Sakiniu prioritetai auga iš viršaus i apacia.
precedence left PLUS, MINUS precedence left
TIMES, DIVIDE, MOD precedence left UMINUS
90Leksinio analizatoriaus kuriamos klases
- sym saugo terminalams skirtas konstantas
- parser klase realizuoja analizatoriu
- ji yra java_cup.runtime.lr_parser poklase
- CUPaction klase skirta kaip gramatikoje nurodyto
vartotojo kodo veikoms, taip ir veiku kodui
deklaracijose.
91Inerpretatoriaus kurimas
- Apskaiciuoti išraiškas ir išvesti rezultata
galima tik su atitinkamu Java kodu. - Šis Java kodas turi buti atitinkamose vietose
patalpintas tarp žymiu ir - exprl PLUS exprr
- RESULTnew Integer(l.intValue()
r.intValue()) - Pirmasis neterminalas pažymetas l, o antrasis r.
- Kiekvienos produkcijos kairioji puse visuomet
žymima identifikatoriumi RESULT - ši reikšme (RESULT) priskiriama analizatoriaus
gražinamam objektui Symbol.
92package Example import java_cup.runtime. parser
code public static void main(String args)
throws Exception new parser(new
Yylex(System.in)).parse() terminal SEMI,
PLUS, TIMES, LPAREN, RPAREN terminal Integer
NUMBER non terminal expr_list, expr_part non
terminal Integer expr precedence left
PLUS precedence left TIMES expr_list
expr_list expr_part expr_part expr_part
expre System.out.println(" "e"")
SEMI expr NUMBERn RESULTn
exprl PLUS exprr RESULTnew
Integer(l.intValue() r.intValue())
exprl TIMES exprr RESULTnew
Integer(l.intValue() r.intValue())
LPAREN expre RPAREN RESULTe
minimal.cup
93minimal.lex
package Example import java_cup.runtime.Symbol
cup "" return new Symbol(sym.SEMI)
"" return new Symbol(sym.PLUS) ""
return new Symbol(sym.TIMES) "(" return new
Symbol(sym.LPAREN) ")" return new
Symbol(sym.RPAREN) 0-9 return new
Symbol(sym.NUMBER, new Integer(yytext()))
\t\r\n\f / ignore white space. / .
System.err.println("Illegal character
"yytext())