You are on page 1of 71

2.

SINTAKSA IN SEMANTIKA
Vsak jezik, tako naravni kot programski, opišemo s sintakso, semantiko in pragmatiko. Strukturo stavkov
jezika opišemo s sintakso, njihov pomen pa s semantiko. Z implementacijo jezika se ukvarja pragmatika.
3URJUDPVNH MH]LNH XSRUDEOMDMR WDNR QDþUWRYDOFL MH]LND NRW UD]YLMDOFL SUHYDMDOQLNRY LQ NRQþQL XSRUDEQLNL

jezika, to je programerji. Vsi ti uporabniki jezika morajo imeti enako predstavo o pomenu posameznih
stavkov programskega jezika. Zato morajo biti pravila, s katerimi opišemo strukturo (sintaksa) in pomen
(semantika SURJUDPVNLKVWDYNRYQDWDQþQRGRORþHQD
1DORJD VLQWDNWLþQH DQDOL]H MH XJRWDYOMDQMH VWUXNWXUH stavkov jezika. Pravimo, da preverjamo sintakWLþQR
SUDYLOQRVW VWDYNRY MH]LND3UHGVLQWDNWLþQR DQDOL]RMHWUHED RSUDYLWL ãH OHNVLNDOQR DQDOL]R NDWHUH QDORJDMH

SRLVNDWLL]QL]D]QDNRYEHVHGHNRWVRUH]HUYLUDQHEHVHGHLQãWHYLOD1DORJDVHPDQWLþQHDQDOL]HMHGRORþLWL

pomen posDPH]QLK VWDYNRY MH]LND 9VH WUL ID]H OHNVLNDOQR VLQWDNWLþQR LQ VHPDQWLþQR DQDOL]R  ODKNR
SUHSURVWR UD]ORåLPR ] QDVOHGQMR DQDORJLMR þORYHNRYHJD UD]XPHYDQMD QDUDYQHJD MH]LND 3UYL NRUDN SUL

UD]XPHYDQMXVWDYNDMHSUHSR]QDYDQMHQDMPDQMãLKHQRWNLåHLPDMRY sebino. To so besede.

Primer 2.1:

-RåHEHUHNQMLJR

-RåH – osebek
bere – povedek
knjigo – predmet
. – pika

Iskanje besed R] VHVWDYOMDQMH ]QDNRY Y EHVHGH MH ]HOR SRPHPEQR LQ QH þLVWR HQRVWDYQR RSUDYLOR þH
besede niso omejene s presledki.

Primer 2.2:

Toni sta vek.

1DORJD OHNVLNDOQHJD DQDOL]DWRUMD MH WRUHM UD]þOHQLWHY L]YRUQH GDWRWHNH SURJUDPD  Y EHVHGH R] QDWDQþQHMH

v osnovne leksikalne simbole (“tokens”). Razlika med njima je opisana v podpoglavju 2.1. V programskih
MH]LNLK ]DVOHGLPR RELþDMQR QDVOHGQMH RVQRYQH OHNVLNDOQH VLPEROH UH]HUYLUDQH EHVHGH LGHQWLILNDWRUMH

literale, operatorje in separatorje.


2. SINTAKSA IN SEMANTIKA
Primer 2.3:

if x=y then z:=0 else z:=’a’

if – rezervirana beseda
x – identifikator
= – operator
y – identifikator
then – rezervirana beseda
z – identifikator
:= – operator
0 –QXPHULþQLOLWHUDO
else – rezervirana beseda
z – identifikator
:= – operator
’a’ – znakovni literal
Tako besede if, then in else predstavljajo osnovni leksikalni simbol rezervirana beseda in, besede x,
y in z predstavljajo osnovni leksikalni simbol identifikator.

Naslednji korak je razumevanje strukture stavka. V ta namen uporabljamo diagram. Diagram je drevo, ki
pove, kako so besede, ki sestavljajo stavek, povezane med seboj.

Primer 2.4:
Struktura stavka iz primera 2.1.
-RåH bere knjigo .

osebek povedek predmet pika

stavek

28
1.2 KRATKA ZGODOVINA PROGRAMSKIH JEZIKOV
Primer 2.5:
Struktura stavka iz primera 2.3.

if x=y then z:=0 else z:=’a’

pogoj stavek stavek

stavek if then else

ýH MH VWUXNWXUD stavka pravilna, poskušamo razumeti njegov pomen 9HQGDU RG UDþXQDOQLND R]

SUHYDMDOQLNDQHPRUHPRSULþDNRYDWLGDERUD]XPHOSURJUDPYWDNãQHPSRPHQXNRWJDUD]XPHPROMXGMH

Vendar pa SUHYDMDOQLN ODKNR RSUDYL RPHMHQR VHPDQWLþQR DQDOL]R ] QDPHQRP GD SUHYHUL PRUHELWQH
nepravilnosti v programu.

Primer 2.6:
-RåH je prebrala knjigo .

napaka v spolu

Primer 2.7:
if x=y then z:=0 else z:=’a’

napaka v tipu

=DGQMD QDORJD VHPDQWLNH MH JHQHULUDQMH VHPDQWLþQR HNYLYDOHQWQH REMHNWQH NRGH 7D NRUDN XVWUH]D

translaciji jezika v kak drug naravni jezik.

29
2. SINTAKSA IN SEMANTIKA

LEKSIKALNA ANALIZA

Leksikalno analizo opravi leksikalni analizator, imenovan tudi pregledovalnik (“scanner”), ki je vmesnik
PHG L]YRUQLP SURJUDPRP LQ VLQWDNWLþQLP DQDOL]DWRUMHP VOLND   *ODYQD QDORJD OHNVLNDOQHJD

DQDOL]DWRUMDMHSRVUHGRYDWLVLQWDNWLþQHPXDQDOL]DWRUMXRVQRYQHOHNVLNDOQHVLPEROH3UDYWDNRL]ORþL]QDNH

ki ne vplivajo na pomen, kot so prazna mesta, preskoke v novo vrstico in komentar. Hkrati lahko polni tudi
tabele, v katerih imamo shranjene dodatne informacije za obdelavo. Tem tabelam pravimo simbolne
tabele. Leksikalni analizator obravnava izvorno datoteko kot niz znakov (“stream of characters”), iz njih
sestavi osnovne leksikalne simboleLQMLKSRVUHGXMHVLQWDNWLþQHPXDQDOL]DWRUMX

osnovni leksikalni
niz znakov Leksikalni simboli 6LQWDNWLþQLLQ
vmesna predstavitev
VHPDQWLþQL
analizator
analizator

Slika 2.1: Groba zgradba prevajalnika

9 SURJUDPVNLK MH]LNLK RELþDMQR ]DVOHGLPR QDVOHGQMH RVQRYQH OHNVLNDOQH VLPEROH UH]HUYLUDQH EHVHGH

identifikatorje, literale, operatorje in separatorje. Primeri rezerviranih besed so: begin, end,
identifikatorjev: imenik, matrika; literalov: 10, “abc“; operatorjev: +, * in separatorjev: ,, ;. Vsak
osnovni leksikalni simbol je opisan s pravili oz. vzorcem (“pattern”), ki pove, kdaj niz znakov predstavlja
ta osnovni leksikalni simbol. Tako npr. niz znakov oz. besede imenik, a10 in pi predstavljajo osnovni
leksikalni simbol identifikator. V vseh treh primerih leksikalni analizator poVUHGXMH VLQWDNWLþQHPX
analizatorju osnovni leksikalni simbol identifikator. Ker osnovni leksikalni simbol ne pove dovolj
LQIRUPDFLM VH VLQWDNWLþQHPX DQDOL]DWRUMX YUQH WXGL QMHJRYD OHNVLNDOQD YUHGQRVW oz. lexem. Lexem je niz

znakov vhodne datoteke, ki se ujema z vzorcem za neki osnovni leksikalni simbol. Pojmi osnovni
leksikalni simbol, lexem in vzorec so prikazani v tabeli 2.1:

Tabela 2.1: Primeri neformalnih opisov osnovnih leksikalnih simbolov


Osnovni leksikalni simbol Lexem Neformalni opis vzorca
id stevec, a10, pi znak, kateremu sledijo znaki in cifre
num 2.7, 0, 5.2E10 QXPHULþQLOLWHUDO

relop <, <=, =, <>, >, >= relacijski operator

30
2.1 LEKSIKALNA ANALIZA
9 PQRJLK SURJUDPVNLK MH]LNLK VR GRORþHQL QL]L ]QDNRY UH]HUYLUDQL LQ MLK QL PRJRþH XSRUDEOMDWL ]D

identifikatorje. Vkolikor so lahko identifikatorji tudi rezHUYLUDQH EHVHGH SUHGVWDYOMD WR WHåDYR SUHGYVHP
pri generatorjih leksikalnega analizatorja, ker le-ti uporabljajo prioritetno pravilo (glej podpoglavje 2.4).
3URJUDPL Y WDNãQLK SURJUDPVNLK MH]LNLK VR WXGL WHåMH EHUOMLYL NDU SULND]XMH QDVOHGQML SULPHU Y

programskem jeziku PL/I:

Primer 2.8:

IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;

9]RUHFMHSUDYLORNLSRYHNDWHUDPQRåLFD lexemov predstavlja osnovni leksikalni simbol3RYVHPRþLWQR


MH GD SRWUHEXMHPR IRUPDOQR PHWRGR NL QD QHGYRXPHQ QDþLQ RSLãH Y]RUFH 3UHGHQ VSR]QDPR UHJXODUQH

izraze oz. regularne definicije, s katerimi opišemo osnovne leksikalne simbole, si oglejmo nekaj definicij,
ki jih potrebujemo.
Jezik WHPHOML QD GRORþHQHP VORYDUMX NL JD VHVWDYOMDMR EHVHGH 3RVDPH]QD EHVHGD je sestavljena iz
NRQþQHJDQDERUD]QDNRY=QDNLVRHOHPHQWLQHNHNRQþQHPQRåLFHNLMLSUDYLPRDEHFHGDLQMRR]QDþLPRV

Σ. Beseda w dolåine n je element karteziþnega produkta w∈Σn = Σ × Σ × ... × Σ. Pišemo: w = w1w2 ... wn ∧
wi∈Σ. Dolåino besede w oznaþimo z |w| in velja |w| = n.
Besedo dolåine 0 imenujemo prazna beseda (“empty string”) in jo oznaþimo z ε. Nad besedami
definiramo binarno operacijo zdruåevanja (°  =GUXåHYDQMH GYHK EHVHG imenujemo tudi konkatenacija ali
operacija stik. Definiramo jo na naslednji naþin:

w = w1w2 ... wn
z = z1z2 ... zm
w°z = w1w2 ... wnz1z2 ... zm

Prazna beseda ima vlogo enote za operacijo zdruåevanja, saj velja:

w°ε = ε°w = w

Znak zdruåevanja smemo izpušþati, w°z = wz. Mnoåico vseh besed nad abecedo Σ oznaþimo s Σ*. Z
oznako
∞ n
Σ+ = ∪ Σ
n =1
velja:
Σ* = Σ+ ∪ {ε}

Jezik L nad abecedo Σ definiramo kot neko podmnoåLFRPQRåLFH Σ* (L ⊆ Σ*). Ta definicija jezika je zelo
ãLURND LQ RPRJRþD YHOLNR UD]OLþQLK MH]Lkov nad abecedo Σ 1D ]GUXåHYDQMH besed lahko gledamo tudi s

31
2. SINTAKSA IN SEMANTIKA
VWDOLãþDSURGXNWD=DWRGHILQLUDPRSRWHQFLUDQMHQDQDVOHGQMLQDþLQV = ε, si = si-1s. Nad jeziki definiramo
0

naslednje operacije: unija (L∪M), konkatenacija (LM) in zaprtje (L* , L+).

L∪M = { s | s ∈L ∨ s ∈M }
LM = { st | s ∈L ∧ t ∈M }

L* = ∪ Li
i =0

L+ = ∪ Li = L L*
i =1

Za formalni opis vzorcev, s katerimi opišemo osnovne leksikalne simbole, uporabljamo regularne izraze.
Regularni izraz je zgrajen iz preprostejših regularnih izrazov na osnovi spodaj definiranih pravil. Vsak
regularni izrazUR]QDþXMHMH]LN L(r). Pravila, ki definirajo regularne izraze nad abecedo Σ, so naslednja:
1. ε je regularni izraz in oznaþXMHMH]LN {ε}.
2. a ∈Σ je regularni izraz in oznaþXMHMH]LN {a}.
ýHVWDULQVUHJXODUQDL]UD]DNLR]QDþXMHWDMH]LND/ U LQ/ V SRWHPMH

a) (r)|(s) regularni izrazNLR]QDþXMHMH]LN L(r) ∪ L(s)


b) (r)(s) regularni izraz, ki oznaþuje jezik L(r)L(s)
c) (r)* je regularni izraz, ki oznaþuje jezik (L(r))*
d) (r) je regularni izraz, ki oznaþXMHMH]LN L(r).
2GYHþQLK RNOHSDMHY VH ODKNR ]QHELPR þH VH GUåLPR QDVOHGQMHJD SUDYLOD 2SHUDFLMD ]DSUWMD LPD SUHGQRVW

pred konkatenacijo in slednja ima prednost pred unijo; vsi operatorji imajo levo asociativnost.

Primer 2.9:
Σ = {a, b}
Regularni izraz a|ER]QDþXMHMH]LN {a, b}.
Regularni izraz (a|b) (a|E R]QDþXMHMH]LN {aa, ab, ba, bb}.
Regularni izraz a*R]QDþXMHMH]LN {ε, a, aa, aaa, ...}.

ýH Uegularne izraze poimenujemo, govorimo o regularnih definicijah. Regularna definicija je zaporedje

poimenovanih regularnih izrazov naslednje oblike:

d1 → r 1

32
2.1 LEKSIKALNA ANALIZA

d2 → r2
...
dn → r n ,
kjer so diUD]OLþQLLGHQWLILNDWRUMLLQUi regularni izrazi nad Σ in predhodno definiranimi d1 do di-1.

Primer 2.10:
Osnovni leksikalni simbol id iz tabele 2.1 lahko sedaj formalno opišemo z naslednjimi regularnimi
definicijami:

znak → A | B | ... | Z | a | b | ... | z


cifra → 0 | 1 | ... | 9
id → znak (znak | cifra)*

Nekateri regularni izrazi se pojavljajo zelo pogosto, zato zanje vpeljemo naslednje zapise:

r+ = rr* oz. r* = r+ | ε (pozitivna iteracija)


r? = r | ε (opcija)
[abc] = a | b | c (razred znakov)
[a-z] = a | b | ... | z

Primer 2.11:
1XPHULþQLOLWHUDO iz tabele 2.1 zapisan s pozitivno iteracijo, opcijo in razredom znakov.

cifra → [0-9]
num → cifra+ (. cifra+)? (E(+|-)? cifra+)?

2VQRYQHOHNVLNDOQHVLPEROHL]WDEHOHODKNRVHGDMRSLãHPRQDQDVOHGQMLIRUPDOQLQDþLQ WDEHOD 

Tabela 2.2: Primeri formalnih opisov osnovnih leksikalnih simbolov


Osnovni leksikalni simbol Lexem Formalni opis vzorca
*
id stevec, a10, pi znak (znak | cifra)
num 2.7, 0, 5.2E10 cifra+ (. cifra+)? (E(+|-)? cifra+)?
relop <, <=, =, <>, >, >= < | <= | = | <> | > | >=

33
2. SINTAKSA IN SEMANTIKA
'UXJVSORãQR]QDQIRUPDOL]HP]DRSLVRVQRYQLKOHNVLNDOQLKVLPERORYVRGHWHUPLQLVWLþQLNRQþQLDYWRPDW i,
NL VR XSRUDEQLNX QHNROLNR UD]XPOMLYHMãL YHQGDU VR ]D UDþXQDOQLãNR REGHODYR EROM ]DKWHYQL

'HWHUPLQLVWLþQLNRQþQLDYWRPDW je peterka M = <Q, Σ, δ, q0, F>, kjer je:

4NRQþQDPQRå ica stanj,


Σ : abeceda avtomata,
δ : parcialna funkcija, ki preslika stanje in vhodni simbol abecede Σ v novo stanje (δ : (Q × Σ) → Q),
q0]DþHWQRVWDQMHDYWRPDWD T0 ∈ Q),
)QHSUD]QDPQRåLFDNRQþQLKVWDQMDYWRPDWD )⊂ Q).

Primer 2.12:
6HVWDYLPRGHWHUPLQLVWLþQLNRQþQLDYWRPDWNLQDYKRGXVSUHMHPDUHDOQHãWHYLONH=]QDNRPGVPRR]QDþLOL

cifro.
d
B
d .
d
+
S A H d

.
. d
G

6OLND'HWHUPLQLVWLþQLNRQþQLDYWRPDWNLVSUHMHPDUHDOQHãWHYLONH

'HWHUPLQLVWLþQLNRQþQLDYWRPDWQDVOLNLMHVHVWDYOMHQL]4 ^6$%*+`T0 = S, F = {B, H}, Σ =


{+, -, d, .} in funkcije δ z naslednjimi prehodi:

{δ(S,+) = A, δ(S,-) = A, δ(S,.) = G,


δ(S,d) = B, δ(A,d) = B, δ(A,.) = G,
δ(B,d) = B, δ(B,.) = H, δ(G,d) = H,
δ(H,d) = H}

34
2.1 LEKSIKALNA ANALIZA
Primer 2.13:
Funkcijo δ iz prejšnega primera predstavLPR V WDEHOR SUHKRGRY NMHU VR NRQþQD VWDQMD ]DSLVDQD

poudarjeno.

δ + - . d
S A A G B
A G B
B H B
G H
H H

Leksikalni analizator

Program, ki opravlja leksikalno analizo, imenujemo leksikalni analizator ali pregledovalnik.


Najpreprosteje ga sestavimo tako, da LPSOHPHQWLUDPRGHWHUPLQLVWLþQLNRQþQLDYWRPDW. Funkcijo prehodov
δ lahko implementiramo s tabelo ali s programsko kodo, kjer so stanja oznake, prehode pa
LPSOHPHQWLUDPR V VNRNL ýH OHNVLNDOQL DQDOL]DWRU LPSOHPHQWLUDPR V WDEHOR SRWUHEXMHPR ãH DOJRULWHP NL

interpretira tabelo (v primeru 2.14 je to metoda nextTokenImp  $YWRPDW SULþQH YHGQR ]

UD]SR]QDYDQMHP Y ]DþHWQHP VWDQMX7UHQXWQR VWDQMH LQ SUHEUDQL ]QDN QD YKRGX GRORþDWD QDVOHGQMH VWDQMH

ýH RE WUHQXWQHP VWDQMX LQ SUHEUDQHP ]QDNX QD YKRGX SUHKRG QL GRORþHQ SUHYHULPR DOL MH DYWRPDW Y

NRQþQHP VWDQMX ýH MH Y NRQþQHP VWDQMX OHNVLNDOQL DQDOL]DWRU YUQH RVQRYQL OHNVLNDOQL VLPERO , ki je
SULGUXåHQ WHPX NRQþQHPX VWDQMX Y QDVSURWQHP SULPHUX SULGH GR OHNVLNDOQH QDSDNH . Prednosti
implementacije funkcije prehodov s programsko kodo pred implementacijo s tabelo so predvsem manjša
prostorskD LQ GHORPD WXGL þDVRYQD ]DKWHYQRVW 3UHGQRVW LPSOHPHQWDFLMH V WDEHOR MH SUHSURVWRVW VDM VH
leksikalni analizatorji med seboj razlikujejo le v tabeli (v primeru 2.14 je to metoda initAutomata).
Algoritem, ki interpretira to tabelo, pa ostaja nespremenjen.

Primer 2.14:
Implementirajmo leksikalni analizator za jezik DULWPHWLþQLK L]UD]RY Y SURJUDPVNHP MH]LNX & 7DNãQL
DULWPHWLþQL L]UD]L VR         LWG 1DORJD OHNVLNDOQHJD DQDOL]DWRUMD MH UD]SR]QDvanje

naslednjih osnovnih leksikalnih simbolov:

integer → [0-9]+
operator → + | *
separator → ( | )

in preskok praznih mest. Funkcijo prehodov leksikalnega analizatorja implementiramo z naslednjo tabelo
prehodov:

35
2. SINTAKSA IN SEMANTIKA

δ 0..9 +,* (,) \t, \n, ‘ ‘


0 1 2 3 4
1 1
2
3
4 4

Leksikalni analizator zapišimo v programskem jeziku C++:

// DATOTEKA: Token.h
#ifndef TOKEN_H
#define TOKEN_H
#include <iostream.h>
#include <string>

class Token
{
private:
string lexem; // leksikalni element
// stolpec izvorne datoteke, kjer je prvi znak lexema
int column;
// vrstica izvorne datoteke, kjer je prvi znak lexema
int row;
int token; // osnovni leksikalni simbol
bool eof; // konec datoteke

public:
// konstruktor
Token(const string& aLexem, int aColumn, int aRow,
int aToken, bool aEof)
: lexem(aLexem), column(aColumn), row(aRow),
token(aToken), eof(aEof) {
}
// privzeti konstruktor
Token() : lexem(""){
}

// vrni leksikalni element


const string getLexem() const {
return lexem;
}

// vrni vrstico lexema


const int getRow() const {
return row;
}

36
2.1 LEKSIKALNA ANALIZA
// vrni stolpec lexema
const int getColumn() const {
return column;
}
// vrni osnovni leksikalni element
const int getToken() const {
return token;
}
// vrni ali konec datoteke
const bool isEof() const {
return eof;
}
// izpis osnovnega leksikalnega simbola
friend ostream& operator<<(ostream &out, const Token& aToken) {
out << "’" << aToken.getLexem()<< "’ " <<
aToken.getToken() << " (" << aToken.getRow() <<
", " << aToken.getColumn() << ") " <<
(aToken.isEof()?"true":"false");

return out;
}
};
#endif // TOKEN_H

// DATOTEKA: Scanner.h
#ifndef SCANNER_H
#define SCANNER_H
#include "Token.h"
class Scanner {
private:
istream* input; // vhodna datoteka
Token lastToken; // trenutni osnovni leksikalni simbol
int row; // vrstica vhodne datoteke
int column; // stolpec vhodne datoteke
// opis tabele prehodov
const static int maxState = 4; // število stanj avtomata
const static intVWDUW6WDWH ]DþHWQRVWDQMHDYWRPDWD
const static int noEdge = -1; // ni prehoda
int automata[maxState+1][256]; // tabela prehodov
intILQLWH>PD[6WDWH@WDEHODNRQþQLKVWDQM
// inicializacija tabele prehodov in tabele NRQþQLKVWDQM
void initAutomata() {
// tabela prehodov je prazna
for (int i = 0; i<=maxState; i++) {
for (int j = 0; j<256; j++)
automata[i][j] = noEdge;
}

37
2. SINTAKSA IN SEMANTIKA
þHVPRYVWDQMXDOLREFLIULJUHPRYVWDQMH

for (int i = ’0’; i<=’9’; i++)


automata[0][i] = automata[1][i] = 1;
þHVPRYVWDQMXREDOL JUHPRYVWDQMH

automata[0][’+’] = automata[0][’*’] = 2;
þHVPRYVWDQMXRE DOL JUHPRYVWDQMH

automata[0][’(’] = automata[0][’)’] = 3;
þHVPRYVWDQMXRESUD]QHPPHVWXJUHPRYVWDQMH

automata[0][’\n’]=automata[0][’ ’]=automata[0][’\t’]=4;
þHVPRYVWDQMXRESUD]QHPPHVWXJUHPRYVWDQMH

automata[4][’\n’]=automata[4][’ ’]=automata[4][’\t’]=4;

VWDQMHQLNRQþQRYUQHPROHNVLNDOQRQDSDNR

finite[0] = tLexError;
VWDQMHMHNRQþQRYUQHPRRVQRYQLOHNVLNDOQLVLPERO integer
finite[1] = tInteger;
VWDQMHMHNRQþQRYUQHPR osnovni leksikalni simbol operator
finite[2] = tOperator;
VWDQMHMHNRQþQRYUQHPRRVQRYQLOHNVLNDOQLVLPERO separator
finite[3] = tSeparator;
VWDQMHMHNRQþQRYHQGDUVHOHWRSUH]UH

finite[4] = tIgnore;
}

protected:
QDVOHGQMHVWDQMHMHGRORþHQRþHSR]QDPRWUHQXWQRVWDQMHLQ

// znak na vhodu, s preprostim vstopom v tabelo


int getNextState(int aState, int aChar) const {
if (aChar==-1) return noEdge;
return automata[aState][aChar];
}

DOLMHVWDQMHNRQþQRVWDQMH

bool isFiniteState(int aState) const {


return finite[aState]!=tLexError;
}

YUQLNRQþQRVWDQMH

int getFiniteState(int aState) const {


return finite[aState];
}

private:
int peek() {
return input->peek();
}

38
2.1 LEKSIKALNA ANALIZA
// preberi naslednji znak na vhodu
int read() {
int temp = input->get();
column++;
if (temp==’\n’)
{
row++;
column = 1;
}
return temp;
}

bool eof() {
return peek()==-1;
}

SRLãþLQDVOHGQMLRVQRYQLOHNVLNDOQLVLPERO

Token nextTokenImp() {
int currentState = startState;
string lexem;
int startColumn = column;
int startRow = row;
do
{ // ob trenutnem stanju in vhodnemu znaku pojdi v novo stanje
int tempState = getNextState(currentState, peek());
if (tempState!=noEdge)
^SUHKRGYQRYRVWDQMHMHPRåHQ

currentState = tempState;
]GUXåLSUHEUDQL]QDNYOH[HP

lexem += (char)read();
}
else
^SUHKRGQLPRåHQDOLMHVWDQMHNRQþQR

if (isFiniteState(currentState))
{
VWDQMHMHNRQþQRLQYUDþDPRRVQRYQLOHNVLNDOQLVLPERO

Token token(lexem, startColumn, startRow,


getFiniteState(currentState), eof());
if (token.getToken()==tIgnore)
// presledke in nove vrstice prezremo
return nextToken();
else return token;
}
else
^VWDQMHQLNRQþQRYUDþDPROHNVLNDOQRQDSDNR

return Token("", startColumn, startRow,


tLexError, eof());

39
2. SINTAKSA IN SEMANTIKA
}
}
}
while (true);
}

public:
const static int tLexError = -1;
const static int tIgnore = 0;
const static int tInteger = 1;
const static int tOperator = 2;
const static int tSeparator = 3;

// konstruktor
Scanner(istream *aInput) {
row = 1;
column = 1;
initAutomata();
input = aInput;
}

Token nextToken() {
return lastToken = nextTokenImp();
}

Token currentToken() {
return lastToken;
}
};
#endif // SCANNER_H

40
2.2 6,17$.7,ý1$ ANALIZA

6,17$.7,ý1$$1$/,=$

1DORJDVLQWDNWLþQHDQDOL]HMHXJRWDYOMDQMHVWUXNWXUHVWDYNRYMH]LND9SUHMãQHPSRGSRJODYMXVPRGHILQLUDOL

jezik L kot neko podmnoåLFR PQRåLFH YVHK EHVHG Σ*. Za praktiþno uporabo je ta definicija jezika
SUHãLURND 8SRUDEHQMH]LN PRUD LPHWL GRORþHQR VWUXNWXUR ]DSLVDQR V NRQþQLP ãWHYLORP SUDYLO NL SRYHGR

NDNR QDM SRYH]XMHPR SRVDPH]QH EHVHGH 0QRåLFR SUDYLO V NDWHULPL RSLãHPR VWUXNWXUR VWDYNRY MH]LND

imenujemo sintaksa ali gramatika jezika. *UDPDWLNDMHþHWYHUND* 71=3!NMHUVR


• 7NRQþQDPQRåLFDWHUPLQDOQLKDOLNRQþQLKVLPERORY7⊆ Σ* (terminalni simbol je sinonim za osnovni
leksikalni simbol iz leksikalne analize),
• 1NRQþQDPQRåLFDQHWHUPLQDOQLKDOLQHNRQþQLKVLPERORY7∩ N =∅,
• =]DþHWQLVLPERO, Z ∈N,
• 3PQRåLFD produkcijR]NRQþQDQHSUD]QDSRGPQRåLFD relacije (T ∪ N)*N(T ∪ N)* → (T ∪ N)*.

Dogovorjeno je, da pišemo terminalne simbole (terminale) z malimi in neterminalne simbole (neterminale)
] YHOLNLPL þUNDPL (OHPHQWH 7 ∪ N)  R]QDþXMHPR ] PDOLPL JUãNLPL þUNDPL =DSRUHGMH WHUPLQDOQLK
*

simbolov zapišemo s T* in zaporedje neterminalnih simbolov z N*.

Bodi G = <T, N, Z, P>. Naj bosta α ∈ (T ∪ N)*N(T ∪ N)* in β ∈ (T ∪ N)*. Pravimo, da obstaja
neposredna izpeljava (“direct derivation”) za αþHREVWDMDWDEHVHGLγ in ρ, ki sta lahko tudi prazni, tako da
je α = γϕρ, β = γλρ in obstaja produkcija ϕ→λ. Neposredno izpeljavo zapišemo α ⇒ β in pravimo, da α
neposredno producira β oz. da se β neposredno reducira v α.

Iz α izpeljemo βYHQHPDOLYHþNRUDNLKþHREVWDMDMRα1, α2, ... , αn , n > 0, tako da velja:

α ⇒ α1 ⇒ α2 ⇒ ... ⇒ αn ⇒ β

Pišemo α ⇒+ β in pravimo, da obstaja izpeljava iz α v β. Relacija ⇒+ je tranzitivno zaprtje (“transitive


closure”) relacije ⇒ ýH ]D Q GRSXVWLPR WXGL YUHGQRVW 0, lahko definiramo refleksivno trazitivno zaprtje
(“reflexive transitive closure” QDQDVOHGQMLQDþLQ

α ⇒* β ⇔ (α ⇒+ β ∨ α = β )

Jezik / JHQHULUDQL] JUDPDWLNH *MH GHILQLUDQ QD QDVOHGQML QDþLQ / *   ^[ _ = ⇒*x ∧ x ∈ T*}. Jezik je
PQRåLFD vseh tistih zaporedij terminalnih simbolov, ki jih lahko izpeljemo iz zaþHWQHJDVLPERODJUDPDWLNH

Takšna zaporedja terminalnih simbolov imenujemo stavek jezika.

41
2. SINTAKSA IN SEMANTIKA
Primer 2.15:
JezikDULWPHWLþQLKL]UD]RYODKNR]DSLãHPR]QDVOHGQMRJUDPDWLNR
* ^   D`^(7)`(3!]QDVOHGQMRPQRåLco produkcij P:

E→ E+T
E→ T
T→ T*F
T→ F
F → (E)
F→ a

3RNDåLPRGDMH]DSRUHGMH terminalnih simbolov a + a * a stavek jezika:

E⇒E+T⇒T+T⇒F+T⇒a+T⇒a+T*F⇒a+F*F⇒ a+a*F⇒a+a*a

*UDPDWLNL * LQ * VWD HNYLYDOHQWQL þH YHOMD / *   / *  *UDPDWLNR LPHQXMHPR OHYR UHNXU]LYQD

gramatika þH YVHEXMH YVDM HQR SURGXNFLMR REOLNH $ → Aα. Gramatiko imenujemo desno rekurzivna
gramatikaþHYVHEXMHYVDMHQRSURGXNFLMRREOLNH$→ αA.

)RUPDOQD WHRULMD MH]LNRY MH SRPHPEHQ GHO UDþXQDOQLãWYD 6YRMH ]DþHWNH LPD Y VUHGLQL  OHW NR MH 1RDP

&KRPVN\ SRGDO PDWHPDWLþHQ PRGHO JUDPDWL k za naravne jezike. Chomsky je klasificiral gramatike v 4
razrede glede na omejitve pri obliki produkcij. V prvi razred spadajo gramatike brez omejitev, imenovane
neomejene gramatike G0 (“unrestricted grammars”). V drugi razred sodijo kontekstno odvisne gramatike
G1 (“context-sensitive grammars”), katerih produkcije imajo naslednjo obliko:

α→β ∧ |α| ≤ |β|

=QDþLOQR]DWHJUDPDWLNHMHGDODKNRL]YHGHPRGRORþHQRL]SHOMDYRQHWHUPLQDOQHJDVLPERODOHYRGYLVQRVWL

od njegove okolice. Te gramatike nimajo praznih produkcij oblike α → ε. Kontekstno odvisne gramatike
generirajo kontekstno odvisne jezike.

Primer 2.16:
Zapišimo gramatiko za jezik L(G) = {an bn cn| n ≥ 1}.
* ^DEF`^6%&`63!]QDVOHGQMRPQRåLFRSURGXNFLM P:
S → aSBC
S → abC
CB → BC
aB → ab
bB → bb
bC → bc
cC → cc

42
2.2 6,17$.7,ý1$ ANALIZA
3RNDåL mo, da je zaporedje terminalnih simbolov aabbcc stavek jezika:

S ⇒ aSBC ⇒ aabCBC ⇒ aabBCC ⇒ aabbCC ⇒ aabbcC ⇒ aabbcc

V tretji razred spadajo kontekstno proste gramatike G2 (“context-free grammars”), katerih produkcije
imajo naslednjo obliko:

A→β ∧ A∈N

Pri teh gramatikah izpeljava neterminalnega simbola ni odvisna od okolice in gramatika lahko vsebuje
prazno produkcijo A → ε. Prazna produkcija QHRPRJRþDGDELRSLVDOLãLUãLUD]UHGMH]LNRY9HOMDQDPUHþ
da lahko vsako gramatiko, ki vsebuje prazno produkcijo, preoblikujemo v takšno, ki prazne produkcije ne
vsebuje, a vseeno definira isti jezik. Kontekstno proste gramatike generirajo kontekstno proste jezike.

sodijo desno linearne gramatike G3 (“right linear grammars”), katerih produkcije imajo
9 þHWUWL UD]UHG

naslednjo obliko:

A → aB
A → a, kjer je a ∈ T in A, B ∈ N.

Desno linearne gramatike generirajo desno linearne jezike. Levo linearne gramatike (“left linear
grammars”) in regularne gramatike (“regular grammars”) so podobne desno linearnim gramatikam.
Produkcije v levo linearni gramatiki imajo naslednjo obliko:

A → Ba
A → a, kjer je a ∈ T in A, B ∈ N.

Produkcije v regularni gramatiki pa imajo naslednjo obliko:

A → aB
A → a, kjer je a ∈ Σ in A, B ∈ N.

Primer 2.17:
Jezik binarnih številk lahko definiramo z naslednjo regularno gramatiko:

* ^`^'`'3!]QDVOHGQMRPQRåLFRSURGXNFLM P:
D → 0D
D → 1D
D→0
D→1

43
2. SINTAKSA IN SEMANTIKA
3RNDåLPRGDMH]DSRUHGMH terminalnih simbolov 101 stavek jezika:

D ⇒ 1D ⇒ 10D ⇒ 101

2VWDYþQLREOLN i (“sentential form”) govorimo, ko velja: β ∈ (T ∪ N)* in Z ⇒* β.

Primer 2.18:
=JOHGLVWDYþQLKREOLN]DJUDPDWLNRL]SULPHUD

F+F*F
a+F*F
a+a*a

Za vsak razred gramatik obstaja razred abstraktnih strojev, ki sprejema jezike tega razreda. Tako ustreza
razredu neomejenih gramatik razred Turingovih strojev, razredu kontekstno odvisnih gramatik razred
omejenih linearnih avtomatov, razredu kontekstno prostih gramatik razred skladovnih avtomatov in
razredu regularnih gramatik usWUH]DUD]UHGNRQþQLKDYWRPDWRY 1DSRGURþMXVLQWDNVHSURJUDPVNLKMH]LNRY
VWD SRPHPEQD SUHGYVHP ]DGQMD GYD UD]UHGD UD]UHGD NRQWHNVWQR SURVWLK LQ UHJXODUQLK JUDPDWLN ýHSUDY V

kontekstno prostimi gramatikami ne moremo v celoti opisati programskih jezikov (npr. ne moremo
XJRWRYLWL DOL MH GRORþHQ LGHQWLILNDWRU GHILQLUDQ Y GRORþHQHP L]UD]X DOL WLSL SRVDPH]QLK SRGL]UD]RY

XVWUH]DMRRSHUDWRUMXLWG XSRUDEOMDPR]DRSLVVLQWDNVHSURJUDPVNLKMH]LNRYL]NOMXþQR]DGQMDGYDUD]UHGD

1H REVWDMDMR QDPUHþ XþLQNRYLWL DOJoritmi za razpoznavanje kontekstno odvisnih jezikov. Zgornji problem

kontekstne omejenosti (“contextual constraint” SDSUHQHVHPRQDSRGURþMHVHPDQWLNH


6LQWDNWLþQD analiza ali razpoznavanje (“parsing”) preveri, ali je neko zaporedje terminalnih simbolov

stavekMH]LND7RUHML]]DþHWQHJDVLPERODPRUDPRVSRPRþMRUD]SR]QDYDQMDSURGXFLUDWLVWDYHNR]VWDYHN
UHGXFLUDWL Y ]DþHWQL VLPERO ,]SHOMDYR EROM SUHJOHGQR SULNDåHPR JUDILþQR Y REOLNL GUHYHVD, ki ga

imenujemo drevo izpeljav (“derivation tree´  .RUHQ GUHYHVD L]SHOMDY MH ]DþHWQL VLPERO, listi drevesa so
terminalni simboli in vPHVQD YR]OLãþD GUHYHVD VR QHWHUPLQDOQL VLPEROL =D GRORþHQR GUHYR ODKNR REVWDMD
YHþ UD]OLþQLK L]SHOMDY 0HG QMLPL SRXGDULPR VNUDMQR levo izpeljavo (“left most derivation”) in skrajno

desno izpeljavo (“right most derivation´ 3ULVNUDMQROHYLL]SHOMDYLL]EHUHPRYVWDYþQLREOLNLVNUDMQROHYL


QHWHUPLQDOQLVLPEROLQXSRUDELPRXVWUH]QRSURGXNFLMR0RåQRMHWXGLGDWYRULMRUD]OLþQHL]SHOMDYHLVWHJD

VWDYNDUD]OLþQDGUHYHVDL]SHOMDYLQVWHPWXGLUD]OLþHQSRPHQ. Le-WRMHVHYHGDQH]DåHOHQR=DWRYSHOMHPR

naslednji pojem.
Gramatika je dvoumna (“ambiguous”  þH ]D YVDM HQ VWDYHN, ki ga generira ta gramatika REVWDMD YHþ NRW
eno drevo izpeljav. Treba je poudariti, da govorimo o dvoumni gramatiki in ne o dvoumnem jeziku. Za
GRORþHQ MH]LN REVWDMD YHþ UD]OLþQLK JUDPDWLN PHG NDWHULPL VR ODKNR GRORþHQH GYRXPQH GUXJH SD QH

Obstajajo pa dvoumni jeziki, za katere ne najdemo nedvoumnih gramatik.

44
2.2 6,17$.7,ý1$ ANALIZA
Primer 2.19:
V naslednji gramatiki obstajata za stavek a + a * a dve drevesi izpeljav (slika 2.3), in s teP GYD UD]OLþQD
pomena: (a + a) * a in a + (a * a).

E→E+E
E→E*E
E → (E)
E→a

E E

E E

E E E E E E

a + a * a a + a * a

6OLND3ULPHUGYHKUD]OLþQLKGUHYHVL]SHOMDY

=JRUQMRJUDPDWLNRODKNR]XYHGERGRGDWQLKQHWHUPLQDOQLKVLPERORYNLGRORþDMRSULRULWHWRLQDVRFLD tivnost
operatorjev, spremenimo tako, da še zmeraj definira isti jezikQLSDYHþGYRXPQD (glej primer 2.15).

Lahko si zastavimo vprašanje, ali obstaja algoritem, ki za poljubno grDPDWLNRYNRQþQHPþDVXXJRWRYLDOL


je gramatika dvoumna ali ne. Odgovor na to vprašanje je NE'RORþLWL]QDPRPQRåLFR]DGRVWQLKSRJRMHY
NL GRORþDMR QHGYRXPQR JUDPDWLNR DPSDN QLVR SRWUHEQL = GUXJLPL EHVHGDPL najdemo lahko takšno

gramatiko, kjer zadostni pogoji ne veljajo, gramatika pa je kljub temu nedvoumna.

BNFLQVLQWDNWLþQLGLDJUDPi

Metajezik je jezik, s katerim opisujemo druge jezike. Simbole, ki jih uporablja metajezik, imenujemo
PHWDVLPEROL=DRSLVVLQWDNVHSURJUDPVNLKMH]LNRYVHMHXYHOMDYLOQHNROLNRGUXJDþHQ]DSLV od navedenega
v tem poglavju, imenovan BNF (“Backus-Naur Form”). Produkcije z enakim neterminalom na levi strani
]GUXåLPR LQ QMLKRYH GHVQH VWUDQL ORþLPR ] PHWDVLPERORP _ NL SUHGVWDYOMD DOWHUQDFLMR 0HWDVLPERO →

zamenjamo z metasimbolom ::=. Produkcije imajo sedaj naslednjo obliko:

45
2. SINTAKSA IN SEMANTIKA

A ::= α1 | α2 | ... | αn , kjer velja A ∈ N in αi ∈ (T ∪ N)*

Primer 2.20:
Primer 2.15 v zapisu BNF:

E ::= E + T | T
T ::= T * F | F
F ::= (E) | a

Prvi programski jezik zapisan s sintakso v obliki BNF je algol-60. Od takrat naprej za opis sintakse
uSRUDEOMDPRVNRUDML]NOMXþQR%1)DOLQMHJRYHLQDþLFH oz. razširitve, med katerimi sta najpogostejša EBNF
LQVLQWDNWLþQL diagrami (grafi). Razširjena Backus-Naurova oblika EBNF (“extended BNF”) vpelje dodatna

metasimbola: {} in [], s katerima opišemo iteracijo in opcijo.

Produkcije oblike: A ::= α A | ε lahko nadomestimo s produkcijo A ::= {α}.

Produkcije oblike: A ::= α | ε lahko nadomestimo s produkcijo A ::= [α].

Primer 2.21:
Primer 2.15 v EBNF zapisu:

E ::= [E +] T
T ::= [T *] F
F ::= (E) | a

Lahko se zgodi, da je metasimbol hkrati tudi simbolMH]LNDNLJDRSLVXMHPR7DNRSULGHGRRNROLãþLQHNR


GRORþHQ VLPERO KNUDWL SUHGVWDYOMD VLPERO ]DSLVD %1) in simbol jezika. Marsikateri programski jezik

uporablja naslednje terminalne simbole: [], {}, |, ki so metasimboli v EBNF. Problem rešimo tako, da
vpeljemo novi metasimbol ’ (enojni narekovaj). V zapisu BNF metasimbol, ki je hkrati tudi element
jezika, obdamo z enojnima narekovajema. Seveda se lahko nato zgodi, da je tudi enojni narekovaj element
jezika, ki ga opisujemo. Ta problem rešimo z naslednjim dogovorom: enojnemu narekovaju, ki ni
PHWDVLPEROWHPYHþHOHPHQWMH]LNDGRGDPRãHHQRMQLQDUHNRYDM7DNRGRELPRãWLULQDUHNRYDMH

6LQWDNWLþQL diagrami (“syntax diagrams”  VR JUDILþQD SRQD]RULWHY %1) oz. EBNF in jih dobimo z
naslednjimi pravili:

46
2.2 6,17$.7,ý1$ ANALIZA

a∈T a

A∈N A

Produkcijo oblike A ::= α1 | α2 | ... | αn ponazorimo z:

α1

α2

...
αn

produkcijo oblike A ::= α1α2 ... αn ponazorimo z:

α1 α2 ... αn

produkcijo oblike A ::= {α} ponazorimo z:

produkcijo oblike A ::= [α] ponazorimo z:

47
2. SINTAKSA IN SEMANTIKA
Primer 2.22:
6LQWDNWLþQLGLDJUDPL za gramatiko iz primera 2.21 so:

E E + T

T T * F

F ( E )

Formalni zapis sintakse jezika ima naslednje prednosti:


• sintaksaMH]LNDMHGHILQLUDQDQDQDWDQþHQLQQHGYRXPHQQDþLQ
• PRåQRMHDYWRPDWVNRJHQHULUDQMHVLQWDNWLþQHJDDQDOL]DWRUMDLQ
• VOXåLNRWRURGMH]DQDþUWRYDQMHVLQWDNVHMH]LND

6LQWDNWLþQLDQDOL]DWRU

6LQWDNWLþQL analizator ali razpoznavalnik ("parser  MH SURJUDP NL RSUDYOMD VLQWDNWLþQR DQDOL]R 1D
splošnR REVWDMDWD GYD SULVWRSD 3UL SUYHP L]KDMDPR L] ]DþHWQHJD VLPEROD LQ SRVNXãDPR ]JUDGLWL GUHYR
izpeljav, ki bi imelo za liste terminalne simbole. Ta pristop imenujemo razpoznavanje od zgoraj navzdol
("top-down parsing"). V drugem pristopu izhajamo iz listov drevesa (terminalnih simbolov) in poskušamo
SULWL GR NRUHQD GUHYHVD ]DþHWQHJD VLPEROD  7D SULVWRS LPHQXMHPR UD]SR]QDYDQMH RG VSRGDM QDY]JRU

("bottom-up parsing  3UL UD]SR]QDYDQMX RG ]JRUDM QDY]GRO ORþLPR YHþ SULVWRSRY LQ WHKQLN WHKQLNR
YUDþDQMD backtracking", "brute-force") in razpoznavalnike LL(1), kot so: rekurzivni navzdolnji

razpoznavalnik ("recursive-descent parser"), skladovni razpoznavalnik LQ WDEHODULþQR vodeni


razpoznavalnik ("table-driven parser 3ULUD]SR]QDYDQMXRGVSRGDMQDY]JRUSUDYWDNRSR]QDPR YHþ YUVW
razpoznavalnikov: razpoznavalnike na osnovi prioritete operatorjev ("operator precedence parser"),
razpoznavalnike na osnovi preproste prioritete ("simple precendence parser"), razpoznavalnike na osnovi
razširjene prioritete ("extended precendence parser"), razpoznavalnike LR(k) ("LR(k) parser"),
razpoznavalnike SLR(1), razpoznavalnike /$/5   LWG 5D]SR]QDYDOQLNL /5 VR ]HOR XþLQNRYLWL LQ MLK Y
praksi veliko uporabljamo, vendar je njihova zgradba zahtevnejša od razpoznavalnikov od zgoraj navzdol.

48
2.2 6,17$.7,ý1$ ANALIZA
,]JUDGQMDLQSULPHUMDYDUD]OLþQLKYUVWUD]SR]QDYDOQLNRYVRGLQDSRGURþMHSUHYDMDOQLNRY=DWRVLRJOHMPROH

izgradnjo razpoznavalnikov LL(1).

 Razpoznavalniki LL(1)

7HKQLND YUDþDQMD MH ]HOR VSORãQD YHQGDU QHXþLQNRYLWD 9 SUDNVL VR WDNãQL UD]SR]QDYDOQLNL QHXSRUDEQL

Gramatika mora biti takšna, da lahko glede na trenutni terminalni simbol na vhodu za izpeljavo vedno
izberePR SUDYLOQR SURGXNFLMR WHU WDNR SUHSUHþLPR YUDþDQMH )RUPDOQR ]DSLãHPR WH SRJRMH ] XYHGER
funkcij FIRST in FOLLOW'RPHQDIXQNFLMH),567MHPQRåLFD (T ∪ N)* in domena funkcije FOLLOW
MHPQRåLFDQHWHUPLQDORY)XQNFLMLVWDGHILQLUDQLQDQDVOHGQMLQDþLQ

FIRST(α) = {x | α ⇒* xβ , x ∈ T}
FOLLOW(A) ={x | Z ⇒* αAβ , x ∈ FIRST(β)}

Funkcija FIRST YUQH PQRåLFR ]DþHWQLK WHUPLQDOQLK VLPERORY NL MLK ODKNR L]SHOjemo iz zaporedja
(T ∪ N)*, medtem ko funkcija FOLLOWYUQHPQRåLFRWHUPLQDOQLKVLPERORYNLWDNRMVOHGLMRGRORþHQHPX
QHWHUPLQDOX =D GRORþDQMH PQRåLF FIRST in FOLLOW si pomagamo z naslednjimi pravili (domeno

IXQNFLMH),567UD]ãLULPRQDPQRåLFREHVHG8LQ9QDQDVOHGQMLQDþLQ),567 89  ∪ FIRST(uv)):
u ∈ U, v ∈ V

1. FIRST(a) = {a}
2. FIRST(ε) = {ε}
3. FIRST(α β) = FIRST(FIRST(α)°FIRST(β))
4. FIRST(A) = FIRST(α1) ∪ FIRST(α2) ∪ ... ∪ FIRST(αn),
þHREVWDMDSURGXNFLMDREOLNH$ α1 | α2 | ... | αn

5. FOLLOW(X) = FIRST(β°FOLLOW(A)),
þHREVWDMDSURGXNFLMDREOLNH$ αXβ. Simbol β je lahko tudi ε.

*UDPDWLNDMH//  þH

1. za vsako produkcijo A ::= α1 | α2 | ... | αn velja: ∀i, j: FIRST(αi) ∩ FIRST(αj) = ∅ ∧ i ≠ j in


2. za vse neterminale A ∧ A ⇒ * ε velja: FIRST(A) ∩ FOLLOW(A) = ∅

ýH MH JUDPDWLND LL(1) ("Left-to-right scanning, Left-most derivation"), se lahko na osnovi terminalnega
VLPERODQDYKRGXYHGQRRGORþLPR]DSUDYLOQRSURGXNFLMRLQMHYUDþDQMHQHSRWUHEQR6WHPVPRL]EROMãDOL

algoritem razpoznavanja, vendar smo hkrati omejili razred gramatik, saj ni vsaka gramatika tudi gramatika
//   ýH MH JUDPDWLND //   ODKNR ]DSLãHPR ]HOR XþLQNRYLW VLQWDNWLþQL DQDOL]DWRU ali razpoznavalnik.

Razpoznavalnike LL(1) imenujejo nekateri avtorji tudi brezpovratna analiza z enosimbolnim oknom na
vhodu ("one symbol look-ahead without backtracking").

49
2. SINTAKSA IN SEMANTIKA
Primer 2.23:
=DQDVOHGQMRJUDPDWLNRL]UDþXQDMPRPQRåLFL), RST in FOLLOW:

P ::= Ac | Bd
A ::= aA | ε
B ::= bB | ε

FIRST(P) = FIRST(Ac) ∪ FIRST(Bd)


= FIRST(FIRST(A)°FIRST(c)) ∪ FIRST(FIRST(B)°FIRST(d))
= {a, c} ∪ {b, d}
= {a, b, c, d}
FIRST(A) = FIRST(FIRST(a)°FIRST(A)) ∪ FIRST(ε)
= {a} ∪ {ε}
= {a, ε}
FIRST(B) = FIRST(FIRST(b)°FIRST(B)) ∪ FIRST(ε)
= {b} ∪ {ε}
= {b, ε}
FOLLOW(P) = ∅
FOLLOW(A) = FIRST(c°FOLLOW(P)) ∪ FOLLOW(A)
= {c} ∪ FOLLOW(A)
= {c}
FOLLOW(B) = FIRST(d°FOLLOW(P)) ∪ FOLLOW(B)
= {d} ∪ FOLLOW(B)
= {d}

(QDþED)2//2: (B) = {d} ∪)2//2: % MHUHNXU]LYQDLQLPDQHVNRQþQRUHãLWHYYHQGDUQDV]DQLPDOH


najmanjša. Vidimo, da je zgornja gramatika LL(1), saj velja:

FIRST(Ac) ∩ FIRST(Bd) = {a, c} ∩ {b, d} = ∅


FIRST(FIRST(a)°FIRST(A)) ∩ FIRST(ε) = {a} ∩ {ε} = ∅
FIRST(FIRST(b)°FIRST(B)) ∩ FIRST(ε) = {b} ∩ {ε} = ∅
FIRST(A) ∩ FOLLOW(A) = {a, ε} ∩ {c} = ∅
FIRST(B) ∩ FOLLOW(B) = {b, ε} ∩ {d} = ∅

0QRåLFRYVHKWLVWLKQHWHUPLQDOQLKVLPERORYNLMLKODKNRL]SHOMHPRY εR]QDþLPR]1ε:

Nε = {A | A ⇒*ε ∧ A ∈ N}

50
2.2 6,17$.7,ý1$ ANALIZA
0QRåLFL),567 in FOLLOWODKNRL]UDþXQDPRWXGL]XSRUDERUHODFLM9WDQDPHQGHILQLUDMPRUHODFLMH F,
L, B in njihova tranzitivna ali refleksivno tranzitivna zaprtja.

ýHREVWDMDSURGXNFLMD; Y2 ... Yn, potem je X v relaciji F z Y1 in pišemo XFY1ýHMH<1 ∈ Nε, potem


<1

je tudi XFY2 itd. Tranzitivno zaprtje F+ PHG 8 LQ ; REVWDMD þe velja U ⇒ A1 ⇒ A2 ⇒ ... ⇒ An ⇒ X in
pišemo UF+;0QRåLFR),567 sedaj definiramo:

FIRST(A) = {x | AF+x ∨ (x = ε ∧ A ∈ Nε) ∧ x ∈ T ∧ A ∈ N}

ýHREVWDMDSURGXNFLMD; <1 Y2 ... Yn, 1 ≤ i < n, potem je YiBYi+1LQþHYHOMD<i+1 ∈ Nε in i < n-1, potem
je tudi YiBYi+2 itd.

ýHREVWDMDSURGXNFLMD; <1 Y2 ... Yn, potem je YnL;LQþHYHOMD<n ∈ Nε, potem je Yn-1LX itd.

0QRåLFR)2//2: sedaj definiramo:

FOLLOW(A) = {x | A(L*BF*)x ∧ x ∈ T ∧ A ∈ N}

Poljubno relacijo R lahko predstavimo v obliki matrike, ki ima enice na tistih mestih, kjer velja med
elementoma relacija R. Tako lahko tranzitivno zaprtje R+L]UDþXQDPR]:DUVKDOORYLPDOJRULWPRP

Algoritem 2.1
Warshallov algoritem]DL]UDþXQWUDQ]LWLYQHJD]DSUWMD

A - matrika, ki predstavlja relacijo R


n - dimenzija matrike
P - matrika, ki predstavlja zaprtje R+
P = A;
for k = 1 to n
for i = 1 to n
for j = 1 to n
P[i,j] = P[i,j] or (P[i,k] and P[k,j])

Refleksivno tranzitivno zaprtje R* dobimo iz tranzitivnega zaprtja R+ tako, da na glavno diagonalo


matrike, ki predstavlja R+, postavimo 1.

Primer 2.24:
,]UDþXQPQRåLF FIRST in FOLLOW za gramatiko iz primera 2.23:

51
2. SINTAKSA IN SEMANTIKA

F: F*:

P A B a b c d P A B a b c d
P 1 1 1 1 P 1 1 1 1 1 1 1
A 1 A 1 1
B 1 B 1 1
a a 1
b b 1
c c 1
d d 1

F+: L*:

P A B a b c d P A B a b c d
P 1 1 1 1 1 1 P 1
A 1 A 1
B 1 B 1
a a 1 1
b b 1 1
c c 1 1
d d 1 1

L = L+: B:

P A B a b c d P A B a b c d
P P
A 1 A 1
B 1 B 1
a 1 a 1
b 1 b 1
c 1 c
d 1 d

52
L*BF*:
P A B a b c d
P
A 1
B 1
a 1 1 1
b 1 1 1
c
d

,]PDWULNLQL]SUDYLOD]DGRORþDQMHPQRåLFH FIRST in FOLLOWUD]EHUHPRQDVOHGQMHPQRåLFH

FIRST(P) = {a, b, c, d}
FIRST(A) = {a, ε}
FIRST(B) = {b, ε}
FOLLOW(P) = ∅
FOLLOW(A) = {c}
FOLLOW(B) = {d}

Ker lahko neterminalna simbola A in B izpeljemo v ε, je le-WDSRSUDYLOX]DGRORþDQMHPQRåLFH FIRST tudi


HOHPHQWPQRåLF),567 $ LQ),567 % 

Z izrDþXQRP F+ WHVWLUDPR WXGL OHYR UHNXU]LYQRVW JUDPDWLN NDMWL þH LPD PDWULND F+ na glavni diagonali
kakšno enico, potem velja AF+A oz. A ⇒* A ..., kar pomeni, da je gramatika levo rekurzivna.
Razpoznavalniki od zgoraj navzdol se ob levo rekurzivnih gramatikah zazankajo (razlogi bodo postali
razumljivi, ko bomo spoznali implementacijo razpoznavalnikov). Zato preoblikujemo takšne gramatike z
naslednjim pravilom:

Produkcijo oblike:

A ::= Aα1 | Aα2 | ... | Aαm | β1 | β 2 | ... | β n

zamenjamo z:

A ::= β1A’ | β2A’ | ... | β nA’


A’ ::= α1A’ | α2A’ | ... | αmA’ | ε
2. SINTAKSA IN SEMANTIKA
Uporabo zgornjega pravila imenujemo odpravljanje leve rekurzije (“left recursion elimination”) ýH VH
YVH DOWHUQDWLYH QHNHJD SUDYLOD SULþQHMR ] α ∈ (N ∪ T) , gramatika ni LL(1) in jo moramo prav tako
*

preoblikovati. To opravilo imenujemo levo faktoriranje (“left factoring”).

Produkcijo oblike

A ::= αβ1 | αβ2 | ... | αβ n

zamenjamo z:

A ::= αA’
A’::= β1 | β2 | ... | β n

Primer 2.25:
V primeru 2.15 odpravimo levo rekurzijo in dobimo naslednjo gramatiko:

E ::= T EE
EE ::= + T EE | ε
T ::= F TT
TT ::= * F TT | ε
F ::= (E) | a

0RåQD LPSOHPHQW acija razpoznavanja LL(1) je tehnika rekurzivnega navzdolnjega razpoznavanja.


,]GHODYR UHNXU]LYQHJD QDY]GROQMHJD UD]SR]QDYDOQLND VL QDMODåMH SUHGVWDYLPR NRW SUHWYRUER VLQWDNWLþQLK

diagramov v programsko kodo po naslednjih štirih pravilih:

1.
A∈N A call A;

2.

a∈T a if token = ’a’ then nextToken else error

54
2.2 6,17$.7,ý1$ ANALIZA
3.

α1 if token IN FIRST(α1) then T(α1)

α2 else if token IN FIRST(α2) then T(α2)

... ...

αn else if token IN FIRST(αn) then T(αn)

else error

4.

α1 α2 ... αn T(α1);T(α2);...;T(αn)

Podprogram nextToken opravlja nalogo leksikalnega analizatorja. V spremenljivki token je shranjen


osnovni leksikalni simbol, ki ga leksikalni analizator SRVUHGXMH VLQWDNWLþQHPX DQDOL]atorju. Funkcija T je
transformacijska funkcija, ki uporablja zgornja štiri pravila. Za vsak neterminal na levi strani produkcije
zapišemo podprogram, katerega telo je desna stran produkcije, pretvorjena z zgornjimi pravili v
programsko kodo.

Primer 2.26:
Po zgornjih pravilih zapišimo rekurzivni navzdolnji razpoznavalnik ]D DULWPHWLþQH L]UD]H SULPHU 
kjer je simbolDVLQRQLP]DãWHYLONR 1DMSUHML]UDþXQDMPRPQRåLFL FIRST in FOLLOW!

FIRST(E) = {a, (}
FIRST(EE) = {+, ε}
FIRST(T) = {a, (}
FIRST(TT) = {*, ε}
FIRST(F) = {a, (}
FOLLOW(E) = {)}
FOLLOW(EE) = {)}
FOLLOW(T) = {+, )}
FOLLOW(TT) = {+, )}
FOLLOW(F) = {+, *, )}

55
2. SINTAKSA IN SEMANTIKA
Gramatika je LL(1), kar pomeni, da lahko zgradimo rekurzivni navzdolnji razpoznavalnik. Zapišimo ga v
programskem jeziku C++:

// DATOTEKA: Parser.h
#ifndef PARSER_H
#define PARSER_H
#include "Scanner.h"

class Parser {
private:
Scanner* scanner; // glej primer 2.14
protected:
bool E(){
return T() && EE();
}
bool EE() {
if (scanner->currentToken().getLexem()=="+")
{
scanner->nextToken();
return T() && EE();
}
return true;
}
bool T() {
return F() && TT();
}
bool TT() {
if (scanner->currentToken().getLexem()=="*")
{
scanner->nextToken();
return F() && TT();
}
return true;
}
bool F(){
if (scanner->currentToken().getToken()==Scanner::tInteger)
{
scanner->nextToken();
return true;
}
else
if (scanner->currentToken().getLexem()=="(")
{
scanner->nextToken();
bool zac = E();
if (zac && scanner->currentToken().getLexem()==")")
{

56
2.2 6,17$.7,ý1$ ANALIZA
scanner->nextToken();
return true;
}
else return false;
}
else
return false;
}
public:
// konstruktor
Parser(Scanner* aScanner) {
scanner = aScanner;
scanner->nextToken();
}
bool parse() {
return E() && scanner->currentToken().isEof();
}
};
#endif

Za stavek a + a * a je drevo rekurzivnih klicev enako drevesu izpeljav (slika 2.4):

T EE

F TT T EE

F TT

F TT

a ε + a * a ε ε

Slika 2.4: Drevo rekurzivnih klicev

6ODERVW UHNXU]LYQLK QDY]GROQMLK UD]SR]QDYDOQLNRY MH VODEãH RGNULYDQMH LQ RGSUDYOMDQMH QDSDN 2ELþDMQR

kar ob prvi napaki prenehamo z razpoznavanjem.

57
2. SINTAKSA IN SEMANTIKA

6(0$17,ý1$$1$/,=$

6HPDQWLNR SURJUDPVNLK MH]LNRY RSLãHPR RELþDMQR Y QDUDYQHP MH]LNX 7DNãHQ RSLV MH UD zumljiv in
GRVWRSHQ ãLURNHPX NURJX XSRUDEQLNRY YHQGDU LPD WXGL YHOLNR SRPDQMNOMLYRVWL QSU QHQDWDQþQRVW LQ

GYRXPQRVW NL GRSXãþDWD PRåQRVW UD]OLþQLK LQWHUSUHWDFLM =DWR SRWUHEXMHPR IRUPDOQR PHWRGR NL RSLãH

pomen programskih stavkoYQDUD]XPOMLYLQQHGYRXPHQQDþLQ9HQGDUMHVHPDQWLNRYHOLNRWHåMHIRUPDOQR


opisati kot sintakso. Danes še nimamo za semantiko podobnega standarda, kot je BNF za sintakso. V tem
podpoglavju spoznavamo eno izmed formalnih metod za opis semantike programskih jezikov - atributne
gramatike (“attribute grammars”), ki so posplošitev kontekstno prostih gramatik. Neterminalnim in
terminalnim simbolom kontekstno proste gramatike SULGUXåLPR DWULEXWH NL SUHGVWDYOMDMR VHPDQWLþQR
LQIRUPDFLMR 9VDNL SURGXNFLML GRGDPR PQRåLFR VHPDQWLþQLK SUDYLO ]D RYUHGQRWHQMH atributov. Glede na

zahtevnost ovrednotenja atributov delimo atributne gramDWLNH QD YHþ UD]UHGRY DWULEXWQH JUDPDWLNH YUVWH
S, atributne gramatike vrste LQHFLNOLþQHLQDEVROXWQRQHFLNOLþQHDWULEXWQHJUDPDWLNH.
3UHGQRVWL IRUPDOQHJD RSLVD VHPDQWLNH QL VDPR Y QHGYRXPQL LQ QDWDQþQL GRORþLWYL SRPHQD 6 SRPRþMR

formalne metode lahko generiranje prevajalnikov in interpreterjev povsem avtomatiziramo, za kar so


atributne gramatike zelo primerne.

Atributna gramatika

Naj bo dana kontekstno prosta gramatika* 71=3!]PQRåLFRWHUPLQDORY7PQRåLFRQHWHUPLQDORY

L(G) (podpoglavje 2.2). Definirajmo


1 ]DþHWQLP QHWHUPLQDORP = LQ SURGXNFLMDPL 3 NL GHILQLUDMR MH]LN

PQRåLFR 9 = T ∪ N. Produkcijo p ∈ P lahko pišemo kot X0 → X1 X2 … Xnp, kjer so np ≥ 0, X0 ∈ N in


Xi ∈ V za 1 ≤ i ≤ np. V tem poglavju privzemimo, da je kontekstno prosta gramatika G standardizirana
(“standardized context free grammar”)NDUSRPHQLGDVH]DþHWQLQHWHUPLQDO Z ne pojavlja na desni strani
QREHQH SURGXNFLMH ýH QDãD JUDPDWLND QL VWDQGDUGL]LUDQD MR VWDQGDUGL]LUDPR WDNR GD XYHGHPR QRYL

zaþHWQLQHWHUPLQDO=′ in gramatiki dodamo produkcijo Z′ → Z.

Atributna gramatika je nadgradnja kontekstno proste gramatike G, tako da vsaki produkciji p ∈ P


SULUHGLPR PQRåLFR VHPDQWLþQLK funkcij (“semantic functions”). Vsakemu neterminalu X ∈ N priredimo
GYH ORþHQL NRQþQL PQRåLFL DWULEXWRY 6 ;  LQ , ;  NMHU YHOMD 6 ; ∩ I(X) = ∅ (OHPHQWH PQRåLFH S(X)

imenujemo pridobljeni atributi (“synthesized attributes”) LQ HOHPHQWH PQRåLFH , ;  podedovani atributi
(“inherited attributes”) neterminala X. Velja naj še I(Z) = ∅NDUSRPHQLGD]DþHWQLQHWHUPLQDO gramatike
G nima podedovanih aWULEXWRYWHPYHþVDPRSULGREOMHQH'HILQLUDMPRãHQDVOHGQMHL]UD]H
• PQRåLFRYVHKDWULEXWRYQHWHUPLQDOD;$ ; = S(X) ∪ I(X),
• PQRåLFRYVHKSULGREOMHQLKDWULEXWRY6 = ∪X∈N S(X),
• PQRåLFRYVHKSRGHGRYDQLKDWULEXWRY, = ∪X∈N I(X) in
• PQRåLFRYVHKDWULEXWRYDWributne gramatike: A = I ∪ S.

$WULEXWH VL ODKNR SUHGVWDYOMDPR NRW VSUHPHQOMLYNH QHNHJD SRGDWNRYQHJD WLSD NL ]DY]DPHMR GRORþHQH

vrednosti 9UHGQRVWL DWULEXWRY VR QD ]DþHWNX QHGHILQLUDQH GRORþLPR MLK V VHPDQWLþQLPL IXQNFLMDPL

58
2.3 6(0$17,ý1$ ANALIZA
$WULEXWLSUHGVWDYOMDMRSROMXEQHREMHNWHNLMLKåHOLPRRYUHGQRWLWLSRVLQWDNWLþQHPUD]SR]QDYDQMXYKRGQHJD

stavka in vsebujejo informacije o neterminalih. Z njimi predstavimo poljubne vrednosti: niz, število,
strukture, objekte itd.
Poleg neterminalov nastopajo v kontekstno prosti gramatiki tudi terminali. Tem simbolom ne prirejamo
DWULEXWRY VDM LPDMR åH GHILQLUDQ SULGREOMHQ DWULEXW, v katerem je shranjena njihova leksikalna vrednost

(lexem – podpoglavje 2.1).


3UL GHOX V SURJUDPVNLPL MH]LNL RELþDMQR XSRUDEOMDPR GUXJDþQR LPH ]D MH]LN in stavek: jezik L(G)

imenujemo programski jezik in stavek w ∈ L(G) program.

Navedimo še nekaj prednosti atributnih gramatik:


• osnovna ideja in zapis atributne gramatike sta relativno preprosti,
• z atributno gramatiko lahko definiramo tako kontekstno proste kot tudi kontekstno odvisne vidike
programskega jezika,
• iz atributne gramatikeMHSRYVHPUD]YLGQDVLQWDNWLþQDVWUXNWXUD jezika in
• VHPDQWLþQDSUDYLODDWULEXWQHJUDPDWLNHVRVWUXNWXULUDQDJOHGHQDVLQWDNWLþQRVWUXNWXURMH]LND

3RVWRSHN L]UDþXQDYDQMD YUHGQRVWL DWULEXWRY QDYHGHPR V VHPDQWLþQLPL IXQNFLMDPL 9VDNL SURGXNFLML S

X0 → X1 X2 … XnpSULUHGLPRPQRåLFRVHPDQWLþQLKIXQNFLMNLGRORþDMRQDþLQL]UDþXQDYUHGQRVWL atributov
YPQRåLFDK6 ;0) in I(Xi), 1 ≤ i ≤ np. Za vsak pridobljeni atribut neterminala X0 GRORþLPRHQRVHPDQWLþQR

funkcijo in prav tako za vsak podedovani atribut vsakega neterminala Xi, 1 ≤ i ≤ np. Pri izvrševanju
VHPDQWLþQLK IXQNFLM YHOMD RPHMLWHY GD VH YVDND VHPDQWLþQD IXQNFLMD izvrši samo enkrat, in tako se tudi

DWULEXWRPGRORþLQMLKRYDYUHGQRVW samo enkrat.

SHPDQWLþQD IXQNFLMD fp,X.a: a = f(a1, a2, …, ak  GHILQLUD L]UDþXQ YUHGQRVWL atributa a neterminala X nad
atributi a1, a2, …, ak NL VR HOHPHQWL PQRåLF A(Xi), 0 ≤ i ≤ np 9 ELVWYX MH VHPDQWLþQD IXQNFLMD fp,X.a
prireditveni stavek, ki priredi atributu a novo vrednost. Ponavadi jih zapisujemo kot prireditvene stavke v
QHNHP]DSLVX PDWHPDWLþQL]DSLV, zapis v programskem jeziku C itd).

Atributu aNLMHYQHNLVHPDQWLþQLIXQNFLMLSULGUXåHQQHWHUPLQDOX;i, pravimo dogodek atributa (“attribute


occurrence”) 'RJRGHN DWULEXWD ODKNR R]QDþLPR ] a(i), (a, i), aXi ali tudi z Xi.a. 0QRåLFR YVHK GRJRGNRY
atribXWRY Y SURGXNFLML S R]QDþLPR ] :p: Wp = {a(i) | a ∈ Α(Xi), 0 ≤ i ≤ np}. Namesto pojma dogodek
atributa uporabljamo pogosto kar pojem atribut, vendar se moramo zavedati razlike med atributi in
konkretnimi dogodki atributov v posameznih semanWLþQLKIXQNFLMDK
Pomen (“semantics”) programa w ∈ / *  GRORþLPR ] DWULEXWL DWULEXWQH JUDPDWLNH. Definiramo ga kot
vrednostiYVHKSULGREOMHQLKDWULEXWRY]DþHWQHJDQHWHUPLQDOD=9UHGQRVWLDWULEXWRYDWULEXWQHJUamatike in s
tem njen pomenL]UDþXQDPR]DGRORþHQSURJUDPPHGovrednotenjem (“evaluation”) atributne gramatike.

Primer 2.27:
'RORþLPRSRPHQ binarnih številk, ki jih definiramo z naslednjo kontekstno prosto gramatiko:

59
2. SINTAKSA IN SEMANTIKA
Neterminali Terminali Produkcije
(X ∈ N): (x ∈ T): (p ∈ P):
E, C, B, D +, -, 0, 1 E→CB
C→+|-|ε
B→D|DB
D→0|1

=DSLãLPRDWULEXWQRJUDPDWLNRVNDWHURGRORþLPRSRPHQ binarnih številk kot desetiško vrednost:

Neterminali Pridobljeni atributi Podedovani atributi


(X ∈ N): (s ∈ S(X)): (i ∈ I(X)):
E {izhVred} ∅
C {jeNeg} ∅
B {izhVred} {vhoVred}
D {cifra} ∅

Produkcije 6HPDQWLþQHIXQNFLMH

(p ∈ P): (fp,a, a ∈ S(X0) ∨ a ∈ I(Xi), 1 ≤ i ≤ np):


E→CB B.vhoVred = 0
E.izhVred = (C.jeNeg = = true) ? −B.izhVred : B.izhVred
C→+ C.jeNeg = false
C→- C.jeNeg = true
C→ε C.jeNeg = false
B→D B.izhVred = B.vhoVred + D.cifra
B0 → D B1 B1.vhoVred = (B0.vhoVred + D.cifra) ∗ 2
B0.izhVred = B1.izhVred
D→0 D.cifra = 0
D→1 D.cifra = 1

=DþHWQLQHWHUPLQDO gramatike G je po dogovoru levi neterminal prve navedene produkcije (neterminal E).
Tipi atributov pa so naslednji: vhoVred, izhVred in cifra VR DWULEXWL FHORãWHYLOþQHJD WLSD PHGWHP NR MH
jeNeg atribut ORJLþQHJD WLSD .DGDU GRJRGNL DWULEXWRY ] LPHQRP QHWHUPLQDOD QLVR HQR]QDþQR GRORþHQL
dodamo neterminalom indekse B0, B1, … in ustrezne dogodke atributov pišemo kot B0.vhoVred ali
B1.izhVred.

Kontekstno prosta gramatika * ]D YVDN VLQWDNWLþQR SUDYLOHQ VWDYHN jezika L(G) definira drevo, ki opisuje
potek izpeljave tega stavka. To drevo imenujemo VLQWDNWLþQR drevo (“syntax tree”) ali drevo izpeljav
(“derivation tree”). 9VDNHPX QRWUDQMHPX YR]OLãþX VLQWDNWLþQHJD GUHYHVD je prirejen neterminal in
vsakemu listu terminal $WULEXWQR JUDPDWLNR SRYHåHPR V VLQWDNWLþQLP GUHYHVRP WDNR GD SULUHGLPR

60
2.3 6(0$17,ý1$ ANALIZA
DWULEXWH QRWUDQMLP YR]OLãþHP VLQWDNWLþQHJD GUHYHVD SUL XVWUH]QLK QHWHUPLQDOLK 6LQWDNWLþQHPX GUHYHVX Y

NDWHUHPMHYVDNRQRWUDQMHYR]OLãþHUD]ãLUMHQR]DWULEXWLXVWUH]QHJDQHWHUPLQDODSUDYLPRVHPDQWLþQR drevo
(“semantic tree”)3RYH]DYHYVHPDQWLþQHPGUHYHVXSULND]XMHMRSUHQRVYUHGQRVWL med atributi.
ýH VL QHWHUPLQDO Y QRWUDQMHP YR]OLãþX VHPDQWLþQHJD GUHYHVD predstavljamo kot objekt oz. spremenljivko

VWUXNWXULUDQHJDWLSDODKNRUHþHPRGDVRDWULEXWLHOHPHQWLWHVWUXNWXUH. Temu ustreza zapis Xi.a, ki je znan

v programskih jezikih. Torej je neterminal spremenljivka strukturiranega tipa, atribut pa je element te


strukture.
Pri definiciji atributne gramatike VPR DWULEXWH QHWHUPLQDOD UD]GHOLOL Y GYH ORþHQL PQRåLFL SRGHGRYDQH LQ
pridobljene atribute. Pomen obeh vrst atributov je naslednji: podedovani atributi prenašajo informacije
QDY]GRO SR VHPDQWLþQHP GUHYHVX WRUHM SURWL QMHJRYLP listom, pridobljeni atributi prenašajo informacije

QDY]JRU SR VHPDQWLþQHP GUHYHVX WRUHM SURWL QMHJRYHPX NRUHQX 9UHGQRVWL DWULEXWRY L]UDþXQDPR Y

VHPDQWLþQHP GUHYHVX WDNR GD RELVNXMHPR QMHJRYD YR]OLãþD Y GRORþHQHP ]DSRUHGMX LQ SUL YVDNHP RELVNX

XSRUDELPR HQR DOL YHþ VHPDQWLþQLK IXQNFLM SULGUXåHQLK SURGXNFLML Y GDQHP YR]OLãþX 1HWHUPLQDO QD OHYL

strani produkcije (X0  R] QMHJRYL DWULEXWL VH QDQDãDMR QD RELVNDQR YR]OLãþH QHWHUPLQDOL QD GHVQL VWUDQL
produkcije (X1, X2, ... , Xnp  LQ QMLKRYL DWULEXWL SD VH QDQDãDMR QD QDVOHGQLNH RELVNDQHJD YR]OLãþD
6HPDQWLþQH IXQNFLMH SURGXNFLMH S VH L]YDMDMR Y YVDNHP YR]OLãþX GUHYHVD izpeljav, ki predstavlja to

produkcijo, in tako ovreGQRWLMRSULGREOMHQHDWULEXWHY WHP YR]OLãþXDOLSRGHGRYDQHDWULEXWHYHQHPL]PHG


QMHJRYLKQDVOHGQLNRY0QRåLFRYVHKDWULEXWRY;i.aYVHPDQWLþQHPGUHYHVX7LPHQXMHPR:T0QRåLFD:T

MH PQRåLFD vseh primerkov atributov (“attribute instances”), ki jih moramo med procesom ovrednotenja

L]UDþXQDWL

Primer 2.28:
6OLNDNDåHVHPDQWLþQRGUHYR za stavek -101 gramatike iz primera 2.27. Pomen stavka -101 je število
-5.

61
2. SINTAKSA IN SEMANTIKA

E izhVred=-5

C jeNeg=true vhoVred=0 B izhVred=5

− D cifra=1 vhoVred=2 B izhVred=5

1 D cifra=0 vhoVred=4 B izhVred=5

0 D cifra=1

6OLND6HPDQWLþQRGUHYR za stavek -101.

9VHPDQWLþQLKIXQNFLMDKODKNRSULXSRUDELDWULEXWRYL]PQRåLF A(Xi), 0 ≤ i ≤ npGHILQLUDPRWXGLGRORþHQH

omejitve. Atributna gramatika je normalizirana (“normalized”) ali v normalni obliki (“normal form”),
NDGDU XSRUDEOMD QD GHVQL VWUDQL VHPDQWLþQLK IXQNFLM VDPR DWULEXWH NL VH L]UDþXQDMR L]YHQ SURGXNFLMH S

DWULEXWL Y PQRåLFDK , ;0) in S(Xi), 1 ≤ i ≤ np  9 QRUPDOL]LUDQL DWULEXWQL JUDPDWLNL ODKNR VHPDQWLþQH

funkcije]DL]UDþXQXSRUDEOMDMRVDPRDWULEXWHL]PQRåLF, ;0) in S(Xi), 1 ≤ i ≤ np, to so podedovani atributi


levega neterminala produkcije in pridobljeni atributi GHVQLK QHWHUPLQDORY SURGXNFLMH 9 YVDNL QHFLNOLþQL
DWULEXWQL JUDPDWLNL ODKNR SUHSLãHPR VHPDQWLþQH IXQNFLMH YHGQR WDNR GD SRVWDQH DWULEXWQD JUDPDWLND

normalizirana.
2EVWDMD ãH YPHVQD REOLND VHPDQWLþQLK IXQNFLM PHG SRSROQRPD VSORãQR LQ QRUPDOL]LUDQR DWULEXWQR

gramatiko. V tej vmesni obliki velja:


• þHMHa pridobljen atribut levega neterminala a ∈ S(X0), potem so a1, a2, …, ak poljubni atributi desnih
neterminalov, a1, a2, …, ak ∈ A(Xi), 1 ≤ i ≤ np;
• þH MH a podedovan atribut katerega izmed desnih neterminalov a ∈ I(Xi), 1 ≤ i ≤ np, potem so
a1, a2, …, ak poljubni atributi poljubnega neterminala, a1, a2, …, ak ∈ A(Xi), 0 ≤ i ≤ np.

9LGLPR GD Y WHP SULPHUX ]D L]UDþXQ SULGREOMHQLK DWULEXWRY GRYROMXMHPR WXGL XSRUDER SRGHGRYDQLK

DWULEXWRYL]PQRåLF, ;i ), 1 ≤ i ≤ npREWHKSD]DL]UDþXQSRGHGRYDQLKDWULEXWRYGRYROMXMHPRWXGLXSRUDER

62
2.3 6(0$17,ý1$ ANALIZA
pridobljenih atrLEXWRYL]PQRåLFH S(X0 9WDEHOLVRRSLVDQHUD]OLþQHYUVWHDWULEXWQLKJUDPDWLN glede na
GRYROMHQRXSRUDERDWULEXWRYSULGHILQLFLMLVHPDQWLþQLKIXQNFLM

1DMYHþNUDW XSRUDEOMDPR VSORãQH DWULEXWQH JUDPDWLN e, saj skrajšajo zapis LQ V WHP SRYHþDMR SUHJOHGQRVW LQ
XþLQNRYLWRVW 1DPHVWR GD Y YVDNL VHPDQWLþQL IXQNFLML QHNH SURGXNFLMH SRVHEHM L]UDþXQDYDPR LVWH

vrednosti, raje definiramo pri neterminalu X0 še en pridobljen atribut ,] DWULEXWRY NL VH L]UDþXQDMR L]YHQ
SURGXNFLMH S L]UDþXQDPR QDMSUHM YUHGQRVW tega pridobljenega atributa in ga nato uporabljamo v vseh

RVWDOLK VHPDQWLþQLK IXQNFLMDK 7DND DWULEXWQD JUDPDWLND seveda ni normalizirana, saj uporabljamo v

VHPDQWLþQLKIXQNFLMDKDWULEXWNLVHL]UDþXQDYWHMSURGXNFLMLMHSDEROMXþLQNRYLWD

Tabela 2.3: Vrste atributnih gramatik


Vrste atributnih gramatik 'RYROMHQLDWULEXWL]DL]UDþXQ atributa a
Normalne a ∈ S(X0): I(X0) ∪ S(Xi), 1 ≤ i ≤ np
a ∈ I(Xi): I(X0) ∪ S(Xi), 1 ≤ i ≤ np
Vmesne a ∈ S(X0): I(X0) ∪ A(Xi), 1 ≤ i ≤ np
a ∈ I(Xi): A(X0) ∪ A(Xi), 1 ≤ i ≤ np
Splošne a ∈ S(X0): A(X0) ∪ A(Xi), 1 ≤ i ≤ np
a ∈ I(Xi): A(X0) ∪ A(Xi), 1 ≤ i ≤ np

Nekateri avtorji uporabljajo namesto imena atributna gramatika tudi ime VLQWDNWLþQR usmerjena definicija
(“syntax directed definition”) %LVWYHQLK UD]OLN PHG REHPD QL 6LQWDNWLþQR XVPHUMHQD GHILQLFLMD je
DWULEXWQD JUDPDWLND UD]ãLUMHQD V VHPDQWLþQLPL IXQNFLMDPL NL QLVR SUHSURVWH SULUHGLWYH DWULEXWRY DPSDN

ODKNR LPDMR WXGL VWUDQVNH XþLQNH 7DNH VHPDQWLþQH IXQNFLMH ODKNR YNOMXþLPR Y DWULEXWQR JUDPDWLNR þH R

njih razmišljamo kot o funkcijah, ki definirajo navidezne pridobljene atribute. Te funkcije navideznim
atributom priredijo neke vrednosti, ki MLKSR]QHMHQHXSRUDEOMDPRYHþ
$WULEXWQH JUDPDWLNH QH GRORþDMR YUVWQHJD UHGD L]YDMDQMD SRVDPH]QH VHPDQWLþQH IXQNFLMH. Za razliko od

njih pa prevajalne sheme (“translation shemes”) SRSROQRPD GRORþDMR PHsto in vrstni red izvajanja
VHPDQWLþQLKIXQNFLM

Primer 2.29:
Prevajalna shema za gramatiko iz primera 2.27:

63
2. SINTAKSA IN SEMANTIKA

E→ C {B.vhoVred = 0}
B {E.izhVred = (C.jeNeg = = true)? −B.izhVred : B.izhVred}
C→ + {C.jeNeg = false}
C→ - {C.jeNeg = true}
C→ ε {C.jeNeg = false}
B→ D {B.izhVred = B.vhoVred + D.cifra}
B0 → D {B1.vhoVred = (B0.vhoVred + D.cifra) ∗ 2;}
B1 {B0.izhVred = B1.izhVred}
D→ 0 {D.cifra = 0}
D→ 1 {D.cifra = 1}

3UHYDMDOQH VKHPH XSRUDEOMDPR UHGNR VDM REVWDMDMR XþLQNRYLWL DOJRULWPL ]D GRORþDQMH YUVWQHJD UHGD

L]YDMDQMDVHPDQWLþQLKIXQNFLMDWULEXWQHJUDPDWLNH .

Ovrednotenje atributne gramatike

Ovrednotenje atributne gramatike je postopek, med katerim izvajamo obhode (“traversals”) po


VHPDQWLþQHP GUHYHVX VWDYND 0HG REKRGL L]YDMDPR Y YR]OLãþLK GUHYHVD VHPDQWLþQH IXQNFLMH in atributom

SULUHMDPRL]UDþXQDQHYUHGQRVWLLQWDNRL]UDþXQDPo pomen atributne gramatike.

3UHGL]YDMDQMHPVHPDQWLþQLKIXQNFLMYQHNHPYR]OLãþXVRSRGHGRYDQLDWULEXWL neterminala X0 z leve strani

in pridobljeni atributi neterminalov Xi, 1 ≤ i ≤ np ]GHVQHVWUDQLSURGXNFLMHåHGRORþHQL1MLKRYHYUHGQRVWL


GRELPR L] RNROLãNLK YR]OLãþ VHPDQWLþQHJD GUHYHVD. Pravila za ovrednotenje atribXWRY GRORþDMR L]UDþXQ

preostalih atributov (pridobljeni atributi neterminala X0 in podedovani atributi neterminalov Xi, 1 ≤ i ≤ np).
Evaluator (“evaluator”) atributne gramatike je program, ki sprejme na vhodu sHPDQWLþQR GUHYR in ga
RYUHGQRWL2YUHGQRWHQMHVH]DþQH]QHGHILQLUDQLPLYUHGQRVWPLDWULEXWRYYYR]OLãþLKVHPDQWLþQHJDGUHYHVD.

9 YVDNHP NRUDNX L]EHUHPR HQHJD L]PHG DWULEXWRY NL JD ODKNR RYUHGQRWLPR ] QHNR VHPDQWLþQR funkcijo.

,]EUDQD VHPDQWLþQD IXQNFLMD se izvrši in ustrezni atribut Y YR]OLãþX VH SRVWDYL QD L]UDþXQDQR YUHGQRVW.

3RVWRSHN QDGDOMXMHPR WDNR GROJR GRNOHU QLVR L]UDþXQDQL YVL DWULEXWL Y GUHYHVX 3RYHGDOL VPR åH GD

DWULEXWQH JUDPDWLNH QH GRORþDMR QDWDQþQHJD YUVWQHJD UHGD L]UDþXQD DWULEXWRY 7DNR GHILQLUDQL HYDOXDWRU

zato imenujemo QHGHWHUPLQLVWLþQL (“nondeterministic”), saj lahko v vsakem koraku za ovrednotenje


izberemo poljuben atribut, ki je pripravljen.
Glede na zapletenost in zahtevnost pri ovrednotenju delimo atributne gramatikeQDYHþUD]UHGRY
• atributne gramatike vrste S,
• atributne gramatike vrste L,
• QHFLNOLþQHDWULEXWQHJUDPDWLNH in
• DEVROXWQRQHFLNOLþQHDWULEXWQHJUDPDWLNH.

64
2.3 6(0$17,ý1$ ANALIZA
Poleg opisanih razredov atributnih gramatik obstaja še mnogo drugih podrazredov, za katere veljajo
GRORþHQH ODVWQRVWL NL MLK ODKNR XSRUDELPR SUL L]JUDGQML HYDOXDWRUMD 6HYHGD QL QXMQR GD MH VHPDQWLþQR

drevo tudi neposreGQR ]JUDMHQR 3UDY WDNR ODKNR XSRUDELPR YHþ REKRGRY SR VHPDQWLþQHP GUHYHVX
$WULEXWL VH ODKNR L]UDþXQDYDMR QD QDþLQ NL ]DKWHYD YHþNUDWQR RELVNRYDQMH LVWLK YR]OLãþ VHPDQWLþQHJD

drevesa.

Atributne gramatike vrste S

V praksi pogosto uporabljamo pridobljene atribute. Atributnim gramatikam, ki uporabljajo samo


pridobljene atribute, pravimo atributne gramatike vrste S (“S-attributed grammar”). Atributne gramatike
vrste S prenašajo vrednostiDWULEXWRYYOLVWLKVHPDQWLþQHJDGUHYHVDLQMLK]GUXåXMHMRSRGUHYHVXQDY]JRUGR
NRUHQDVHPDQWLþQHJDGUHYHVD

Atributna gramatika za jezik binarnih številk iz primera 2.27 ni vrste S, saj ima neterminal B podedovan
atribut vhoVred.
3ROMXEQR VHPDQWLþQR GUHYR za atributno gramatiko vrste S lahko vedno ovrednotimo z enim obhodom

drevesa Y JORELQR 2YUHGQRWHQMH ]DþQHPR Y NRUHQX VHPDQWLþQHJD GUHYHVD 9 WUHQXWQHP YR]OLãþX QDMSUHM
RELãþHPR YVH VLQRYH YR]OLãþD NDU SRPHQL GD ]D YVDNHJD RG QMLK UHNXU]LYQR SRNOLþHPR SURFHGXUR ]D

ovrednotenje 3R RYUHGQRWHQMX YVHK VLQRY L]UDþXQDPR ãH YVH VHPDQWLþQH IXQNFLMH WHJD YR]OLãþD LQ
priredimo vrednosti SULGREOMHQLP DWULEXWRP WHJD YR]OLãþD 7H VHPDQWLþQH IXQNFLMH VR RGYLVQH VDPR RG
DWULEXWRY VLQRY NL VR åH RYUHGQRWHQL RE QMLKRYHP RELVNX7DNR VH L]UDþXQDMR YUHGQRVWL YVHK SULGREOMHQLK

aWULEXWRYWUHQXWQHJDYR]OLãþD=DOJRULWPRPRYUHGQRWLPRDWULEXWQRJUDPDWLNRYUVWH6

Algoritem 2.2:

procedureRYUHGQRWLBYR]OLãþH YR]OLãþH;0)
begin
naj bo pSURGXNFLMDXSRUDEOMHQDYYR]OLãþX;0
for i = 1 to np do {]DYVHVLQRYHYR]OLãþD;0}
begin
if (Xi ∈ N) then
RYUHGQRWLBYR]OLãþH ;i)

end
L]UDþXQDMSULGREOMHQHDWULEXWHYR]OLãþD;0

end

Primer 2.30:
Naj bo dana kontekstno prosta gramatika]DDULWPHWLþQHL]UD]H

65
2. SINTAKSA IN SEMANTIKA
Neterminali Terminali Produkcije
(X ∈ N): (x ∈ T): (p ∈ P):
R, E, T, F +, -, *, /, % R→E
(, ) E→T|E+T|E-T
number T→F|T*F|T/F|T%F
F → ( E ) | number

Terminal numberR]QDþXMHSROMXEQRFHORãWHYLOR]JUDMHQR]UHJXODUQLPL]UD]RP(+|-)?[0−9]+.

Zapišimo atribuWQRJUDPDWLNRYUVWH6VNDWHURGRORþLPRSRPHQDULWPHWLþQLKL]UD]RY

Neterminali Pridobljeni atributi Podedovani atributi


(X ∈ N): (s ∈ S(X)): (i ∈ I(X)):
R {vred} ∅
E {vred} ∅
T {vred} ∅
F {vred} ∅

Produkcije (p ∈ P): 6HPDQWLþQHIXQNFLMH Ip,a , a ∈ S(X0)):


R →E R.vred = E.vred
E →T E.vred = T.vred
E0 → E1 + T E0.vred = E1.vred + T.vred
E0 → E1 - T E0.vred = E1.vred − T.vred
T →F T.vred = F.vred
T0 → T1 * F T0.vred = T1.vred * F.vred
T0 → T1 / F T0.vred = T1.vred div F.vred
T0 → T1 % F T0.vred = T1.vred mod F.vred
F →(E) F.vred = E.vred
F → number F.vred = Str2Int(number.lexVred)

Atribut vred QDM ER FHORãWHYLOþQHJD tipa. Privzemimo še, da sistem za implementacijo atributne gramatike
in njegov leksikalni analizator RE YVDNHP UD]SR]QDQHP WHUPLQDOX GRORþL WXGL QMHJRYR YUHGQRVW ter jo
zapiše v atribut lexVred, ki je tipa niz znakov.
Oglejmo si ovrednotenje DULWPHWLþQHJD L]UD]D 4 * 3 – 2 + 1 $WULEXWL VH L] OLVWRY VHPDQWLþQHJD GUHYHVD
prenašajo navzgor do korena drevesa. Proces ovrednoWHQMD MH SULND]DQ QD VOLNL  3RPHQ DULWPHWLþQHJD
izraza je število 11.

66
2.3 6(0$17,ý1$ ANALIZA

R vred=11

E vred=11

E vred=10 + T vred=1

E vred=12 − T vred=2 F vred=1

T vred=12 F vred=2 number lexVred="1"

T vred=4 * F vred=3 number lexVred="2"

F vred=4 number lexVred="3"

number lexVred="4"

6OLND6HPDQWLþQRGUHYR]DDULWPHWLþQLL]UD] 4*3–2+1

 Atributne gramatike vrste L

Tudi atributne gramatike vrste L (“L-attributed grammar”) imajo omejeno uporabo atributov. Atributno
gramatiko vrste L dobimo takrat, kadar je vsak podedovan atribut neterminala Xi, i ≥ 1 odvisen le od
atributov neterminalov, ki stojijo levo od Xi (X0, X1, …, Xi-1  7DNL DWULEXWL VR Y VHPDQWLþQHP GUHYHVX
RGYLVQL OH RG VRVHGRY QD OHYL LQ RG RþHWD XVWUH]QHJD YR]OLãþD 3RJRM VH QDQDãD VDPR QD SRGHGRYDQH

atribute, zato je vsaka atributna gramatika vrste S tudi vrste L.


Prav tako, kot atributno gramatiko vrste S, lahko tudi poljubno atributno gramatiko vrste L vedno
ovrednotimo z enim obhodom drevesa v globino. Ovrednotenje izvajamo podobno kot pri atributnih
JUDPDWLNDK YUVWH 6 OH GD Y YR]OLãþX VHPDQWLþQHJD GUHYHVD SUHG RELVNRP LQ RYUHGQRWHQMHP VLQRY

L]UDþXQDPRãHSRGHGRYDQHDWULEXWHYR]OLãþD=DOJRULWPRPRYUHGQRWLPRDWULEXWQRJUDPDWLNRYUVWH/

67
2. SINTAKSA IN SEMANTIKA
Algoritem 2.3:

procedureRYUHGQRWLBYR]OLãþH YR]OLãþH;0)
begin
QDMERSSURGXNFLMDXSRUDEOMHQDYYR]OLãþX;0

for i = 1 to np do {]DYVHVLQRYHYR]OLãþD;0}
begin
if (Xi ∈ N) then
begin
L]UDþXQDMSRGHGRYDQHDWULEXWHYR]OLãþD;i

RYUHGQRWLBYR]OLãþH ;i )
end
izUDþXQDMSULGREOMHQHDWULEXWHYR]OLãþD;0
end
end

Funkcije za ovrednotenje atributnih gramatik vrste S in vrste L lahko preprosto vgradimo v rekurzivni
navzdolnji razpoznavalnik.

Primer 2.31:
Poglejmo si evaluator za atributno gramatiko iz primera 2.30. Vendar za ta primer ne moremo zapisati
rekurzivnega navzdoljnega razpoznavalnika, ker v kontekstno prosti gramatiki nismo odpravili leve
rekurzije (podpoglavje 2.2.2). Potem ko odpravimo levo rekurzijo, se spremeni kontekstno prosta
gramatika in s tem tudi atributna gramatika. Zaradi poenostavitve smo iz primera 2.30 izpustili operatorje
-, /, %.

Neterminali Pridobljeni atributi Podedovani atributi


(X ∈ N): (s ∈ S(X)): (i ∈ I(X)):
E {vred} ∅
EE {vred} {invred}
T {vred} ∅
TT {vred} {invred}
F {vred} ∅

68
2.3 6(0$17,ý1$ ANALIZA

Produkcije (p ∈ P): 6HPDQWLþQHIXQNFLMH Ip,a, a ∈ S(X0)):


E → T EE E.vred = EE.vred
EE.invred = T.vred
EE0 → + Τ ΕE1 EE0.vred = ΕE1.vred
EE1.invred = EE0.invred + T.vred
EE0 →ε EE0.vred = EE0.invred
T → F TT T.vred = ΤΤ.vred
TT.invred = F.vred
TT0 → ∗ F ΤΤ1 TT0.vred = ΤΤ1.vred
ΤΤ1.invred = ΤΤ0.invred * F.vred
TT0 →ε TT0.vred = ΤΤ0.invred
F →(E) F.vred = E.vred
F → number F.vred = Str2Int(number.lexVred)

Evaluator za atributno gramatiko vrste L implementiramo preprosto tako, da v rekurzivni navzdolnji


razpoznavalnik YNOMXþLPR VHPDQWLþQH IXQNFLMH =D YVDN QHWHUPLQDO ]DSLãHPR SRGSURJUDP NL LPD WROLNR
parametrov, kot ima neterminal atributov. Pri tem se podedovani atributi prenašajo po vrednosti in
pridobljeni atributi po referenci. Evaluator zapišimo v programskem jeziku C++ !

// DATOTEKA: Evaluator.h

#ifndef EVALUATOR_H
#define EVALUATOR_H
#include "Scanner.h"

class Evaluator {
private:
Scanner* scanner; // glej primer 2.14
protected:
bool E(int& val) {
int tempVal;
bool ok = T(tempVal);
return ok && EE(tempVal, val);
}

bool EE(int inVal, int &val) {


if (scanner->currentToken().getLexem()=="+")
{
scanner->nextToken();
int tempVal;
bool ok = T(tempVal);
return ok && EE(inVal+tempVal,val);
}
else

69
2. SINTAKSA IN SEMANTIKA
{
val = inVal;
return true;
}
}
bool T(int &val) {
int tempVal;
bool ok = F(tempVal);
return ok && TT(tempVal, val);
}
bool TT(int inVal, int &val) {
if (scanner->currentToken().getLexem()=="*")
{
scanner->nextToken();
int tempVal;
bool ok = F(tempVal);
return ok && TT(inVal*tempVal,val);
}
else
{
val = inVal;
return true;
}
}
bool F(int &val) {
if (scanner->currentToken().getToken()==Scanner::tInteger)
{
val = atoi(scanner->currentToken().getLexem().c_str());
scanner->nextToken();
return true;
}
else
if (scanner->currentToken().getLexem()=="(")
{
scanner->nextToken();
bool zac = E(val);
if (zac && scanner->currentToken().getLexem()==")")
{
scanner->nextToken();
return true;
}
else return false;
}
else
return false;
}

70
2.3 6(0$17,ý1$ ANALIZA
public:
Evaluator(Scanner* aScanner) {
scanner = aScanner;
scanner->nextToken();
}
bool parse(int &val) {
return E(val) && scanner->currentToken().isEof();
}
};

#endif
#include <fstream.h>
#include "Parser.h" // glej primer 2.26
#include "Evaluator.h"

int main(int argc, char** argv) {


Scanner s = Scanner(new ifstream(argv[1]));
Token token;

s = Scanner(new ifstream(argv[1]));
int val;
Evaluator e(&s);
if (e.parse(val))
cout << val << endl;
else
cout << "false" << endl;
}

3RGHGRYDQL DWULEXWL VR SULPHUQL ]D L]UDåDQMH NRQWHNVWQH RGYLVQRVWL Y MH]LNX .RQWHNVWQD RGYLVQRVW ODKNR

QDVWRSD Y MH]LNX SUL GHILQLFLML LQ XSRUDEL VSUHPHQOMLYN NMHU PRUDPR SUHYHULWL DOL MH XSRUDEOMHQR LPH åH

bilo definirano. Takšnih preverjanj s kontekstno prosto gramatiko ne moremo opisati, lahko pa uporabimo
podedovane atribute.
Atributne gramatike vrste L vsebujejo vse atributne gramatike, pri katerih se lahko ovrednotenje izvaja
brez izgradnje semantLþQHJDGUHYHVD. Zato je ta razred atributnih gramatik še posebej pomemben.

 1HFLNOLþQHLQDEVROXWQRQHFLNOLþQHDWULEXWQHJUDPDWLNH

Medtem ko atributne gramatike vrste L RPHMXMHMR XSRUDER DWULEXWRY ODKNR YVHEXMHMR QHFLNOLþQH LQ
DEVROXWQR QHFLNOLþQHDWULEXWQH JUDPDWLNH podedovane atribute, ki so odvisni tudi od atributov neterminala

Xi in atributov neterminalov, ki so desno od neterminala Xi (Xi+1, Xi+2, …, Xnp). Take atributne gramatike
QD VSORãQR QL PRJRþH RYUHGQRWLWL ] HQLP REKRGRP GUHYHVD Y JORELQR WHPYHþ PRUDPR DQDOL]LUDWL

odvisnost med posameznimi atributi in iz analize ugotoviti pravilen obhod drevesa za ovrednotenje
atribXWRY 7D ODKNR YNOMXþXMH RELVNH YR]OLãþ VHPDQWLþQHJD GUHYHVD Y SROMXEQHP YUVWQHP UHGX WXGL
YHþNUDWQHRELVNHLVWLKYR]OLãþ

71
2. SINTAKSA IN SEMANTIKA
Na sliki 2.7 je prikazano zaporedje postopkov za analizo odvisnosti med atributi gramatike. V
nadaljevanju bomo opisali posamezne postopke.
Za osvetlitev navedenih postopkov bomo uporabljali atributno gramatiko za jezik binarnih številk. Ker je
ta atributna gramatika vrste L, je tudi absolutQR QHFLNOLþQD NDU ERPR ] L]UDþXQRP UD]ãLUMHQLK JUDIRY
odvisnosti tudi preverili.

vhodno/
izhodni grafi
vrstni red
VHPDQWLþQH PQRåLFH grafi
ovrednotenja
funkcije odvisnosti odvisnosti
razširjeni atributov
grafi
odvisnosti

Slika 2.7: Postopki pri analizi odvisnosti med atributi gramatike

6HPDQWLþQDIXQNFLMDMHY]DSRUHGMXIXQNFLM]DL]YDMDQMHQDWDQþQRGRORþHQD]RGYLVQRVWPL med atributi, ki


MLK XSRUDEOMD LQ ] DWULEXWRP NL JD L]UDþXQD 9 WD QDPHQ GHILQLUDPR ]D YVDNR VHPDQWLþQR IXQNFLMR Ip,a

produkcije p PQRåLFR odvisnosti DSp,a (“dependency set”) 0QRåLFD RGYLVQRVWL '6p,a MH PQRåLFD vseh
atributov, ki se upoUDEOMDMRQDGHVQLVWUDQLVHPDQWLþQHIXQNFLMH fp,a: a = f(a1, a2, …, ak).
Definirajmo relacijo lokalnih odvisnosti DRp med atributoma Xi.a in Xj.b za dano produkcijo p:

∀ Xi.a ∈ DSp,Xj.b ⇒ Xi.a DRp Xj.b

Atributa Xi.a in Xj.b sta v relaciji DRp, kadar se atribut Xi.aSRMDYLYPQRåLFLRGYLVQRVWL]DDWULEXW Xj.b.
Graf odvisnosti DGp (“dependency graph”) produkcije p je graf relacije DRp. To je usmerjen graf, ki
JUDILþQR SUHGVWDYOMD RGYLVQRVWL PHG DWULEXWL Y YVHK VHPDQWLþQLK IXQNFLMDK SURGXNFLMH S 9 QMHP VR

predstavljene lokalne odvisnosti PHGDWULEXWLVHPDQWLþQLKIXQNFLMSURGXNFLMHS


9R]OLãþDJUDIDRGYLVQRVWL DGpVRYVLDWULEXWLYVHKQHWHUPLQDORYL]SURGXNFLMHSýHMHDWULEXW b odvisen od

atributa a, potem imamo v grafu odvisnosti usmerjeno povezavo od a proti b:

∀ Xi.a ∈ DSp,Xj.b ⇒ DGp = DGp ∪ (Xj.a, Xi.b)

Povezave v grafu odvisnosti DGp lahko obravnavamo kot poti pretoka podatkov med atributi atributne
gramatike. Na sliki 2.8 so narisani grafi odvisnosti produkcij za jezik binarnih številk iz primera 2.27.

72
2.3 6(0$17,ý1$ ANALIZA

DGE →CB DGC →+ DGC →− DGC →ε

E izhVred C jeNeg C jeNeg C jeNeg

C jeNeg vhoVred B izhVred

DGB→ D DGB→ DB DGD→0 DGD→1

vhoVred B izhVred vhoVred B izhVred D cifra D cifra

D cifra D cifra vhoVred B izhVred

Slika 2.8: Grafi odvisnosti za jezik binarnih številk

Graf odvisnosti DGT VHPDQWLþQHJD GUHYHVD T dobimo s sestavljanjem grafov odvisnosti DGp produkcij
VHPDQWLþQHJD GUHYHVD7D SUHGVWDYOMD SRWL SUHWRND SRGDWNRY Y FHOHP VHPDQWLþQHP GUHYHVX ]D VLQWDNWLþQR

pravilen stavek jezika. Kadar ima graf odvisnosti drevesa T za kak stavek jezika cikel, pravimo, da je
atributna gramatika FLNOLþQD (“circular”). Atributna gramatika je QHFLNOLþQD (“noncircular”), kadar graf
odvisQRVWLQLPDFLNORY]DQREHQRVHPDQWLþQRGUHYR T.
ýH JUDI RGYLVQRVWL DGT na nekem nivoju prekinemo, prekinemo s tem poti pretoka podatkov. Nekatere

poti postanejo tako usmerjene navzgor (poti usmerjene v pridobljene atribute), druge so usmerjene
navzdol ali pa so na istem nivoju (poti usmerjene v podedovane atribute). Zato imenujemo takšne atribute
tudi vhodne atribute (“input attributes”) oz. izhodne atribute (“output attributes”). Vhodni atributi morajo
biti na voljo preden lahko ovrednotimo izhodne atribute. Na sliki 2.9 je prikazan graf odvisnosti
VHPDQWLþQHJDGUHYHVD jezika binarnih števil za stavek -10.

73
2. SINTAKSA IN SEMANTIKA
E izhVred

C jeNeg vhoVred B izhVred

− D cifra vhoVred B izhVred

1 D cifra

Slika 2.9: Graf odvisnosti za drevo, ki ustreza stavku -10

mi ponazorimo odvisnosti med atributi


=DUD]OLþQHVWDYNHVRJUDILRGYLVQRVWL'*TUD]OLþQL=DWRODKNR]QML

le za konkretne stavke. Za izgradnjo evaluatorja, ki lahko sprejme poljuben stavek, moramo predvideti vse
PRåQH RGYLVQRVWL Y SROMXEQHP VHPDQWLþQHP GUHYHVX WXGL þH VH RGYLVQRVW SUHQDãD SR YHþ QLYRMLK 7H

odvisnosti zapišemo v razširjenem grafu odvisnosti DGp* (“augmented dependency graph”), ki ga


UHNXU]LYQR L]UDþXQDPR L] XVWUH]QHJD JUDID RGYLVQRVWL '*p V SRPRþMR vhodno/izhodnih grafov (“input-

output graphs”).
Vhodno/izhodni graf IOX neterminala X predstavlja vhodno/izhodne odvisnosti atributov pri neterminalu
;9R]OLãþDJUDIDVRDWULEXWLQHWHUPLQDOD;8VPHUMHQDSRYH]DYD od atributa a do atributa b neterminala X

SRPHQL GD REVWDMDVHPDQWLþQD IXQNFLMD ali zaporedje VHPDQWLþQLK IXQNFLM NL SUHVOLNDMR DWULEXW a v atribut

b. Atribut b je tako neposredno ali posredno odvisen od atributa a.


Imejmo podane vhodno/izhodne grafe IOX1, IOX2, … , IOXnp za simbole gramatike Xi produkcije p, pri
*
þHPHU QDM YHOMD GD MH ,2Xi SUD]HQ JUDI þH VLPERO Xi ni neterminal. Razširjen graf odvisnosti DGp

L]UDþXQDPR WDNR GD JUDI RGYLVQRVWL '*p razširimo s povezavami iz vhodno/izhodnih grafov IOX1, IOX2,

…, IOXnp=DOJRULWPRPL]UDþXQDPRYKRGQRL]KRGQHJUDIHLQUD]ãLUMHQHJUDIHRGYLVQRVWL

Algoritem 2.4:

L]GHODM]DþHWQHJUDIH'*p* tako, da prepišeš vse povezave iz grafov DGp;


L]GHODM]DþHWQHSUD]QHJUDIH,2X za vsak neterminal X

do

1. za vsako pot v trenutnih grafih DGp* od


podedovanega atributa X0.a do pridobljenega atributa
X0.b dodaj povezavo v vhodno/izhodni graf IOX0þHMHWDPãHQL
povezave dodaMDMGRNOHUQLYHþQRYLKSRYH]DY

74
2.3 6(0$17,ý1$ ANALIZA
2. za vsak graf DGp* produkcije p preglej
vhodno/izhodne grafe IOX1, IOX2, …, IOXnp in
za vsako povezavo v IOXi od atributa Xi.a do
atributa Xi.b dodaj povezavo v graf DGp*þHMHWDPãHQL
povezave dodajaj, dRNOHUQLYHþQRYLKSRYH]DY

while (ponavljaj, dokler v grafe DGp* ni bila


dodana nobena nova povezava)

grafi DGp* in IOXVRL]UDþXQDQL

Atributna gramatika je absolutno QHFLNOLþQD (“absolutely noncircular”) þH QRben graf DGp* ne vsebuje
FLNOD $EVROXWQD QHFLNOLþQRVW MH VWURåML SRJRM NRW QHFLNOLþQRVW ýH MH DWULEXWQD JUDPDWLND absolutno

QHFLNOLþQDSRWHPMHWXGLQHFLNOLþQDREUDWQRQHYHOMD7RSRPHQLGDLPDPRODKNRDWULEXWQRJUDPDWLNR ki

MH QHFLNOLþQD JUDIL RGYLVQRVWL GUHYHV VR ]D YVH VWDYNH GHILQLUDQHJD MH]LND QHFLNOLþQL  YHQGDU UD]ãLUMHQL

grafi odvisnosti vsebujejo vsaj en cikel.

Na sliki 2.10 so narisani vhodno/izhodni grafi in na sliki 2.11 razširjeni grafi odvisnosti za gramatiko
binarnih številk iz primera 2.27. V grafih odvisnosti (slika 2.8) najprej opazimo povezavo v produkciji
B → D od atributa B.vhoVred do atributa B.izhVred, zato jo dodamo v vhodno/izhodni graf za neterminal
B. Ker smo v IOB dodali novo povezavo, pregledamo grafe odvisnosti in ugotovimo, da lahko dodamo to
povezavo pri produkcijah E → C B in B → D B.
Nato se vrnemo na iskanje novih povezav od podedovanega do pridobljenega atributa in ker ni nobene
novH SRYH]DYH WXGL Y JUDIH RGYLVQRVWL QH PRUHPR GRGDWL QRYLK SRYH]DY 7DNR VPR L]UDþXQDOL
vhodno/izhodne grafe in razširjene grafe odvisnosti.

IOE IOC IOB IOD

E izhVred C jeNeg B izhVred D cifra

B vhoVred

Slika 2.10: Vhodno/izhodni grafi za jezik binarnih številk

.RWVPRåHSRYHGDOLDWULEXWQHJUDPDWL ke ne vsiljujejo nobenega posebnega vrstnega reda za ovrednotenje


atributov. Zagotovljeno mora biti le, da se atribut a, od katerega je odvisen atribut b, ovrednoti prej kot
atribut b 9VDN YUVWQL UHG NL L]UDþXQD DWULEXW a pred vsemi drugimi atributi, ki so od njega odvisni, je
zadovoljiv. Videli smo, da dobimo pri atributni gramatiki vrste S in vrste L zadovoljiv vrstni red
RYUHGQRWHQMD þH XSRUDELPR REKRG VHPDQWLþQHJD GUHYHVD Y JORELQR =D DEVROXWQR QHFLNOLþQR DWULEXWQR

JUDPDWLNR GRORþLPR YUVWQL UHG L]YDMDQMD VHPDQWLþQLK IXQNFLM L] JUDIRY RGYLVQRVWL DOL L] UD]ãLUMHQLK JUDIRY

75
2. SINTAKSA IN SEMANTIKA
odvisnosti. V ta namen definirajmo topološko urejenost (“topological sort”) XVPHUMHQHJD DFLNOLþQega
grafa. To je takšno zaporedjeYR]OLãþJUDID m1, m2, …, mnNMHUJUHGRXVPHUMHQHSRYH]DYHL]YR]OLãþNLVR
SUHMY]DSRUHGMXSURWLYR]OLãþHPNLVRSR]QHMHY]DSRUHGMXýHMHYJUDIXXVPHUMHQDSRYH]DYD od mi proti

mj, potem se mora v zaporedju mi pojaviti pred mj. Poljubna topološka urejenost atributov (razširjenih)
JUDIRY RGYLVQRVWL GDMH YHOMDYHQ YUVWQL UHG V NDWHULP ODKNR RYUHGQRWLPR VHPDQWLþQD SUDYLOD DWULEXWQH

gramatike. Kadar tak vrstnL UHG REVWDMD SUDYLPR GD VR DWULEXWL RSLVDQL V VHPDQWLþQLPL IXQNFLMDPL dobro
definirani (“well defined”).

DG *E →CB DG *C →+ DG *C →− DG *C →ε
E izhVred C jeNeg C jeNeg C jeNeg

C jeNeg vhoVred B izhVred

DG *B→ D DG *B→ DB DG *D→0 DG *D→1


vhoVred B izhVred vhoVred B0 izhVred D cifra D cifra

D cifra D cifra vhoVred B1 izhVred

Slika 2.11: Razširjeni grafi odvisnosti za jezik binarnih številk

Primer 2.32:
,]UDþXQDMPRYUVWQLUHGRYUHGQRWHQMD]DQDVOHGQM o atributno gramatiko:

Neterminali Terminali Produkcije


(X ∈ N): (x ∈ T): (p ∈ P):
R, A, B a, b R→A
A→aB|aaB
B→b|bb

Neterminali Pridobljeni atributi Podedovani atributi


(X ∈ N): (s ∈ S(X)): (i ∈ I(X)):
R {r} ∅
A {z} {c}
B {x, y} {a, b}

76
2.3 6(0$17,ý1$ ANALIZA

Produkcije (p ∈ P): 6HPDQWLþQHIXQNFLMH (fp,a): 0QRåLFHRGYLVQRVWL'6p,a

R→A R.r = A.z {A.z}


A.c = 1 ∅
A→aB A.z = B.y {B.y}
B.a = A.c {A.c}
B.b = B.x {B.x}
A→aaB A.z = B.x {B.x}
B.a = B.y {B.y}
B.b = A.c {A.c}
B→b B.x = B.a {B.a}
B.y = B.b {B.b}
B→bb B.x = B.a {B.a}
B.y = 2 ∅

0RåQLVWDYNLGHILQLUDQHJDMH]LNDVRa b, a b b, a a b in a a b b. Vidimo, da atributna gramatika ni vrste L,

saj je podedovani atribut B.b Y VHPDQWLþQL IXQNFLML %b = B.x produkcije A → a B odvisen od atributa
istega neterminala. Spomnimo se, da mora biti vsak podedovani atribut neterminala X odvisen od
DWULEXWRY QHWHUPLQDORY OHYR RG ; þH QDM ER DWULEXWQD JUDPDWLND YUVWH /. Atributna gramatika je

normalizirana.
Ker smo ugotovili, da atributna gramatikaQLYUVWH/ODKNRQDGDOMXMHPR]L]UDþXQRP JUDIRYRGYLVQRVWLLQ
razširjenih grafov odvisnosti (slika 2.12). Vidimo, da noben izmed grafov odvisnosti ne vsebuje cikla.

DGR → A DG A→aB DGB→aaB DGB→b DGB→bb

R r c A z c A z a b B x y a b B x y

c A z a b B x y a b B x y

Slika 2.12: Grafi odvisnosti

6HGDMSULNDåLPRãHYKRGQRL]KRGQHJUDIHLQUD]ãLUMHQHJUDIHRGYLVQRVWL2EHPQRåLFLJUDIRYVWDSULND]DQL

na slikah 2.13 in 2.14.

77
2. SINTAKSA IN SEMANTIKA

IOR IO A IOB
R r A z B x y

A c B a b

Slika 2.13: Vhodno/izhodni grafi

DG *R → A DG * A→aB DG *B→aaB DG *B→b DG *B→bb

R r c A z c A z a b B x y a b B x y

c A z a b B x y a b B x y

Slika 2.14: Razširjeni grafi odvisnosti

Tudi razširjeni grafi odvisnosti nimajo nobenega cikla, zato je atributna gramatika tudi absolutno
QHFLNOLþQD 1D NRQFX L]UDþXQDMPR ãH WRSRORãNR XUHMHQRVW DWULEXWRY UD]ãLUMHQLK JUDIRY RGYLVQRVWL ]D YVDN

graf iz razširjenih grafov odvisnosti. Primeren vrstni red atributov za ovrednotenje je naslednji:

R→A {A.c, A.z, R.r}


A→aB {A.c, B.a, B.x, B.b, B.y, A.z}
A→aaB {A.c, B.b, B.y, B.a, B.x, A.z}
B→b {B.a, B.b, B.x, B.y}
B→bb {B.a, B.x}

Vidimo, da se mora ovrednotenje QHWHUPLQDOD % Y GUXJL LQ WUHWML SURGXNFLML NOLFDWL GYDNUDW SUYLþ GD VH
ovrednoti prvi pridobljeni atribut (B.x oz. B.y  QDWR VH L]UDþXQD YUHGQRVW podedovanemu atributu B.b oz.
B.aGUXJLþSDGDVHRYUHGQRWLMRGUXJLSULGREOMHQLDWULEXWL (B.y oz. B.x).

78
2.4 GENERATORJI PREVAJALNIKOV

GENERATORJI PREVAJALNIKOV

H generatorjem prevajalnikom prištevamo orodja, ki popolnoma avtomatizirajo del ali celoten postopek
prevajanja. Generator pregledovalnikov ("scanners generator”) dobi na vhodu formalni opis osnovnih
leksikalnih simbolov in generira pregledovalnik NL VSUHMHPD åHOHQH RVQRYQH OHNVLNalne simbole. Najbolj
znan generator pregledovalnikov je Lex (1975), ki je standardno orodje okolja UNIX. Generator
razpoznavalnikov ("parsers generator") dobi na vhodu BNF in generira razpoznavalnik. Prvi generatorji
razpoznavalnikov so generirali rekurzivne navzdolnje razpoznavalnike. Generatorji razpoznavalnikov, ki
temeljijo na gramatikah LR, se pogosteje uporabljajo, ker sprejemajo širši razred gramatik kot generatorji
na podlagi gramatik LL. Najbolj znan generator razpoznavalnikov je YACC (1975), ki je prav tako kot
Lex standardno orodje okolja UNIX.

Lex

Lex MH SURJUDPVNR RURGMH NL JD XSRUDEOMDPR SUL UHãHYDQMX QDORJ V SRGURþMD SURFHVLUDQMD LQ NRGLUDQMD
EHVHGLODSLVDQMDSUHYDMDOQLNRYLQQDPQRJLKGUXJLKSRGURþMLK/H[ VOLND XSRUDEOMDUHJXODUQHL]UD]H

za opis osnovnih leksikalnih simbolov in njim pridrXåHQH VHJPHQWH NRGH NL MLK LPHQXMHPR DNFLMH GD
lahko generira tabelo prehodov in program, ki interpretira to tabelo. Izhod iz Lex-a je program v
SURJUDPVNHPMH]LNX&NLVLPXOLUDNRQþQLDYWRPDW.DGDUMHNRQþQLDYWRPDWYNRQþQHPVWDQMXVHL]YHGH

programska koda, imenovana akcija.

izvorni funkcija lex.yy.c


Lex
program Lex yylex()

prevajalnik cc lex.yy.c -ll


C
stdin stdout
vhodni pregledovalnik terminalni
tekst simboli
a.out

Slika 2.15: Uporaba Lex-a

Pravila za sestavljanje regularnih izrazov v Lex-u so podana v tabeli 2.4. Izvorni program za Lex je
sestavljen iz treh delov: dHILQLFLM SUDYLO SUHKRGRY LQ XSRUDEQLãNLK IXQNFLM NL MLK PHG VHERM ORþLPR ]
znakoma %%.

definicije
%%

79
2. SINTAKSA IN SEMANTIKA
pravila prehodov
%%
uporabniške funkcije, zapisane v programskem jeziku C

ni. Nanje se sklicujemo


6 SRPRþMR GHILQLFLM LPHQXMHPR SRVDPH]QH UHJXODUQH L]UD]H V VLPEROLþQLPL LPH

tako, da njihova imena navedemo v zavitih oklepajih. Oblika definicij je naslednja:

ime regularni izraz

Pravila prehodov imajo naslednjo obliko:

regularni izraz akcija

Tabela 2.4: Regularni izrazi v Lex-u


Izraz Opis
x znak "x"
"x" "x", ki je lahko tudi poseben znak
\x "x", ki je lahko tudi poseben znak
[s] znak v nizu s
[x-y] ]QDNYREPRþMXRGx do y

[^s] znak, ki ni v nizu s


^x izraz xNLVHSULþQHQD]DþHWNXYUVWLFH
x$ izraz xNLVHNRQþDQDNRQFXYUVWLFH
x? izraz x, ki se lahko pojavi ali pa ne (opcija)
x* QLþDOLYHþSRQDYOMDQML]UD]Dx

x+ HQRDOLYHþSRQDYOMDQML]UD]Dx

x|y izraz x ali izraz y


(x) izraz x
x/y izraz x, ki mu sledi izraz y
{s} izraz, definiran z definicijo s
x{m,n} izraz x, ki se ponavlja od m-krat do n-krat
. vsak znak razen \n

Akcija je zaporedje stavkov, zapisanih v programskem jeziku C. Prepoznani niz znakov se shrani v
spremenljivko yytext[] QMLKRYD GROåLQD SD Y VSUHPHQOMLYNR yyleng 0RåQR MH GD YHþ UHJXODUQLK
izrazov opisuje isti osnovni leksikalni simbol. V tem primeru velja naslednje pravilo izbire: prvi regularni
izraz, ki prepozna najdaljši niz znakov na vhodu.

Primer 2.33:
Lex-ov izvorni program za preprost imperativni jezik.

80
2.4 GENERATORJI PREVAJALNIKOV
/* definicije */
/* DIGIT je cifra */
DIGIT [0-9]

/* ID je besedaNLVHSULþQHVþUNRNDWHUL
sledi polMXEQRãWHYLORþUNLQFLIHU 
ID [a-z][a-z0-9]*

%%

/* pravila prehodov */
/* cela številka je sestavljena iz cifer */
{DIGIT}+ printf(”celo število: %s\n”, yytext);

/* realna številka je sestavljena iz celega dela,


decimalne pike in lahko tudi iz ostanka */
{DIGIT}+”.”{DIGIT}* printf(”realno število: %s\n”, yytext);

/* rezervirane besede */
if⏐then⏐begin⏐end printf(”rezervirana beseda: %s\n”,yytext);

/* identifikator */
{ID} printf(”identifikator: %s\n”, yytext);

/* operatorji */
”+”⏐”-”⏐”*”⏐”/” printf(”operator: %s\n”, yytext);

 NRPHQWDUVHSULþQH]^LQNRQþD]`PHG

]DþHWQLPLQNRQþQLP]QDNRPVRSROMXEQL]QDNL

razen } in znaka za preskok v novo vrstico */


”{”[^}\n]*”}” ; /* preskok komentarja */

/* prazna mesta, tabulatorje in preskoke v novo


YUVWLFRSUHVNRþLPR 

[ \n\t] ;

/* vsi ostali znaki so nepravilni */


. printf(”Nepravilen znak: %s\n”, yytext);
%%

Lex generira program, ki iz standardne vhodne enote bere poljubno besedilo in ga primerja z regularnimi
izrazi, ki smo jih podali v izvornem programu Lex-a. Poljubno zaporedje znakov na vhodu se lahko ujema
] YHþ UHJXODUQLPL L]UD]L YHQGDU VH ER L]YHGOD WLVWD DNFLMD NL SULSDGD SUYHPX UHJXODUQHPX L]UD]X NL VH

ujema z najdaljšim zaporedjem vhodnih znakov. V gornjem primeru bo tako vhodno besedo begin
pregledovalnik UD]SR]QDO NRW UH]HUYLUDQR EHVHGR þHSUDY VH EHVHGD begin ujema tudi z regularnim

81
2. SINTAKSA IN SEMANTIKA
menjali vrstni red pravil za rezervirane
L]UD]RP NL RSLVXMH LGHQWLILNDWRU ýH EL Y L]YRUQHP SURJUDPX ]D

besede in identifikatorje, bi generirani pregledovalnik vse rezervirane besede razpoznal kot identifikatorje.
Zato moramo paziti na pravilni vrstni red pravil.

YACC

YACC ("Yet Another Compiler-Compiler") je generator razpoznavalnikov, ki generira razpoznavalnik


LALR(1). Vhodne specifikacije za YACC (slika 2.16) so, podobno kot pri Lex-u, sestavljene na naslednji
QDþLQ

deklaracije
%%
pravila
%%
uporabniške funkcije, zapisane v programskem jeziku C

izvorni funkcija
YACC yylex()
program YACC yyparse() y.tab.c

prevajalnik cc y.tab.c –ly -ll


C
stdin stdout
vhodni stavek
razpoznavalnik
stavek razpoznan ?
a.out

Slika 2.16: Uporaba YACC-a

V deklaracijah navedemo tiste terminalne simbole, ki jih vrne leksikalni analizator. V deklaracijah lahko
VLPERORPGRORþLPRSULRULWHWRDVRFLDWLYQRVWLQWLS (tabela 2.5). Prav tako lahko v deklaracijah navedemo
WXGL ]DþHWQL VLPERO ýH JD QH QDYHGHPR MH ]DþHWQL VLPERO leva stran prvega produkcijskega pravila.

3UDYLOD]DSLãHPRQDQDVOHGQMLQDþLQ

leva stran GHVQDVWUDQ^VHPDQWLþQHDNFLMH`

_GHVQDVWUDQ^VHPDQWLþQHDNFLMH`

| ...
_GHVQDVWUDQQ^VHPDQWLþQHDNFLMHQ`

9LGLPR GD ODKNR ]D YVDNR SURGXNFLMVNR SUDYLOR GRORþLPR WXGL DNFLMH NL VH L]YHGHMR NR VR SUDYLOD

razpoznana.

82
2.4 GENERATORJI PREVAJALNIKOV
V zadnjem delu specifikacij navedemo uporabniške funkcije, ki se samo prenesejo v izhodni program
y.tab.c. Na podlagi tako podanih specifikacij generira YACC tabele LALR(1) in funkcijo
yyparse(), ki za svoje delo potrebuje še leksikalni analizator yylex(). Funkcijo yylex() lahko
napišemo sami ali uporabimo leksikalni generator Lex.

Tabela 2.5: Deklaracije v YACC-u


KOMXþQDEHVHGD Pomen
%token deklaracija terminalnih simbolov
%start deklaracija]DþHWQHJDVLPEROD
%type deklaracija tipa simbola
%left leva asociativnost simbola
%right desna asociativnost simbola
%nonassoc simbol ni asociativen
%prec sprememba prioritete simbola
%union sprememba tipa spremenljivke yylval

V YACCMH PRåQR YJUDGLWL WXGLVHPDQWLþQHDNFLMH 1D<$&& ODKNR JOHGDPR V VWDOLãþDSUHYDMDOQLK VKHP


NLVRRSLVDQHYSRGSRJODYMX2URGMH<$&&SRGSLUDQDVWUXNWXULUDQQDþLQVDPRSULGREOMHQHDWULEXWH

6HPDQWLþQH DNFLMH VR Y <$&& ]DSLVDQH Y REOLNL NRGH SURJUDPVNHJD MH]LND & 6LPERO  VH QDQDãD QD

vrednost DWULEXWD NL MH SULGUXåHQ QHWHUPLQDOX QD OHYL VWUDQL SURGXNFLMH LQ L VH QDQDãD QD YUHGQRVW
DWULEXWD NL MH SULGUXåHQ L-temu simbolu (terminalnemu ali neterminalnemu) na desni strani produkcije.

9UHGQRVWDWULEXWDL]UDþXQDPRL] YUHGQRVWLDWULEXWRYL6HPDQWLþQHDNFLMHODKNRWXGLL]SXVWLPR9WHP

SULPHUXVHL]YHGHQDVOHGQMDVHPDQWLþQDDNFLMD^ `

Delovanje YACC-DVLRJOHMPRQDSUHSURVWHPSULPHUXUD]SR]QDYDQMDDULWPHWLþQLKL]UD]RY

Primer 2.34:
$ULWPHWLþQLL]UD]L zapisani v YACC-u

%{
#include <ctype.h>
%}
%token DIGIT

%%

line : expr ’\n’ {printf("%d\n", $1);}


;
expr : expr ’+’ term {$$ = $1 + $3;}
| term
;
term : term ’*’ factor {$$ = $1 * $3;}
| factor
;

83
2. SINTAKSA IN SEMANTIKA
factor : ’(’ expr ’)’ {$$ = $2;}
| DIGIT
;

%%

yylex() {
int c;
c = getchar();
if (isdigit(c)) {
/* v yylval shranimo leksikalno vrednost oz. lexem
osnovnega leksikalnega simbola */
yylval = c-’0’;
return DIGIT;
}
return c;
}

LISA

7XGL Y QDãHP ODERUDWRULMX ]D UDþXQDOQLãNH DUKLWHNWXUH LQ MH]LNH VPR VH ORWLOL L]JUDGQMH JHQHUDWRUMD

prevajalnikov/interpreterjev. Ime orodja LISA smo skovali iz angleškega imena Language Implementation
System Based On Attribute Grammars=RURGMHP/,6$ODKNRQDHQRVWDYHQLQXþLQNRYLWQDþLQDYWRPDWVNR
implementiramo programske jezike. Uporablja naslednje formalne metode: regularne izraze, BNF in
atributne gramatike 2URGMH /,6$ MH QDPHQMHQR QDþUWRYDOFHP MH]LND NHU RPRJRþD DYWRPDWVNR L]JUDGQMR
SUHYDMDOQLND DOL LQWHUSUHWHUMD LQ V WHP PRåQRVW WHVWLUDQMD MH]LND åH Y QMHJRYLK ]JRGQMLK ID]DK UD]YRMD

2URGMH/,6$XSRUDEOMDPRWXGLYL]REUDåHYDOQHQDPHQH1DWDQDþLQVSR]QDPRWHRUHWLþQDVSR]QDQMDWXGLY

SUDNVL LQ RPRJRþLPR XWUMHYDQMHLQ SRJODEOMDQMH ]QDQMD9 RURGMX /,6$ ODKNR SUHL]NXãDPR LQ SULPHUMDPR

UD]OLþQH OHNVLNDOQH LQ VLQWDNWLþQH DQDOL]DWRUMH NDNRU WXGL UD]OLþQH VWUDWHJLMH RYUHGQRWHQMD DWULEXWRY WHr

izberemo najustreznejše. Z implementacijo manjših realnih programskih jezikov raznih programskih


vzorcev pa posredno spoznavamo tudi koncepte, ki jih posamezni programski vzorecYNOMXþXMH
Prva verzija orodja LISAMHELODQDþUtovana za okolje Windows in je potrebovala za delovanje microsoftov
prevajalnik iz razvojnega okolja Visual C++ ver. 1.5. Zaradi nekaterih slabosti in vpeljave konceptov, ki bi
podprli modularno, inkrementalno in ponovno uporabnoQDþUWRYDQMHVPRSULVWRSLOLNUD]YRMXQRYHYHU]LMH
orodja. Z namenom, da lahko pri opisu nekega programskega jezika uporabimo delne specifikacije
drugega jezika ter jezik postopno dograjujejmo, smo v orodje vgradili šablone iQ YHþNUDWQR GHGRYDQMH
atributnih gramatik 3UL ãWXGLMX VSHFLILNDFLMUD]OLþQLK SURJUDPVNLK MH]LNRY ]DVOHGLPR VNXSQH Y]RUFH NL VH
pogosto uporabljajo in so neodvisni od strukture produkcij. Za opis takšnih vzorcev uporabimo šablone.

Primer 2.35:
1DVOHGQMLVHPDQWLþQLIXQNFLMLRGUDåDWDGRORþHQRSRGREQRVW

84
2.4 GENERATORJI PREVAJALNIKOV
E ::= E + T { E[0].value = E[1].value + T.value; }
T ::= T * F { T[0].value = T[1].value * F.value; }

Iz njiju lahko razberemo vzorec, ki ga zapišemo v obliki šablone:


template <attributes level0_val, level1_val, nextlevel_val, function op>
compute left_assoc_op {
level0_val=op(level1_val,nextlevel_val);
}

6HPDQWLþQLIXQNFLMLODKNRVHGDM]DSLãHPRQDQDVOHGQMLQDþLQ

E ::= E + T { left_assoc_op<E[0].value, E[1].value, T.value, plus> }


T ::= T * F { left_assoc_op<T[0].value, T[1].value, F.value, mult> }

Vzorec iz primera 2.35 ponazarja osnovno idejo šablon v atributnih gramatikah. Splošnejše šablone
PRUDMR ELWL QHRGYLVQH WXGL RG ãWHYLOD SRMDYLWHY DWULEXWRY NL VH SRMDYOMDMR Y GRORþHQL SURGXNFLML =DWR Y

ãDEORQH XYHGHPR WXGL VH]QDPH VSUHPHQOMLYLK GROåLQ 3ULPHUL QDMRELþDMQHMãLK Y]RUFHY NL se pojavljajo v
VHPDQWLþQLKVSHFLILNDFLMDKVRGLVWULEXFLMDYUHGQRVWL , širjenje vrednosti, širjenje in vrnitev vrednosti.

Vzorec distribucija vrednosti (slika 2.17) ima naslednjo splošno obliko:

Y ::= X1 X2 ... XN
{ X1.in = Y.in; X2.in = Y.in; ...; XN.in = Y.in; }

Y.in Y

X1.in X1 X2.in X2 … XN.in XN

Slika 2.17: Vzorec distribucija vrednosti

Ta vzorec zapišemo z naslednjo šablono:

template <attributes Y_in, X_in*>


compute value_distribution {
{ X_in* = Y_in; }
}

85
2. SINTAKSA IN SEMANTIKA
Formalni argument X_in* v šabloni value_distribution predstavlja seznam s spremenljivo
GROåLQR ]D LPHQRP DUJXPHQWD VOHGL  =D YVDN DUJXPHQW Y VSUHPHQOMLYHP VH]QDPX VH SUL XVWYDUMDQMX

šablone ]D GHO VHPDQWLþQLK IXQNFLM NL MH REGDQ ] ]DYLWLPD RNOHSDMHPD XVWYDULMR XVWUH]QH VHPDQWLþQH
funkcije. Tako naslednja šablona
BLOCK ::= DEC STMTS
{value_distribution<BLOCK.static_level, [DEC.static_level, STMTS.static_level]>}

JHQHULUDQDVOHGQMHVHPDQWLþQHIXQNFLMH .
DEC.static_level = BLOCK.static_level;
STMTS.static_level = BLOCK.static_level;

1DGVH]QDPLVSUHPHQOMLYHGROåLQHGHILQLUDPRQDVOHGQMHIXQNFLMH

• first() - vrne prvi argument seznamDVSUHPHQOMLYHGROåLQH


• last() - vrne zadnji argument seznamDVSUHPHQOMLYHGROåLQH
• succ() - vrne naslednji argument iz seznamDVSUHPHQOMLYHGROåLQHLQ
• pred() - vrne predhodni argument iz seznamDVSUHPHQOMLYHGROåLQH

Naslednjik zadnjega argumenta in predhodnik prvega argumenta ne obstajata. Uporabo teh funkcij
prikazuje naslednji vzorec. Vzorec širjenje vrednosti (slika 2.18) ima naslednjo splošno obliko:
Y ::= X1 X2 ... XN
{ X1.in = Y.in; X2.in = X1.out; ...; XN.in = XN-1.out; }

Y.in Y

X1.in X1 X1.out X2.in X2 X2.out … XN.in XN

Slika 2.18: Vzorec širjenje vrednosti

Ta vzorec zapišemo z naslednjo šablono:

template <attributes Y_in, X_in*, X_out*>


compute propagate {
first(X_in*) = Y_in;
{ X_in* = pred(X_out*); }
}

86
2.4 GENERATORJI PREVAJALNIKOV
Šablone lahko tudi gnezdimo, kot prikazuje naslednji vzorec. Vzorec širjenje in vrnitev vrednosti (slika
2.19) ima naslednjo splošno obliko:

Y ::= X1 X2 ... XN
{ X1.in = Y.in; X2.in = X1.out; ...; XN.in = XN-1.out; Y.out = XN.out; }

Y.in Y Y.out

X1.in X1X1.out X2.in X2 X2.out … XN.in XN XN.out

Slika 2.19: Vzorec širjenje in vrnitev vrednosti

Ta vzorec zapišemo z naslednjo šablono:


template <attributes Y_in, Y_out, X_in*, X_out*>
compute bucket_brigade_left {
propagate<Y_in, X_in*, X_out*>
Y_out = last(X_out*);
}

(QDL]PHGVODERVWLDWULEXWQLKJUDPDWLNMHVODEãDEHUOMLYRVWNHUVRELVWYHQLVHPDQWLþQLL]UDþXQLSRPHãDQLV

preprostimi prenosi vrednosti'DWDNãQHVSHFLILNDFLMHUD]XPHPRMHWUHEDRELþDMQRYHOLNRþDVD

Primer 2.36.
DECLS ::= DECL ”;” DECLS
{ DECL.is_global = DECLS[0].is_global;
DECL.inEnv = DECLS[0].inEnv;
DECLS[1].is_global = DECLS[0].is_global;
DECLS[0].outEnv = DECLS[1].outEnv;
DECLS[1].inEnv = DECL.outEnv; }

Specifikacije s šablonami so velikoEROMEHUOMLYHLQODåMHUD]XPOMLYH2SD]LPRGDVRJRUQMHVSHFLILNDFLMHY


bistvu sestavljene iz vzorca distribucija vrednostiLQY]RUFDãLUMHQMHLQYUDþDQMHYUHGQRVWL VOLND 

bucket_brigade_left<DECLS[0].inEnv, DECLS[0].outEnv,
[DECL.inEnv, DECLS[1].inEnv],
[DECL.outEnv, DECLS[1].outEnv]>
value_distribution<DECLS[0].is_global, [DECL.is_global, DECLS[1].is_global]>

87
2. SINTAKSA IN SEMANTIKA

inEnv is_global DECLS outEnv

inEnv is_global DECLoutEnv ; inEnv is_global DECLS outEnv

Slika 2.20: Kombinacija dveh vzorcev

Prednosti šablon so:


• šablone so abstrakcije na višjem nivoju kot prireditveni stavki,
• specifikacije s šablonami so berljivejše in
• šablone so neodvisne od produkcij, zato so ponovno uporabne.

Dedovanje gramatik je strukturna organizacija gramatik, kjer podeduje gramatika produkcijska in


produkcijskih in
VHPDQWLþQD SUDYLOD RG QDGJUDPDWLNH .UHLUDQMH SRGJUDPDWLNH SRPHQL UHGHILQLUDQMH

VHPDQWLþQLK SUDYLO SRGHGRYDQH QDGJUDPDWLNH LQ YSHOMDYR QRYLK UD]ãLUMHQLK SUDYLO 9HþNUDWQR GHGRYDQMH

oPRJRþD XSRUDEQLNX SRVWRSQR GRJUDMHYDQMH MH]LND LQ XSRUDER VSHFLILNDFLM åH GHILQLUDQLK MH]LNRY =D
formalen opis jezika smo uporabili poseben specifikacijski jezik NL ]GUXåXMH OHNVLNDOQH VLQWDNWLþQH LQ
VHPDQWLþQHVSHFLILNDFLMHWHURPRJRþDXSorabniku uporabo šablonLQYHþNUDWQHJDGHGRYDQMD

language L1 extends L2, ..., LN {


lexicon {
[[P] overrides | [P] extends] R regularni izraz
...
}
attributes type A1, ..., AM ;
rule [[Y] extends | [Y] overrides] Z {
X ::= X11 X12 ... X1p compute {
VHPDQWLþQHIXQNFLMH }

...
|
Xr1 Xr2 ... Xrt compute {
VHPDQWLþQHIXQNFLMH }

;
}
...
method [[N] overrides | [N] extends] M {
RSHUDFLMHQDGVHPDQWLþQLPLGRPHQDPL

}
...
}

88
2.4 GENERATORJI PREVAJALNIKOV
9 REMHNWQR XVPHUMHQLK SURJUDPVNLK MH]LNLK VR LQVWDQþQH VSUHPHQOMLYNH LQ PHWRGH WLVWH ODVWQRVWL NL MLK

ga dedovanja v atributnih gramatikah so


SRGUD]UHGL SRGHGXMHMR LQ UHGHILQLUDMR 9 SULPHUX YHþNUDWQH

lastnosti, ki jih podspecifikacije podedujejo in redefinirajo, naslednje: regularne definicije, definicije


DWULEXWRY SRVSORãHQD SUDYLOD NL YVHEXMHMR WDNR SURGXNFLMH NRW VHPDQWLþQD SUDYLOD SULGUXåHQD WHP

produkcijamLQRSHUDFLMHQDGVHPDQWLþQLPLGRPHQDPL

3UHGQRVWLXSRUDEHYHþNUDWQHJDGHGRYDQMDYDWULEXWQLKJUDPDWLNDKVR

• razširljivost specifikacij (pri opisu novega jezika zapišemo samo spremembe) in


• ponovna uporabnost specifikacij.

Primer 2.37:
Jezik SULUHGLWYHQLK VWDYNRY NMHU DULWPHWLþQL L]UD]L QLPDMR VWUDQVNLK XþLQNRY ]DSLãHPR Y RURGMX /,6$ na
QDVOHGQMLQDþLQ

language Expr {
lexicon {
Number [0-9]+
Identifier [a-z]+
Operator \+ | :=
Separator \[ | \]
ignore [\0x09\0x0A\0x0D]+
}

attributes Hashtable *.inEnv, *.outEnv;


int *.val;

rule Start {
START ::= STMTS compute
{
STMTS.inEnv = new Hashtable();
START.outEnv = STMTS.outEnv;
};
}
rule Statements {
STMTS ::= STMT STMTS compute
{
bucket_brigade_left<STMTS[0].inEnv, STMTS[0].outEnv,
[STMT.inEnv, STMTS[1].inEnv],
[STMT.outEnv, STMTS[1].outEnv]>
}
| compute
{
STMTS.outEnv = STMTS.inEnv;
};
}

89
2. SINTAKSA IN SEMANTIKA
rule Statement {
STMT ::= #Identifier \:= EXPR compute
{
EXPR.inEnv = STMT.inEnv;
STMT.outEnv =
put(STMT.inEnv, #Identifier.value(), EXPR.val);
};
}
rule Expression1 {
EXPR ::= EXPR + TERM compute
{
value_distribution<EXPR[0].inEnv,
[TERM.inEnv, EXPR[1].inEnv]>
EXPR[0].val = EXPR[1].val + TERM.val;
};
}
rule Expression2 {
EXPR ::= TERM compute
{
value_distribution<EXPR.inEnv,[TERM.inEnv]>
EXPR.val = TERM.val;
};
}
rule Term1 {
TERM ::= #Number compute
{
TERM.val = Integer.valueOf(#Number.value()).intValue();
};
}
rule Term2 {
TERM ::= #Identifier compute
{
TERM.val =
((Integer)TERM.inEnv.get(#Identifier.value())).intValue();
};
}
rule Term3 {
TERM ::= [ #Identifier \:= EXPR ] compute
{
TERM.val =
((Integer)TERM.inEnv.get(#Identifier.value())).intValue();
value_distribution< TERM[0].inEnv, [EXPR[0].inEnv]>
};
}

method Environment {
import java.util.*;

90
2.4 GENERATORJI PREVAJALNIKOV
public Hashtable put(Hashtable env, String name, int val)
{
env = (Hashtable)env.clone();
env.put(name, new Integer(val));
return env;
}
}
}

Po izvršitvi naslednjega programa:

a:=5
b:=a+1+[a:=8]+a

ima spremenljivka a vrednost 5 in spremenljivka b vrednost 16. V kolikoU åHOLPR SURJUDPVNL MH]LN, kjer
zapišemo v prejšnje specifikacije samo spremembe. Opazimo,
LPDMRDULWPHWLþQLL]UD]LWXGLVWUDQVNLXþLQHN

da namesto vzorca distribucija, kjer atribut inEnv pošljemo v poddrevesa, sedaj potrebujemo vzorec
širjenje in vrnitev.

language ExprSideEffect extends Expr


{
rule extends Start {
compute {}
} // potrebno zaradi startne produkcije
rule extends Statement {
compute
{
STMT.outEnv = put(EXPR.outEnv, #Identifier.value(),
EXPR.val);
}
}
rule extends Expression1 {
compute
{
bucket_brigade_left<EXPR[0].inEnv, EXPR[0].outEnv,
[EXPR[1].inEnv, TERM.inEnv],
[EXPR[1].outEnv, TERM.outEnv]>
}
}
rule extends Expression2 {
compute
{
bucket_brigade_left<EXPR[0].inEnv, EXPR[0].outEnv,
[TERM.inEnv], [TERM.outEnv]>
}
}

91
2. SINTAKSA IN SEMANTIKA
rule extends Term1 {
compute
{
TERM.outEnv = TERM.inEnv;
}
}
rule extends Term2 {
compute
{
TERM.outEnv = TERM.inEnv;
}
}
rule extends Term3 {
compute
{
TERM.val = EXPR.val;
bucket_brigade_left<TERM.inEnv, TERM.outEnv,
[EXPR.inEnv],
[put(EXPR.outEnv,#Identifier.value(),EXPR.val)]>
};
}
}

Po izvršitvi naslednjega programa:

a:=5
b:=a+1+[a:=8]+a

ima spremenljivka a vrednost 8 in spremenljivka b vrednost 22.

Izboljšave nove verzije orodja LISA:


• Integrirano razvojno okolje ,'(  NL RPRJRþD VSHFLILNDFLMR MH]LND JHQHULUDQMH SUHYDMDOQLND
prevajanje prevajalnika in izvajanje programov, zapisanih v novo definiranem jeziku (slika 2.21).
• Specifikacijski jezik podpira uporabo šablonLQYHþNUDWQHJDGHGRYDQMD
• 2PRJRþD JHQHULUDQMH SRVDPH]QLK NRUDNRY OHNVLNDOQL DQDOL]DWRU VLQWDNWLþQL DQDOL]DWRU,
prevajalnik/interpreter.
• *UDILþQL SULND] SRVDPH]QLK VWUXNWXU NRQþQL DYWRPDW VOLND   VLQWDNWLþQR GUHYR (slika 2.23), graf
odvisnosti VOLND VHPDQWLþQRGUHYR (slika 2.25).
• Animacija delovanja posameznih korakov (leksikalni analizator VLQWDNWLþQL DQDOL]DWRU,
prevajalnik/interpreter).

Orodje LISA prispeva z vgrajeniP JUDILþQLP SULND]RP UD]OLþQLK VWUXNWXU LQ DQLPDFLMR GHORYDQMD
posameznih faz prevajalnika/interpreterja k razumevanju kompleksnih algoritmov, ki se uporabljajo v

92
2.4 GENERATORJI PREVAJALNIKOV
SUHYDMDOQLãNL WHKQLNL =DQLPLY MH JUDILþQL SULND] NRQþQHJD DYWRPDWD %1) -a, sintaNWLþQHJD GUHYHVD,
DQLPDFLMD OHNVLNDOQH DQDOL]H VLQWDNWLþQH DQDOL]H WHU SULND] GHORYDQMD UD]OLþQLK VWUDWHJLM RYUHGQRWHQMD

atributov. Orodje LISA je odmevno tudi v svetovnem merilu, saj jo uporabljajo na tujih univerzah in
raziskovalnih inštitutih.

Slika 2.21: Integrirano razvojno okolje orodja LISA

93
2. SINTAKSA IN SEMANTIKA

6OLND3UHGVWDYLWHYNRQþQHJDDYWRPDWD

6OLND3UHGVWDYLWHYVLQWDNWLþQHJDGUHYHVD

94
2.4 GENERATORJI PREVAJALNIKOV

Slika 2.24: Predstavitev grafa odvisnosti

Slika 23UHGVWDYLWHYVHPDQWLþQHJDGUHYHVD

95
2. SINTAKSA IN SEMANTIKA

ABSTRAKTNA SINTAKSA

1DþUWRYDQMH VLQWDNVH MH SRVWRSHN NL PRUD ELWL RSUDYOMHQ V SUHFHMãQR PHUR SD]OMLYRVWL 3D]LWL PRUDPR QD

prioriteto in asociativnost operatorjev, GYRXPQRVW JUDPDWLNH OHYR UHNXU]LMR LWG9 ]DþHWQLK ID]DK UD]YRMD
programskega jezika je veliko pomembnejša semantikaNRWRPHQMHQHVLQWDNWLþQHSRGUREQRVWL=DWRORþLPR
abstraktno in konkretno sintakso. Abstraktna sintaksa ("abstract syntax") je veliko preprostejša od
NRQNUHWQH VDM ] QMR SRGDMDPR OH GRORþHQH UHODFLMH PHG QHWHUPLQDOQLPL VLPEROL VOHGQML GRORþDMR

VLQWDNWLþQH NDWHJRULMH DOL IUD]H  QH SD WXGL SRGUREQRVWL NRW VR SULRULWHWD LQ DVRFLDWLYQRVW LWG 3UL

formalnem opisu semantike se zaradi zgoraj naštetih razlogov opiramo predvsem na abstraktno sintakso,
ki je tudi bistveno krajša in manj zahtevna kot konkretna sintaksa. Formalne metode za opis semantike
programskih jezikov, kot sta operacijska semantika in denotacijska semantika (poglavje 5), uporabljajo
abstraktno sintakso. Tudi atributne gramatike lahko definiramo nad abstraktno sintakso.
Zapis, s katerimi opisujemo abstraktno sintakso, temelji na BNF1DMSUHMQDYHGHPRVLQWDNWLþQHNDWHJRULMH
LQ SRGDPR PHWDVSUHPHQOMLYNR NL SUHGVWDYOMD HOHPHQWH Y GRORþHQL VLQWDNWLþQL NDWHJRULML

0HWDVSUHPHQOMLYNH ODKNR WXGL RãWHYLOþLPR WDNR Y QDVOHGQMHP SULPHUX PHWDVSUHPHQOMLYNH a, a1 in a2


R]QDþXMHMRDULWPHWLþQL izraz.

Primer 2.38:
Abstraktna sintaksa jezika WHILE:

n ∈ Num VLQWDNWLþQDNDWHJRULMD številk


x ∈ Var VLQWDNWLþQDNDWHJRULMD spremenljivk
a ∈ Aexp VLQWDNWLþQDNDWHJRULMDDULWPHWLþQLKL]UD]RY

b ∈ Bexp VLQWDNWLþQDNDWHJRULMDORJLþQLKL]UD]RY

S ∈ Stm VLQWDNWLþQDNDWHJRULMD stavkov jezika WHILE

a ::= n
| x
| a1 + a2
| a1 * a2
| a1 - a2

b ::= true
| false
| a1 = a2
| a1 <= a2
| not b
| b1 and b2

96
2.5 ABSTRAKTNA SINTAKSA
S ::= x := a
| skip
| S1; S2
| if b then S1 else S2
| while b do S

$ULWPHWLþQL L]UD] VHVWDYOMDMR ãWHYLONH VSUHPHQOMLYNH LQ DULWPHWLþQL L]UD]L NL MLK SRYH]XMHMR RSHUDWRUML

VHãWHYDQMD PQRåHQMD LQ RGãWHYDQMD /RJLþQL L]UD] VHVWDYOMDMR ORJLþQL NRQVWDQWL SULPHUMDYL GYHK

DULWPHWLþQLK L]UD]RY QHJDFLMD ORJLþQHJD L]UD]D LQ NRQMXQNFLMD GYHK ORJLþQLK L]UD]RY 0HG VWDYNH MH]LND

WHILE sodijo: prireditveni stavek, stavek skip, zaporedje stavkov, stavek if in stavek while.

97

You might also like