Professional Documents
Culture Documents
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
(semantikaSURJUDPVNLKVWDYNRYQDWDQþ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
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:
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
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 .
stavek
28
1.2 KRATKA ZGODOVINA PROGRAMSKIH JEZIKOV
Primer 2.5:
Struktura stavka iz primera 2.3.
ý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
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
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:
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
Primer 2.8:
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
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
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/ULQ/VSRWHPMH
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|ER]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
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:
Nekateri regularni izrazi se pojavljajo zelo pogosto, zato zanje vpeljemo naslednje zapise:
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þLQWDEHOD
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
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
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
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
integer → [0-9]+
operator → + | *
separator → ( | )
in preskok praznih mest. Funkcijo prehodov leksikalnega analizatorja implementiramo z naslednjo tabelo
prehodov:
35
2. SINTAKSA IN SEMANTIKA
// 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(""){
}
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
automata[0][’+’] = automata[0][’*’] = 2;
þHVPRYVWDQMXREDOLJUHPRYVWDQMH
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
DOLMHVWDQMHNRQþQRVWDQMH
YUQLNRQþQRVWDQMH
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
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
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
*
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 α.
α ⇒ α1 ⇒ α2 ⇒ ... ⇒ αn ⇒ β
α ⇒* β ⇔ (α ⇒+ β ∨ α = β )
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
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
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:
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.
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
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]DMRRSHUDWRUMXLWGXSRUDEOMDPR]DRSLVVLQWDNVHSURJUDPVNLKMH]LNRYL]NOMXþQR]DGQMDGYDUD]UHGD
1H REVWDMDMR QDPUHþ XþLQNRYLWL DOJoritmi za razpoznavanje kontekstno odvisnih jezikov. Zgornji problem
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
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
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).
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 →
45
2. SINTAKSA IN SEMANTIKA
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
Primer 2.21:
Primer 2.15 v EBNF zapisu:
E ::= [E +] T
T ::= [T *] F
F ::= (E) | a
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
α1
α2
...
αn
α1 α2 ... αn
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 )
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
48
2.2 6,17$.7,ý1$ ANALIZA
,]JUDGQMDLQSULPHUMDYDUD]OLþQLKYUVWUD]SR]QDYDOQLNRYVRGLQDSRGURþMHSUHYDMDOQLNRY=DWRVLRJOHMPROH
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),56789 ∪ 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
ý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 | ε
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.
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:
ý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.
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
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
FIRST(P) = {a, b, c, d}
FIRST(A) = {a, ε}
FIRST(B) = {b, ε}
FOLLOW(P) = ∅
FOLLOW(A) = {c}
FOLLOW(B) = {d}
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:
zamenjamo z:
Produkcijo oblike
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
1.
A∈N A call A;
2.
54
2.2 6,17$.7,ý1$ ANALIZA
3.
... ...
else error
4.
α1 α2 ... αn T(α1);T(α2);...;T(αn)
Primer 2.26:
Po zgornjih pravilih zapišimo rekurzivni navzdolnji razpoznavalnik ]D DULWPHWLþQH L]UD]H SULPHU
kjer je simbolDVLQRQLP]DãWHYLONR1DMSUHML]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
T EE
F TT T EE
F TT
F TT
a ε + a * a ε ε
6ODERVW UHNXU]LYQLK QDY]GROQMLK UD]SR]QDYDOQLNRY MH VODEãH RGNULYDQMH LQ RGSUDYOMDQMH QDSDN 2ELþDMQR
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
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
Atributna gramatika
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
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
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]DSLVXPDWHPDWLþQL]DSLV, zapis v programskem jeziku C itd).
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
Produkcije 6HPDQWLþQHIXQNFLMH
=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
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
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
0 D cifra=1
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
normalizirana.
2EVWDMD ãH YPHVQD REOLND VHPDQWLþQLK IXQNFLM PHG SRSROQRPD VSORãQR LQ QRUPDOL]LUDQR DWULEXWQR
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(X09WDEHOLVRRSLVDQHUD]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
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 .
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
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.
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ãþHYR]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
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
number lexVred="4"
6OLND6HPDQWLþQRGUHYR]DDULWPHWLþQLL]UD] 4*3–2+1
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
L]UDþXQDPRãHSRGHGRYDQHDWULEXWHYR]OLãþD=DOJRULWPRPRYUHGQRWLPRDWULEXWQRJUDPDWLNRYUVWH/
67
2. SINTAKSA IN SEMANTIKA
Algoritem 2.3:
procedureRYUHGQRWLBYR]OLãþHYR]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
-, /, %.
68
2.3 6(0$17,ý1$ ANALIZA
// 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);
}
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"
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
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:
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
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
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
1 D cifra
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
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
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:
do
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
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
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.
B vhoVred
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
Primer 2.32:
,]UDþXQDMPRYUVWQLUHGRYUHGQRWHQMD]DQDVOHGQM o atributno gramatiko:
76
2.3 6(0$17,ý1$ ANALIZA
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.
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
6HGDMSULNDåLPRãHYKRGQRL]KRGQHJUDIHLQUD]ãLUMHQHJUDIHRGYLVQRVWL2EHPQRåLFLJUDIRYVWDSULND]DQL
77
2. SINTAKSA IN SEMANTIKA
IOR IO A IOB
R r A z B x y
A c B a b
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
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:
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[VOLNDXSRUDEOMDUHJXODUQHL]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
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
x+ HQRDOLYHþSRQDYOMDQML]UD]Dx
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);
/* 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
[ \n\t] ;
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
deklaracije
%%
pravila
%%
uporabniške funkcije, zapisane v programskem jeziku C
izvorni funkcija
YACC yylex()
program YACC yyparse() y.tab.c
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
_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.
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
%%
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
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; }
6HPDQWLþQLIXQNFLMLODKNRVHGDM]DSLãHPRQDQDVOHGQMLQDþLQ
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.
Y ::= X1 X2 ... XN
{ X1.in = Y.in; X2.in = Y.in; ...; XN.in = Y.in; }
Y.in Y
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
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
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
(QDL]PHGVODERVWLDWULEXWQLKJUDPDWLNMHVODEãDEHUOMLYRVWNHUVRELVWYHQLVHPDQWLþQLL]UDþXQLSRPHãDQLV
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; }
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
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
...
|
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
produkcijamLQRSHUDFLMHQDGVHPDQWLþQLPLGRPHQDPL
3UHGQRVWLXSRUDEHYHþNUDWQHJDGHGRYDQMDYDWULEXWQLKJUDPDWLNDKVR
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]+
}
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;
}
}
}
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.
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)]>
};
}
}
a:=5
b:=a+1+[a:=8]+a
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.
93
2. SINTAKSA IN SEMANTIKA
6OLND3UHGVWDYLWHYNRQþQHJDDYWRPDWD
6OLND3UHGVWDYLWHYVLQWDNWLþQHJDGUHYHVD
94
2.4 GENERATORJI PREVAJALNIKOV
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
Primer 2.38:
Abstraktna sintaksa jezika WHILE:
b ∈ Bexp VLQWDNWLþQDNDWHJRULMDORJLþQLKL]UD]RY
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