Języki formalne i kompilatory (15 wyk., 15 ćw. audyt., 15 ćw. lab.) dr inŝ. Jolanta Cybulka Instytut Automatyki i InŜynierii Informatycznej, pok. 312a Wilda e-mail: Jolanta.Cybulka@put.poznan.pl www: http://www.man.poznan.pl/~jolac
Literatura 1. Aho A V., Sethi R., Ullman J.: Kompilatory. Reguły Metody i Narzędzia. WNT, Warszawa 2002. 2. Cybulka J., Jankowska B., Nawrocki J. R.: Automatyczne przetwarzanie tekstów. AWK, Lex i YACC, Wyd. NAKOM, Poznań, 2002. 3. Dembiński P., Małuszyński J.: Matematyczne metody definiowania języków programowania, WNT, Warszawa 1981. 4. Hopcroft J.E., Ullman J.D.: Wprowadzenie do teorii automatów, języków i obliczeń, PWN, Warszawa, 1994. 5. Révész G.E.: Introduction to Formal languages, McGraw-Hill, New York, 1983. 2
LITERATURA...2 1. JĘZYKI FORMALNE PODSTAWOWE POJĘCIA...4 2. TRANSLACJA I KOMPILACJA PODSTAWOWE POJĘCIA...10 3. ELEMENTY TEORII JĘZYKÓW FORMALNYCH...17 3.1. METODY DEFINIOWANIA SKŁADNI JĘZYKA <Σ, SYN>...17 3.2. HIERARCHIA JĘZYKÓW WG N. CHOMSKY'EGO:...18 3.3. FORMALNY SYSTEM GENERACJI SKŁADNI (PODEJŚCIE GENERACYJNE)...19 3.4. FORMALNA DEFINICJA AUTOMATU (PODEJŚCIE AKCEPTOROWE)...22 4. JĘZYKI REGULARNE (KLASA "3")...23 4.1. WYRAśENIA REGULARNE...23 4.2. JĘZYK AWK...25 4.2.1.Schemat programu (ciąg reguł przetwarzania) i sposób przetwarzania...25 4.2.2. Rodzaje wzorców...27 4.2.3. Wzorzec z wyraŝeniem regularnym...28 4.2.4. Wzorzec z operatorami relacyjnymi...29 4.2.5. Wzorzec ze spójnikami logicznymi (przykłady programów)...30 4.2.6. Wzorzec warunkowy...30 4.2.7. Wzorzec zakresu...30 4.2.8. Akcje w programach...31 4.2.9. Przykłady programów...37 3
1. Języki formalne podstawowe pojęcia Język (symboliczny) Język naturalny (narodowy) Język sztuczny (formalny) rozwaŝamy języki symboliczne, skonstruowane z symboli naleŝących do zbioru (niepustego, skończonego), zwanego alfabetem, np.: D = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} B = {0,1} H = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F} Lat = {a, b, c,, z, A, B, C,, Z} Pol = {a, ą, b, c, ć,, Ŝ, dz, dź, dŝ, A, Ą, B, C, Ć,, Z, Dz, Dź, DŜ} S = {,,,,, p, f, (, )} i wiele innych (alfabet Morse a, Braille a, symbole nutowe, symbole chemiczne, znaki migowe, ); 4
z symboli alfabetu, zgodnie z zadanymi regułami składania symboli powstają napisy języka zbiór wszystkich napisów naleŝących do języka (i tylko takich) nazywamy jego składnią (syntaktyką, syntaksą); 0 123 09 55000 nad alfabetem D 0001 11001 0 1 nad alfabetem B 0 123F 09A FFAA nad alfabetem H Fundamenta Informaticae Formal Language nad alfabetem Lat Ala mieć ma As Asa nad alfabetem Pol p f p (f p) p p nad alfabetem S 5
składnia moŝe mieć strukturę warstwową, tzn. z ciągu symboli powstają napisy elementarne, których zbiór staje się nowym alfabetem, z którego powstają nowe napisy: nad alfabetem L = {Ala, mieć, ma, As, Asa,\, \n, \t } moŝna zbudować napis Ala ma Asa nad alfabetem C = {if, else, (, ), {, },=, ;, ++, >, num, id, \, \n, \t } moŝna zbudować napis if (xsr >12) {y++;} else {y=xsr;} 6
w wypadku języków formalnych, na składni moŝna wykonywać operacje mnogościowe, jak: suma, róŝnica, przecięcie, dopełnienie do uniwersum, złoŝenie, potęgowanie, domknięcie; A = {a, b, c} alfabet potęgowanie: A 0, A 1, A 2, A 3, A 0 = {ε} słowo długości 0, słowo puste A 1 = { a, b, c } słowa długości 1 A 2 = { aa, ab, ac, ba, bb, bc, ca, cb, cc } słowa długości 2 A 3 = { aaa, aab, aac, aba, abb, abc, aca, acb, acc, baa, bab, bac, bba,bbb, bbc, bca, bcb, bcc, caa, cab, cac, cba, cbb, cbc, cca, ccb, ccc} słowa długości 3 domknięcie zwrotne i przechodnie operacji potęgowania: A * A * = A 0 A 1 A 2 A 3 = (i = 0, ) A i domknięcie przechodnie operacji potęgowania: A + A + = A 1 A 2 A 3 = (i = 1, ) A i 7
napisy (składnia) słuŝą do notowania znaczeń, zadaniem funkcji semantyki języka formalnego jest przypisanie kaŝdemu elementowi składniowemu (napisowi) znaczenia z pewnej dziedziny znaczeń: znaczeniem napisu (2+3)*4 nad alfabetem A n = {0,1,,9} A o ={+, * } { (,)} jest 20 o ile D = {1, 2, 3, } jest zbiorem wartości (liczb) naturalnych, F = {plus, times} jest zbiorem funkcji (dodawania i mnoŝenia), val n : A n D val o : A o F, val o (+)= plus, val o (*)= times value : (A n A o { (,)})* D (dla napisów poprawnych składniowo) 8
język formalny L definiujemy matematycznie jako: L = <Σ, Syn, DSem, Sem> Σ alfabet, skończony niepusty zbiór symboli (znaków), Syn syntaktyka (składnia, syntaksa), zbiór napisów języka, zbudowanych z symboli alfabetu, DSem dziedzina znaczeń, zbiór bytów semantycznych, przypisywanych napisom języka, Sem relacja semantyczna (Sem Syn DSem), definiująca związki między napisami języka a elementami dziedziny znaczeń (relacja ta w zastosowaniach praktycznych jest funkcją semantyki); dodatkowo, język zastosowany w pewnej dziedzinie moŝe wytwarzać odmiany pragmatyczne: L 1 = <Σ, Syn, DSem 1, Sem 1 > L 2 = <Σ, Syn, DSem 2, Sem 2 > 9
2. Translacja i kompilacja podstawowe pojęcia zagadnienie translacji: tekst wejściowy ------->TRANSLACJA--------->wynik translacji zajmiemy się tylko wybranymi aspektami translacji: dotyczącymi tekstów napisanych w językach formalnych (sztucznych, np. językach programowania, dostępu do baz danych, publikacji informacji w Internecie HTML, SGML, XML itd.) w modelu translacji sterowanej składnią (L = <Σ, Syn >) translacja sterowana składnią proces, w którym po przeanalizowaniu struktury składniowej tekstu wejściowego jest on interpretowany lub na jego podstawie generowany jest tekst wyjściowy narzędzia programistyczne realizujące translacje sterowane składnią to np.: AWK, Lex, YACC, sed, PERL i wiele innych, w tym języki programowania 10
wyróŝniamy dwie techniki translacji: interpretację i kompilację proces kompilacji realizuje program zwany kompilatorem: tekst wejściowy --> kompilator --> tekst wyjściowy kompilacja przebiega w dwóch etapach: a) analizy tekstu wejściowego i b) syntezy tekstu wyjściowego, które rozpadają się na fazy (kaŝda faza przetwarza tekst wejściowy lub jego reprezentację): 11
tekst wejściowy tabela symboli, reprezentacje pośrednie tekstu analizator leksykalny analizator składniowy analizator zaleŝności kontekstowych generator kodu pośredniego etap analizy tekstu wejściowego optymalizator kodu generator kodu wynikowego etap syntezy (tekstu) kodu wynikowego 12 tekst wyjściowy
kompilacja moŝe być jedno- lub wieloprzebiegowa przykład kompilacji: program p1; var x: real; i: integer; begin x:=i+1; end. Analizator leksykalny wyodrębni następujący zbiór jednostek leksykalnych: program p1 var x : real ; i : integer begin := + 1 end. Analizator składniowy utworzy drzewo rozbioru składniowego, a informacje o identyfikatorach zmiennych umieści w tabeli symboli: := id1 + id2 1 13
Nazwa Leksem Typ... id1 x real... id2 i integer... Analizator zaleŝności kontekstowych stwierdzi, Ŝe zmienne wykorzystane w instrukcji przypisania zostały zadeklarowane (informacje o tym zawarto w tabeli symboli) oraz zaznaczy w kodzie pośrednim, Ŝe naleŝy przeprowadzić konwersję typu stałej 1 i zmiennej i z typu integer do typu real (operator itor): := id1 + itor itor id2 1 14
Generator kodu trójadresowego, wygeneruje dwie zmienne okresowe temp1 i temp2 i na podstawie powyŝszego drzewa utworzy zapis: temp1 := itor(1) temp2 := itor(id2) id1 := temp1 + temp2 Optymalizator kodu dokona redukcji: temp1 := itor(id2) id1 := temp1 + 1.0 Na podstawie kodu pośredniego, generator kodu wynikowego utworzy zapis w kodzie asemblera, który następnie poddany zostanie asemblacji w celu uzyskania wersji wykonywalnej: MOV id2, R1 ADD R1, #1.0 MOV R1, id1 15
Na czym moŝe polegać definiowanie i przetwarzanie języka formalnego? a) określenie języka (wszystkich jego elementów) w sposób ścisły, za pomocą odpowiednich metod i narzędzi b) badanie przynaleŝności napisu do języka (sprawdzenie poprawności napisu) c) translacja napisu z jednego języka na drugi 16
3. Elementy teorii języków formalnych 3.1. Metody definiowania składni języka <Σ, Syn> metody definiowania składni dzielimy na: generacyjne i akceptorowe, w metodach generacyjnych podaje się zbiór reguł generacji (formalny system generacji składni) poprawnych napisów nad podanym alfabetem (np. gramatyki kombinatoryczne N. Chomsky ego), w metodach akceptorowych definiuje się nad alfabetem automat/akceptor (formalna definicja automatu), który potrafi zbadać przynaleŝność napisu do języka (wszystkie napisy zaakceptowane przez automat definiują język), kaŝdemu typowi gramatyki odpowiada typ automatu (podejścia są zatem komplementarne), translator jest przetwornikiem napisów, od akceptora róŝni się tym, Ŝe ma zdefiniowany alfabet wyjściowy i potrafi generować napisy w języku nad tym alfabetem (formalnie, jest automatem z wyjściem ). 17
3.2. Hierarchia języków wg N. Chomsky'ego: klasy języków uporządkowane relacją zawierania się zbiorów; języki klasy "0" nazywamy obliczalnymi, są klasą najszerszą, matematycznie są przykładem zbiorów rekurencyjnie przeliczalnych (częściowo rozstrzygalnych); języki klasy "1" nazywamy monotonicznymi, matematycznie są przykładem zbiorów rekurencyjnych (rozstrzygalnych); języki klasy "2" nazywamy bezkontekstowymi; wyróŝnia się istotne z praktycznego punktu widzenia podklasy LL i LR (generator YACC); języki klasy "3" nazywamy regularnymi; biorą swą nazwę od jednego z formalizmów ich definiowania zwanego wyraŝeniami regularnymi; 18
3.3. Formalny system generacji składni (podejście generacyjne) F = < Σ, Syn, P, s> Σ alfabet Syn syntaktyka P zbiór reguł generacji napisów ze zbioru Syn s wyróŝniony zbiór napisów początkowych; przykładem systemu generacji jest formalny system kombinatoryczny: F = < Σ, Syn, P, s >, gdzie P Σ * Σ *, s Σ * ; przykładem systemu kombinatorycznego jest gramatyka kombinatoryczna (klasa 0), zdefiniowana przez Noama Chomsky ego: G = < N, Σ, P, S > N Σ = N skończony niepusty alfabet symboli pomocniczych (nieterminalnych), Σ skończony, niepusty alfabet definiowanego języka (symbole terminalne), P (N Σ) + (N Σ) *, zbiór produkcji gramatyki (reguł generacji napisów), S N, wyróŝniony symbol pomocniczy, zwany aksjomatem gramatyki; 19
produkcję gramatyki, opisującą związek pomiędzy dwoma napisami (np. napisem α i napisem β), zapisujemy zwyczajowo α β, gdzie strzałka oznacza znak zastąpienia, a cały napis poleca zastąpić napis α napisem β; relacja wywodu bezpośredniego (oraz jej domknięcie *): xabcy xdvy o ile w zbiorze P istnieje produkcja abc dv; język J(G) generowany gramatyką G: J(G) = {x S * x x Σ*} zdanie (lub słowo) to napis zbudowany wyłącznie z symboli terminalnych, uzyskany za pomocą relacji wywodu *; napis zawierający symbole terminalne i nieterminalne, równieŝ uzyskany za pomocą relacji wywodu *, nazywamy formą zdaniową, 20
operacje na językach (zbiorach słów J, J 1, J 2 ): suma: J 1 J 2 = {x x J 1 x J 2 }, przekrój: J 1 J 2 = {x x J 1 x J 2 }, róŝnica: J 1 - J 2 = {x x J 1 x J 2 }, dopełnienie: J = Σ*- J, złoŝenie: J 1 J 2 = {xy x J 1 y J 2 }, potęgowanie: J n, J 0 = {ε}, J k = JJ k-1, domknięcie: J * = J i, i = 0 domknięcie dodatnie: J + = J i, J + = JJ * =J * J, J * =J + {ε} i = 1 21
3.4. Formalna definicja automatu (podejście akceptorowe) w podejściu akceptorowym: automat M akceptuje słowo (zdanie) s wtw. startując od konfiguracji początkowej ze słowem s na wejściu moŝe wykonać skończony ciąg kroków kończących się konfiguracją końcową automat M definiuje język L(M), który jest zbiorem wszystkich słów s akceptowanych przez M 22
4. Języki regularne (klasa "3") 4.1. WyraŜenia regularne wyraŝeniem regularnym (ang. regular expression) nad alfabetem Σ nazywamy napis zbudowany za pomocą następującej rekurencyjnej definicji: 1) jest w. r. oznaczającym język pusty (pusty zbiór napisów), 2) ε jest w. r. oznaczającym język {ε}, 3) jeśli a Σ, to napis a jest w. r. oznaczającym język {a}, 4) jeśli r 1 i r 2 są w. r., to napis r 1 r 2 jest w. r. oznaczającym język L(r 1 )L(r 2 ), 5) jeśli r 1 i r 2 są w. r., to napis r 1 r 2 jest w. r. oznaczającym język L(r 1 ) L(r 2 ), 6) jeśli r jest w. r., to napis r * jest w. r. oznaczającym język (i=0, ) L(r) i, 7) jeśli r jest w. r., to (r) jest w. r. oznaczającym L(r). właściwości wyraŝeń regularnych; niech p, q i r oznaczają dowolne wyraŝenia regularne, wtedy: p (q r) = (p r) q p(qr) = (pq)r p q = q p p* = ε pp* (p q)r = pr qr r(p q) = rp rq 23
εp = pε = p p = p = przykłady Niech Σ = {0, 1, 2} 1) 11 reprezentuje język {11}, p* = (ε p)* if p = r pq q ε then p = rq* 2) (0 1)* reprezentuje język wszystkich napisów zbudowanych z zer i jedynek, 3) (0 1)*11(0 1)* reprezentuje język wszystkich napisów zbudowanych z zer i jedynek, w których co najmniej raz występują dwie kolejne jedynki, 4) 0*1*2* reprezentuje język składający się z napisów zbudowanych z dowolnej liczby zer, po której następuje dowolna liczba jedynek, a następnie dowolna liczba dwójek; Niech Σ = {0, 1, 2, 9, a, b, z, A, B Z, _,, +} 5) (a b z A B Z _)(a b z A B Z 0 1 9 _)* reprezentuje język identyfikatorów będących niepustymi ciągami liter, cyfr i znaków podkreślenia, rozpoczynającymi się od litery lub znaku podkreślenia, (- + ε)(0 1 9)(0 1 9)* reprezentuje język stałych całkowitych dziesiętnych; 24
4.2. Język AWK Tekst wejściowy Program w AWK Tekst wyjściowy 4.2.1.Schemat programu (ciąg reguł przetwarzania) i sposób przetwarzania wzorzec 1 akcja 1 reguła przetwarzania wzorzec 2 akcja 2... wzorzec n akcja n opcjonalna lista definicji funkcji niestandardowych tekst wejściowy i wyjściowy: ciąg wierszy podzielonych na pola ($0, NF, NR, FS, OFS, RS, ORS) program wczytuje wiersz, przegląda po kolei reguły przetwarzania i jeśli wzorzec pasuje do wiersza, to wykonywana jest akcja z nim związana (sytuacje specjalne: wzorce BEGIN i END oraz kilka plików wejściowych) 25
przykładowy tekst wejściowy (we.txt): 20501 Augustyn Kowalski I1 0.6 0.7 1.0 20456 Emilia Oltaren I1 0.2 0.7 0.9 20593 Hanna Zawadiacka I2 1.0 0.5 0.7 20397 Zefiryn Marchewka I3 1.0 1.0 1.0 20293 Joanna Prawdziwa I1 0.7 0.2 1.0 20517 Karol Nielepszy I4 0.2 0.5 0.5 - przykładowy tekst wyjściowy (wy.txt): LP NR INDEKSU NAZWISKO IMIE SUMA PUNKTOW 1 20501 Kowalski Augustyn 2.3 2 20456 Oltaren Emilia 1.8 3 20593 Zawadiacka Hanna 2.2 4 20397 Marchewka Zefiryn 3. 5 20293 Prawdziwa Joanna 1.9 6 20517 Nielepszy Karol 1.2 26
Liczba osob: 5 # Program drukuje zestawienie informacji o studentach # BEGIN {licz=0;print "LP NR INDEKSU NAZWISKO IMIE SUMA PUNKTOW\n"; } {suma_punktow=$5+$6+$7;printf("%-5i%-14i%-14s%-12s%-12g\n", NR,$1,$3,$2,suma_punktow); if((float)suma_punktow>=1.8)licz++; } END {print "\nliczba osob: ",licz ;} gawk -f program.awk <we.txt >wy.txt 4.2.2. Rodzaje wzorców wzorzec BEGIN i wzorzec END wzorzec w postaci wyraŝenia regularnego wzorzec z operatorami relacyjnymi wzorzec zawierający spójniki logiczne 27
wzorzec warunkowy wzorzec zakresu 4.2.3. Wzorzec z wyraŝeniem regularnym / wyraŝenie_regularne/ $0 ~ / wyraŝenie_regularne/ alfabet w języku AWK (kod ASCII), znaki specjalne alfabetu: \ / - ^ $. [ ] ( ) * +? przykłady programów zawierających wzorce w postaci wyraŝenia regularnego: /Z/ akcja pusta (przepisanie dopasowanego wejścia na wyjście) /\./ /^n$/ {print NR, $0;} /^.$/ /[0-9]/ 28
/[^0-9]/ /^[0-9]/ /Augustyn Zefiryn/ /[A-Za-z][A-Za-z0-9]*/ /[0-9][0-9]*(D d)?/ 4.2.4. Wzorzec z operatorami relacyjnymi wyraŝenie operator_relacyjny wyraŝenie przykłady programów: $1 > $2 $4 ~ /n/ BEGIN {regexpr="n";} $4 ~ regexpr wzorzec dynamiczny 29
$0!~ /[A-Za-z][A-Za-z0-9]*/ 4.2.5. Wzorzec ze spójnikami logicznymi (przykłady programów) ($3 == "Ola" $5 >= 2.0) && NR>1!/[Zz]/ 4.2.6. Wzorzec warunkowy wyraŝenie? wzorzec1 : wzorzec2 ($5 > 2.0)?(/Z/):(!/z/) 4.2.7. Wzorzec zakresu /wzorzec_pierwszego_wiersza/, /wzorzec_ostatniego_wiersza/ /Emilia/, /Oltaren/ 30
4.2.8. Akcje w programach (ciągi instrukcji: przypisania, wyjścia, warunkowych, iteracyjnych, break, continue, delete, exit) w akcjach moŝna wykorzystywać stałe numeryczne i stałe łańcuchowe (mogą zawierać sekwencje znaków specjalnych) takŝe zmienne proste i tablice (jednowymiarowe): 1) zmienne przechowujące wartości pól bieŝącego wiersza ($1, $2,, $i, $NF-3) 2) zmienne standardowe, predefiniowane w kaŝdym programie ($0, NF, ) 3) zmienne uŝyte przez programistę; funkcje standardowe i niestandardowe (arytmetyczne i łańcuchowe) Funkcja Opis Funkcje arytmetyczne atan2(x,y) Oznacza funkcję arcus tangens z x/y w zakresie od -π do π. cos(x) Oznacza funkcję cosinus x. exp(x) Oznacza funkcję e x. int(x) Oznacza funkcję entier(x) (część całkowita x). 31
log(x) Oznacza funkcję logarytm naturalny z x. rand(x) Oznacza funkcję generującą liczbę pseudolosową z przedziału [0-1]. sin(x) Oznacza funkcję sinus x. sqrt(x) Oznacza funkcję pierwiastek kwadratowy z x. srand(x) Oznacza funkcje inicjującą działanie generatora liczb pseudolosowych wartością x. Funkcje łańcuchowe gsub(r, s, t) Jeśli w t występuje ciąg pasujący do r, to zastąp go przez s; wartością funkcji jest liczba wykonanych zastąpień; wyraŝeniem t moŝe być $0, wtedy wywołanie funkcji zapisujemy jako gsub(r, s). index(s, t) Jeśli ciąg t występuje w ciągu s, to wartością funkcji jest numer pierwszej pozycji t w s lub 0, jeśli t nie występuje w s. length(s) Wartością funkcji jest długość ciągu s. match(s, r) Jeśli w s występuje ciąg pasujący do r, to wartością funkcji jest numer pierwszego znaku tego ciągu w s lub 0, gdy ciąg ten nie występuje. Funkcja ta zmienia takŝe wartości standardowych zmiennych RSTART i RLENGTH. split(s, a, r) Funkcja traktuje s jak ciąg pól oddzielonych od siebie separatorem r, generuje tablicę a i umieszcza w niej wspomniane pola; wartością funkcji jest liczba pól. Jeśli wywołanie funkcji przyjmie postać split(s, a), to domyślną wartością separatora jest wartość zmiennej standardowej FS. sprintf(fmt, e1,,en) sub(r, s, t) Funkcja drukuje wartość wyraŝeń e1,, en zgodnie z formatem fmt; wartością funkcji jest wydrukowany ciąg znaków. Funkcja działa podobnie, jak gsub(r, s, t), jednakŝe dokonuje zastąpienia ciągiem s tylko 32
jednego, skrajnie lewego ciągu pasującego do r. Wartością funkcji jest więc 0 lub 1. substr(s, p, n) Wartością funkcji jest podciąg ciągu s, zaczynający się na pozycji p i mający długość n. substr(s, p) Wartością funkcji jest podciąg ciągu s zaczynający się na pozycji p i kończący na ostatniej pozycji ciągu s. tolower(s) Wartością funkcji jest kopia ciągu s, w której zamieniono wszystkie wielkie litery na małe (pozostałe znaki bez zmian). toupper(s) Wartością funkcji jest kopia ciągu s, w której zamieniono wszystkie małe litery na wielkie (pozostałe znaki bez zmian). zestawienie zmiennych standardowych języka AWK: Zmienna ARGC Liczba argumentów polecenia gawk (z wyjątkiem opcji i nazw plików z programem). ARGIND Indeks elementu tablicy ARGV (patrz niŝej) wskazującego bieŝący plik wejściowy. ARGV Tablica argumentów polecenia gawk, indeksowana od 0 do ARGC-1; zmieniając zawartość tej tablicy, mamy moŝliwość zarządzania przetwarzaniem plików z tekstami wejściowymi. CONVFMT Format konwersji wartości dla liczb; formatem domyślnym jest "%.6g". ERRNO Opis Napis sygnalizujący wystąpienie błędu podczas wykonywania instrukcji getline lub close() 33
34 FILENAME Nazwa bieŝącego pliku wejściowego; jeśli nie uŝyto Ŝadnej nazwy pliku, to nazwą zastępczą jest znak minus -; wartość zmiennej FILENAME nie jest dostępna w akcjach związanych z wzorcem BEGIN. FNR Liczba dotychczas przetworzonych wierszy bieŝącego pliku danych wejściowych (całkowita liczba wierszy jest dostępna w akcji związanej z wzorcem END). FS Separator pól w tekście wejściowym domyślnie niepusty ciąg znaków spacji, tabulacji. IGNORECASE Wartość zmiennej wskazuje, czy wielkie i małe litery mają być rozróŝniane (wartość 0), czy teŝ nie (wartość niezerowa). NF Liczba pól w bieŝącym wierszu pliku danych wejściowych. NR Liczba wierszy tekstu wejściowego przeczytanych do tej pory. OFMT Format liczb w pliku wyjściowym domyślnie "%.6g". OFS Separator pól w tekście wyjściowym domyślnie spacja. ORS Separator wierszy w tekście wyjściowym domyślnie \n. RLENGTH Długość ciągu znaków dopasowanego za pomocą funkcji match() RS Separator wierszy w tekście wejściowym domyślnie \n. RSTART Indeks pierwszego znaku w ciągu dopasowanym za pomocą funkcji match() SUBSEP Znak uŝywany do oddzielania indeksów w tablicach (jeśli symulujemy działanie tablic wielowymiarowych) domyślnie jest to znak o kodzie \034. zestawienie operatorów arytmetycznych, logicznych i łańcuchowych Operator Opis
= += Binarne operatory 1 przypisania (wzorowane na podobnych z C). -= *= /= %= ^=?: Ternarny operator wyraŝenia warunkowego postaci: expr1?expr2:expr3; jeśli expr1 jest prawdziwe, to wartością całego wyraŝenia jest wartość expr2, w przeciwnym wypadku, wartością wyraŝenia jest wartość expr3. Binarny spójnik logiczny oznaczający alternatywę. && Binarny spójnik logiczny oznaczający koniunkcję. in Binarny operator wykorzystywany w instrukcjach iteracyjnych realizujących dostęp do elementów tablic. ~!~ Binarny operator ~ słuŝący do sprawdzania, czy pierwszy argument zawiera ciąg znaków pasujący do wzorca będącego drugim argumentem i negacja!~ tego operatora. < > Binarne operatory oznaczające relacje mniejszości i większości. <= >= Binarne operatory oznaczające relacje mniejsze lub równe i większe lub równe.!= == Binarne operatory oznaczające relacje róŝne i równe. blank Binarny operator sklejania łańcuchów znakowych; zamiast słowa blank moŝna uŝyć spacji lub pustego ciągu znaków. + - Binarne operatory oznaczające dodawanie i odejmowanie. *? % Binarne operatory oznaczające mnoŝenie, dzielenie i operację modulo (reszta z dzielenia). + -! Unarny, prefiksowy plus, unarny prefiksowy minus i unarny prefiksowy spójnik negacji 1 Wszystkie operatory zapisuje się infiksowo, o ile nie wskazano jawnie innej notacji. 35
logicznej. ^ Binarny operator oznaczający potęgowanie. ++ -- Unarne operatory inkrementacji i dekrementacji, zapisywane prefiksowo i postfiksowo. zestawienie postaci wywołań funkcji getline i next Postać wywołania Opis działania getline Wczytaj kolejny wiersz z bieŝącego źródła tekstu wejściowego, przypisz go zmiennej $0 oraz podziel na pola i ustal nowe wartości zmiennych: NF, NR, FNR. getline < "file" Wczytaj kolejny wiersz z pliku file, przypisz go zmiennej $0, podziel na pola i ustal nową wartość zmiennej NF. getline x Wczytaj kolejny wiersz z bieŝącego wejścia, przypisz go zmiennej x i ustal nowe wartości zmiennych NF i FNR. getline x < "file" Wczytaj kolejny wiersz z pliku file, przypisz go zmiennej x. "command" getline "command" getline x next Przypisz zmiennej $0 wartość kolejnego wiersza wygenerowanego poleceniem command, podziel ten wiersz na pola i ustal nową wartość zmiennej NF. Przypisz zmiennej x wartość kolejnego wiersza tekstu wygenerowanego poleceniem command. Zakończ przetwarzanie bieŝącego wiersza tekstu, wczytaj kolejny wiersz i rozpocznij wykonywanie programu od pierwszej reguły przetwarzania. Jeśli osiągnięto koniec tekstu wejściowego, to wykonuje się reguły związane ze wzorcem END 2 (gdy są w programie). 2 Instrukcja next nie moŝe występować w akcjach związanych z wzorcami BEGIN i END. 36
nextfile Zakończ przetwarzanie bieŝącego pliku źródłowego, wczytaj wiersz z następnego pliku (tablica ARGV), zmień wartość zmiennych FILENAME i ARGIND, przypisz zmiennej FNR wartość 1 i rozpocznij wykonywanie programu od pierwszej reguły przetwarzania. Jeśli osiągnięto koniec tekstu wejściowego, to wykonaj reguły związane ze wzorcem END (gdy są w programie). 4.2.9. Przykłady programów {gsub(/\ \ */," "); print;} {split($0,t,"-");print "dzien: "t[1]" miesiac: "t[2]" rok: "t[3];} BEGIN {puste=1;} puste && /[0-9]/ {wynik=$1;puste=0;}!puste && /[0-9]/ {wynik=nwp(wynik,$1);} END {print wynik;} function nwp(a,b) { while (a!=b) {if (a>b) a-=b; else b-=a;} return a; } 37
{Lpol+=NF;} END{print " Liczba pol: "Lpol" Liczba linii: "NR;} (NR>2)&&(NR<9) {$2=$2+1000;$NF="";print;} plik wejściowy zarzad.txt : prezes: Jan Czermen zastepca: Magda Wicewicz sekretarz: vacat skarbnik: Krzysztof Pieniazek czlonek: vacat czlonek: Roman Memberski plik wejściowy vacat.txt : sekretarz: Jerzy Papierek czlonek: Anna Wakacka 38
program: BEGIN {"echo. date" getline;printf("%35s,%s\n", $4,$5);} /vacat/ {getline < "vacat.txt"; }!/vacat/ {print;} /prezes/ {sub(/prezes/,"opiekun");}!/prezes/ {print;} (NR>1)&&(NR<9) {print $3, $4 "sort";} {if($0 ~ /prezes/) { sub(/prezes/,"dyrektor"); print;next; }else print;} /prezes/{sub(/prezes/,"opiekun");print; next} {print} 39
(NR>1)&&(NR<9) {for(i=nf;i>0;i--){printf("%-12s",$i);} printf("\n"); } {x[nr]=$0;} END {for (i=nr;i>0;i--) print x[i];} 40