You are on page 1of 34

Sémantika programovacı́ch jazykov

Valerie Novitzká
valerie.novitzka@tuke.sk

Katedra počı́tačov a informatiky FEI TU v Košiciach

LS 2010/2011
1. prednáška

Sémantika programovacı́ch jazykov 1/34


Základné pojmy
Programovacie jazyky obsahujú rôzne druhy konštrukciı́, napr. výrazy,
deklarácie, prı́kazy, atd’.

Naprı́klad:
• čisté funkcionálne jazyky majú deklarácie, typy, vzory, zhody, . . .
• imperatı́vne jazyky majú deklarácie, typy, bloky, formálne parametre,
prı́kazy, . . .

Tieto rozdiely nie sú len na úrovni syntaxe, ale odrážajú podstatné rozdiely
vo význame rôznych druhov konštrukciı́.

Každá konštrukcia v sebe môže zahŕňat’:


• tok riadenia
• tok informáciı́

Sémantika programovacı́ch jazykov 2/34


Základné pojmy
Vykonávanie programu pozostáva z výpočtu na určitom počı́tači.

Výpočet na počı́tači je kombinácia podvýpočtov konštrukciı́ v programe.

Riadenie:
• vtečie do konštrukcie ked’ sa začne jej podvýpočet
• vytečie, ked’ sa tento podvýpočet skončı́.

Spracovanie informáciı́ počas výpočtu odpovedá toku informáciı́ medzi


konštrukciami programu.

Konštrukcie sa môžu lı́šit’ najmä v tom


• aký tok riadenia a
• aký tok informáciı́
spôsobia z- a do- svojich podkonštrukciı́.

Sémantika programovacı́ch jazykov 3/34


Tok riadenia
Medzi základné druhy toku riadenia patria:
• zoradenie do postupnosti (sequencing)- riadenia vteká postupne do
podkonštrukciı́ zhora nadol (zl’ava doprava), pokial’ každý podvýpočet terminuje
normálne;
• prekladanie (interleaving)- riadenie sa presúva striedavo vpred a nazad medzi
dvoma alebo viacerými podkonštrukciami;
• výber medzi alternatı́vami (choice) - medzi niekol’kými alternatı́vami, riadenie
vtečie len do jednej. Ak vykonanie zvolenej alternatı́vy zlyhá, môže sa vrátit’
(backtracking) a skúsit’ inú alternatı́vu;
• signalizovanie výnimočnej situácie (exception raising) - prerušı́ normálny tok
riadenia, pokračuje uzatvárajúcou konštrukciou, ktorá ju spracuje. Potom môže
tok riadenia pokračovat’ nasledujúcou podkonštrukciou;
• iterácia (iteration) - tok riadenia opakovane vteká do tej istej podkonštrukcie;
• volanie procedurálnej abstrakcie (procedural abstraction)- tok riadenia vtečie
do tejto konštrukcie, ktorá sa nachádza na inom mieste programu a po ukončenı́
výpočtu sa pokračuje od bodu aktivácie;
• súbežné procesy (concurrent processes)- delia tok riadenia do separátnych
vlákien, ktoré môžu potrebovat’ synchronizáciu.

Sémantika programovacı́ch jazykov 4/34


Tok informáciı́

Medzi základné druhy toku informáciı́ patria:


• výpočet hodnôt - obvykle hodnoty počı́tajú výrazy, ale napr. deklarácie počı́tajú
prostredie, prı́kazy prázdne (dummy) hodnoty, . . . ;
• použitie vypočı́taných hodnôt - informácie vytekajú z konštrukciı́ a vtekajú do
iných. Výpočet hodnoty vždy zahrňuje termináciu. Signalizovanie výnimočnej
situácie možno chápat’ ako kombináciu toku riadenia (na iné miesto programu) a
výpočet hodnoty, ktorá identifikuje prı́slušnú výnimočnú situáciu;
• účinok na pamät’ - je stabilný, môže sa alokovat’ nová bunka pamäti, alebo sa
do bunky uložı́ nová hodnota, alebo sa bunka dealokuje;
• viditel’nost’ (scope) - väzby vypočı́tané jednou podkonštrukciou môžu vtiect’ do
inej podkonštrukcie, ktorá je v oblasti viditel’nosti (scope) tejto väzby;
• odovzdávanie správ (message passing)- konštrukcia samotná zı́ska
informáciu, že jej kontext akceptuje správu a kontext zı́ska informáciu uloženú v
samotnej správe.

Sémantika programovacı́ch jazykov 5/34


Paradigmy programovania
Programovacie jazyky možno klasifikovat’ podl’a toho, ktorú paradigmu
programovania podporujú najviac.

Niektoré jazyky určené pre jednu paradigmu programovania sa (po určitom


úsilı́) dajú použit’ aj pre iné paradigmy.

Rozoznávame nasledujúce paradigmy programovania:


• imperatı́vne programovanie;
• funkcionálne programovanie;
• súbežné programovanie;
• objektovo orientované programovanie;
• logické programovanie.

Sémantika programovacı́ch jazykov 6/34


Imperatı́vne programovanie - kladie dôraz na zoradenie do postupnosti,
iteráciu, procedurálnu abstrakciu a jej aktiváciu (volanie) a účinok na pamät’.

Charakteristiky imperatı́vneho programovania:


• početné zmeny hodnôt uložených v pamäti;
• samotné výpočty sú jednoduché;
• tok riadenia je vyjadrený postupnost’ou prı́kazov, podmienenými
prı́kazmi a prı́kazmi cyklu.

Jazyky podporujúce túto paradigmu sú napr.: C, Pascal, Algol60 a desiatky


iných.

Sémantika programovacı́ch jazykov 7/34


Funkcionálne programovanie - kladie dôraz na výpočet hodnôt, oblasti
viditel’nosti väzieb, procedurálnu abstrakciu a jej aktiváciu.

Charakteristiky funkcionálneho programovania:


• programy obsahujú rozsiahle a komplexné výpočty hodnôt;
• programy obsahujú málo, alebo žiadne priradenia;
• tok riadenia je vyjadrený aktiváciou funkciı́, funkcie počı́tajú hodnoty z
hodnôt argumentov a odovzdávajú ich iným funkciám ako argumenty;
• oblast’ viditel’nosti väzieb v deklaráciách je často rekurzı́vna.

Jazyky podporujúce túto paradigmu sú napr.: Lisp, Scheme, Miranda, Gofer,
Standard ML, CAML, Haskell a mnoho iných.

Sémantika programovacı́ch jazykov 8/34


Súbežné programovanie - kladie dôraz na súbežné procesyy, výber medzi
alternatı́vami a odovzdávanie správ.

Charakteristiky súbežného programovania:


• každý proces spravidla vykonáva malé množstvo výpočtov medzi
prijı́manı́m a odosielanı́m správ;
• výber medzi alternatı́vami sa robı́ podl’a druhu prijı́manej správy, alebo
na základe synchronizácie procesov.

Jazyky podporujúce túto paradigmu sú napr.: PL/1, Algol68, Modula, Ada,
Occam, Concurrent ML a iné.

Sémantika programovacı́ch jazykov 9/34


Objektovo orientované programovanie - sa často chápe ako imperatı́vne
programovanie s pravidlami pre oblasti viditel’nosti väzieb.

Charakteristiky objektovo orientovaného programovania:


• použı́va väzby medzi objektami a metódami;
• objekty sú fragmenty pamäte vytvorené bud’ inštanciovanı́m tried, alebo
klonovanı́m existujúcich objektov;
• metódy sú procedurálne abstrakcie, ktoré majú často priamy účinok na
objekty, ku ktorým sú viazané.

Jazyky podporujúce túto paradigmu sú napr.: Simula67, SmallTalk, Beta,


Self, C++, Java, OCaml a iné.

Sémantika programovacı́ch jazykov 10/34


Logické programovanie - kladie dôraz na výber medzi alternatı́vami a na
procedurálnu abstrakciu.

Charakteristiky logického programovania:


• táto paradigma programovania sa úplne odlišuje od predošlých;
• program pozostáva z množiny alternatı́vnych procedurálnych abstrakciı́
pre každý identifikátor;
• výber medzi alternatı́vami sa robı́ pomocou unifikácie vzorov (pattern
unification) medzi parametrami abstrakciı́ a argumentami aktiváciı́. Táto
unifikácia viaže identifikátory k termom. Táto väzba zaniká v prı́pade,
ked’ zlyhanie zaprı́činı́ návrat spät’ (backtracking).

Základným logickým programovacı́m jazykom je Prolog.

Sémantika programovacı́ch jazykov 11/34


Formálny popis programovacieho
jazyka

Popis ( alebo definı́cia) programovacieho jazyka sa nazýva formálna, ak


je zapı́saná v pojmoch a symboloch s presným významom.

Referenčné manuály a prı́ručky programovacı́ch jazykov obsahujú často


formálny popis syntaxe jazyka, ale popis významu konštrukciı́ je neformálny,
v prirodzenom jazyku. To často vedie k nejednoznačnému pochopeniu a
mnohým chybám v programoch.

Našı́m ciel’om je zaviest’ vyjadrenie významu konštrukciı́ jazykov explicitne a


jednoznačne použitı́m metód formálnej sémantiky.

Sémantika programovacı́ch jazykov 12/34


Syntax

Syntax programovacieho jazyka determinuje tvar a štruktúru programov


pı́saných v tomto jazyku.

Rozoznávame niekol’ko druhov syntaxe:


• konkrétnu syntax;
• abstraktnú syntax;
• regulárnu syntax;
• bezkontextovú syntax;
• kontextovú syntax.

Z hl’adiska formálnej definı́cie programovacieho jazyka nás bude zaujı́mat’ len


konkrétna a abstraktná syntax.

Sémantika programovacı́ch jazykov 13/34


Konkrétna syntax

Konkrétna syntax sa zaoberá textom programu a slúži pre lexikálnu a


syntaktickú kontrolu programov.

Konkrétna syntax:
• určuje, či ret’azce znakov patria do programovacieho jazyka;
• poskytuje syntaktický strom (parse tree) pre každý akceptovaný
program;
• je špecifikovaná formálnymi gramatikami a zapı́saná v BNF
produkčnými pravidlami pre každý neterminálny symbol;
• gramatika pre konkrétnu syntax by mala byt’ jednoznačná;
• ak je gramatika nejednoznačná, musia byt’ pridané pravidlá precedencie
pre výber jediného syntaktického stromu.

Sémantika programovacı́ch jazykov 14/34


Konkrétna syntax
BNF - Backus Naur Form - je formálny zápis, pomocou ktorého sa vyjadruje
gramatika jazyka v tvare produkčných pravidiel (John Backus, Peter Naur pre
Algol60).

John Backus Peter Naur

Sémantika programovacı́ch jazykov 15/34


Abstraktná syntax
Abstraktná syntax sa zaoberá len štruktúrou programov a slúži pre účely
formálnej sémantiky.

Zatial’čo konkrétna syntax sa zaoberá reálnymi ret’azcami znakov, abstraktná


syntax sa venuje len štruktúre, ktorú reprezentuje ako strom abstraktnej
syntaxe (abstract syntax tree), AST.

Definı́cia abstraktnej syntaxe pozostáva:


• zo syntaktických oblastı́ (domén);
• zo stromu abstraktnej syntaxe.

Strom abstraktnej syntaxe je definovaný nasledovne:


• v uzloch stromu sú prvky syntaktických oblastı́ (konštruktory);
• v listoch sú atomické entity, napr. pravdivostné hodnoty, čı́sla, niekedy
aj operácie;
• z každého uzla vedú hrany ku argumentom konštruktora.

Strom abstraktnej syntaxe môžeme zapı́sat’ aj v tvare produkčných pravidiel


BNF.
Sémantika programovacı́ch jazykov 16/34
V našom predmete budeme použı́vat’ nasledujúcu definı́ciu abstraktnej
syntaxe.

Abstraktná syntax pozostáva:


• zo syntaktických oblastı́;
• z jedného produkčného pravidla pre každú syntaktickú oblast’.

Každé produkčné pravidlo má tvar:

prvok syntaktickej oblasti::=alternativa 1 | alternativa 2 | . . .

Sémantika programovacı́ch jazykov 17/34


Prı́klad abstraktnej synaxe
Pre jazyk netypovaných aritmetických výrazov definujeme abstraktnú syntax:

1.Syntaktické oblasti:

x ∈ Var premenné
n ∈ Num reťazce číslic
e ∈ Expr aritmetické výrazy

n je atomická entita, pre abstraktnú syntax výrazov nie je dôležitý tvar čı́sel.
x je atomická entita, pre abstraktnú syntax výrazov nie je dôležitý tvar
identifikátorov.

2. Potrebujeme preto len jedno produkčné pravidlo pre syntaktickú oblast’


aritmetických výrazov:

e ::= n | x | e + e | e − e | e ∗ e

Sémantika programovacı́ch jazykov 18/34


Sémantika

Formálna sémantika programovacı́ch jazykov


• poskytuje abstraktné jednotky, koré reprezentujú len podstatné črty
všetkých možných vykonávanı́ programov pı́saných v danom jazyku
• ignoruje detaily, ktoré nie sú podstatné.

Obvykle sa za podstatné črty považuje


• vzt’ah medzi vstupom a výstupom
• terminovanie alebo neterminovanie vykonávania programu.
Implementačné detaily, napr.
• skutočné adresy v pamäti počı́tača,
• skutočný čas vykonávania programu,
• architektúra počı́tača
sa z hl’adiska sémantiky považujú za nepodstatné a ignorujú sa.

Sémantika programovacı́ch jazykov 19/34


Sémantické metódy

Poznáme viacero sémantických metód:

• operačná sémantika:
• naturálna sémantika;
• štrukturálna operačná sémantika;
• denotačná sémantika;
• axiomatická sémantika;
• akčná sémantika;
• atribútové gramatiky;
• algebraická sémantika;
• kategorická sémantika;
• sémantika hier.

Sémantika programovacı́ch jazykov 20/34


Atribútové gramatiky
• definujú systémy, ktoré systematicky počı́tajú metadáta (atribúty) pre
rôzne konštrukcie jazyka;
• súvisia s denotačnou sémantikou, ciel’ový jazyk je pôvodný jazyk
obohatený o anotácie atribútov;
• použı́va sa pre generovanie kódu v prekladačoch.

Algebraická sémantika definuje model špecifikácie (ADT) ako


mnohodruhovú algebru.

Kategorická sémantika použı́va ako základný formalizmus teóriu kategóriı́ a


model definuje ako funktor medzi kategóriami.

Sémantika hier je inšpirovaná teóriou hier.

Sémantika programovacı́ch jazykov 21/34


Operačná sémantika

Operačná sémantika:
• explicitne modeluje výpočty;
• prvá verzia bola formulovaná pre Algol68;
• význam programu popisuje v pojmoch abstraktného stroja;
• zaujı́ma sa o to, ako vzniká výsledok programu, t.j. ako sa zmenı́ obsah
pamäti;
• definuje správanie programu pomocou prechodov a odvodzovacı́ch
pravidiel;
• postupne sa vyvinuli dva druhy operačnej sémantiky:
• naturálna sémantika;
• štrukturálna operačná sémantika.

Sémantika programovacı́ch jazykov 22/34


Naturálna sémantika
Formuloval ju Gilles Kahn v roku 1985.
• umožňuje špecifikovat’ mnohé aspekty programovacı́ch jazykov aj
špecifikačných jazykov: typové systémy, statickú analýzu, dynamickú
sémantiku, atd’.;
• umožňuje špecifikovat’ časti prekladača a preložit’ ich priamo do
vykonávatel’ného kódu;
• nazýva sa aj sémantika vel’kých krokov, pretože sa zaoberá
sémantikou celých konštrukciı́ jazyka a nezaujı́ma ju podrobný priebeh
vykonávania programu.

Sémantika programovacı́ch jazykov 23/34


Prı́klad naturálnej sémantiky

z:= x; x:= y; y:= z


Predpokladajme, že máme triviálny program:
Zaujı́ma nás výsledný stav, ktorý zistı́me z odvodzovacieho stromu
aplikovanı́m odvodzovacı́ch pravidiel:
hz := x, s0 i → s1 hx:=y, s1 i → s2
hz:=x; x:=y, s0 i → s2 hy:=z, s2 i → s
hz:=x; x:=y; y:=z, s0 i → s

Nech s0 = [x 7→ 5, y 7→ 7, z 7→ 0] je počiatočný stav.


Výsledný stav s zistı́me z medzistavov:

s1 = s0 [z 7→ 5]
s2 = s1 [x 7→ 7]
s= s2 [y 7→ 5]
=[x 7→ 7, y 7→ 5, z 7→ 5]

Sémantika programovacı́ch jazykov 24/34


Štrukturálna operačná sémantika
Formulovali ju Dana Scott (1970) a neskôr Gordon Plotkin (1981).

• hlavnou myšlienkou je definovat’ správanie programu pomocou


správania jeho komponentov;
• snažı́ sa detailne, formálne popı́sat’ každý krok v procese vykonávania
programu;
• poskytuje induktı́vny pohl’ad na operačnú sémantiku;
• často sa nazýva sémantika malých krokov.

Sémantika programovacı́ch jazykov 25/34


Prı́klad štrukturálnej operačnej
sémantiky

Uvažujme prı́klad triviálneho programu z predošlého prı́kladu:

z:= x; x:= y; y:= z

a počiatočný stav s0 = [x 7→ 5, y 7→ 7, z 7→ 0].

Význam programu zistı́me z odvodzovacej postupnosti aplikovanı́m


odvodzovacı́ch pravidiel:

hz:= x; x:= y; y:= z, [x 7→ 5, y 7→ 7, z 7→ 0]i


⇒ hx:= y; y:= z, [x 7→ 5, y 7→ 7, z 7→ 5]i
⇒ hy:= z, [x 7→ 7, y 7→ 7, z 7→ 5]i
⇒ [x 7→ 7, y 7→ 5, z 7→ 5]

Posledným členom odvodzovacej postupnosti je výsledný stav.

Sémantika programovacı́ch jazykov 26/34


Denotačná sémantika
Autormi denotačnej sémantiky sú Christopher Strachey (1911-1975) a Dana Scott.
Formulovali ju koncom 60. rokov 20.storočia.

• význam programu popisuje pomocou matematických objektov - denotáciı́;


• význam programu definuje ako sémantickú funkciu zo vstupu do výstupu,
explicitne zo syntaktickej oblasti do sémantickej oblasti (domény);
• je úplne kompozičná, t.j. denotácia zložených konštrukciı́ sa definuje len
pomocou sémantiky ich podkonštrukciı́;
• zaujı́ma sa len o výsledok programu, nie o proces, ako sa k nemu dospelo;
• niekedy sa nazýva aj matematická sémantika.

Sémantika programovacı́ch jazykov 27/34


Prı́klad denotačnej sémantiky
Uvažujme prı́klad triviálneho programu z predošlého prı́kladu:

z:= x; x:= y; y:= z

a počiatočný stav s0 = [x 7→ 5, y 7→ 7, z 7→ 0].


Význam programu je kompozı́cia troch sémantických funkciı́ pre prirad’ovacie
prı́kazy:

S[[z:= x]], S[[x:= y]] a S[[y:=z]]


S[[z:= x; x:= y; y:= z]] = S[[z:= x]] ◦ S[[x:= y]] ◦ S[[y:= z]].

Výsledný stav vykonávania programu pre počiatočný stav s0 zı́skame


aplikáciou počiatočného stavu na túto zloženú funkciu:

S[[z:= x; x:= y; y:= z]]([x 7→ 5, y 7→ 7, z 7→ 0])


= (S[[z:= x]] ◦ S[[x:= y]] ◦ S[[y:= z]])([x 7→ 5, y 7→ 7, z 7→ 0])
= S[[y:= z]] (S[[x:= y]] (S[[z:= x]] ([x 7→ 5, y 7→ 7, z 7→ 0])))
= S[[y:= z]] (S[[x:= y]] ([x 7→ 5, y 7→ 7, z 7→ 5]))
= S[[y:= z]] ([x 7→ 7, y 7→ 7, z 7→ 5])
= [x 7→ 7, y 7→ 5, z 7→ 5]

Sémantika programovacı́ch jazykov 28/34


Axiomatická sémantika
Prvý prı́stup k axiomatickej sémantike formuloval Robert Floyd (1967).
Druhý, známejšı́ formuloval Charles Antony Richard Hoare (1969).

• význam programu popisuje pomocou logických formúl (prepodmienok a


postpodmienok);
• použı́va sa na dôkaz čiastočnej korektnosti programov;
• jednou z prvých aplikáciı́ bola axiomatická definı́cia programovacieho
jazyka Pascal (1973).

Sémantika programovacı́ch jazykov 29/34


Prı́klad axiomatickej sémantiky
Uvažujme znovu prı́klad triviálneho programu z predošlého prı́kladu:

z:= x; x:= y; y:= z

a počiatočný stav s0 = [x 7→ 5, y 7→ 7, z 7→ 0].


Pred program zapı́šeme prepodmienku a za program napı́šeme
pospodmienku:

{x = n ∧ y = m} z:= x; x:= y; y:= z {y = n ∧ x = m}

Počiatočný stav s0 = [x 7→ 5, y 7→ 7, z 7→ 0] spĺňa prepodmienku pre n = 5 a


m = 7.
Dôkaz vlastnosti čiastočnej korektnosti vyjadrı́me dôkazovým stromom:
{p0 }z:=x{p1 } {p1 }x:=y{p2 }
{p0 }z:=x; x:=y{p2 } {p2 }y:=z{p3 }
{p0 }z:=x; x:=y; y:=z{p3 }

pričom
p0 = x = n ∧ y = m p1 = z = n ∧ y = m
p2 = z = n ∧ x = m p3 = y = n ∧ x = m

Sémantika programovacı́ch jazykov 30/34


Akčná sémantika
Autormi sú Peter David Mosses a David Watt (1992).

• je hybridnou sémantikou, pokus modularizovat’ denotačnú sémantiku


rozdelenı́m formalizačného procesu do dvoch úrovnı́;
• prvá úroveň je makro sémantika a druhá úroveň je mikro sémantika;
• akčná sémantika predefinuje tri sémantické jednotky: akcie, dáta a
poskytovatel’ov.

Sémantika programovacı́ch jazykov 31/34


Prı́klad akčnej sémantiky
Uvažujme znovu prı́klad triviálneho programu z predošlého prı́kladu:

z:= x; x:= y; y:= z

a počiatočný stav s0 = [x 7→ 5, y 7→ 7, z 7→ 0].

Program zapı́šeme ako postupnost’ akciı́:


executeJz:= x; x:= y; y:= zK =
(executeJz:= xK and then executeJx:= yK) and then executeJy:= zK
kde postupným rozvojom dostávame:
((evaluate x and then store the given number in the cell bound to z)
and then
(evaluate y and then store the given number in the cell bound to x))
and then
(evaluate z and then store the given number in the cell bound to y) =

Sémantika programovacı́ch jazykov 32/34


((give the number stored in the cell bound to x then store the given number in
the cell bound to z)
and then
(give the number stored in the cell bound to y then store the given number in
the cell bound to x))
and then
(give the number stored in the cell bound to z then store the given number in
the cell bound to y)

kde po vyhodnotenı́ stavov dostávame výsledok:


(s1 [z 7→ x] (x = 5) and then s2 [x 7→ y] (y = 7)) and then s3 [y 7→ z] (z = 5)

Výsledný stav je s3 [x 7→ 7, y 7→ 5, z 7→ 5]

Sémantika programovacı́ch jazykov 33/34


Použitie sémantických metód
Všeobecne môžeme nájst’ aplikovanie formálnej sémantiky:
• pri návrhu programovacieho jazyka;
• pri hl’adanı́ skrytých vád navrhnutého jazykka;
• pre generovanie prekladačov a interpreterov;
• pre zápis štandardov programovacı́ch jazykov;
• pre stanovenie všeobecných vlastnostı́ jazykov;
• pre vyučovanie a použı́vanie programovacı́ch jazykov.

Doporučená literatúra:
• V Novitzká: Sémantika programov, ELFA Košice, 2001
• H.R.Nielson, F.Nielson: Semantics with applications. A formal
introduction. Wiley and Sons, 1992
• D.A Schmidt: Denotational semantics. Methodology for language
development. Allyn and Bacon, 1986
• P.D.Mosses: A tutorial on action semantics. Formalmethods Oxford,
1996
• C.A.R.Hoare, N.Wirth: An axiomatic definition of the programming
language Pascal, Acta Informatica 2(4), pp.335-355, 1973
Sémantika programovacı́ch jazykov 34/34

You might also like