Alfabeten, strängar och språk Objektorienterad modellering och diskreta strukturer / design Språk och reguljära uttryck Ett alfabet är en ändlig icketom mängd vars element kallas symboler. Lennart Andersson Reviderad 2011 10 03 2011 En sträng på ett alfabet är en ändlig följd av symboler ur alfabetet. Sträng OMD 2011 F10-1 String OMD 2011 F10-2 Låt Σ vara ett alfabet. ɛ är en sträng på Σ. Om σ Σ och α är en sträng på Σ så är σα en sträng på Σ. public interface String { public class Empty implements String { public class NonEmpty implements String { private char c; private String tail; OMD 2011 F10-3 OMD 2011 F10-4
String Längd public interface String { public int length(); public String concatenate{string other; public String reverse{; ɛ = 0 σα = 1 + α OMD 2011 F10-5 Konkatenering OMD 2011 F10-6 Reversering, prefix, etc. α R ɛ α = α (abc) R = cba. (σα) β = σ(α β) Om ω = α β γ, där α, β och γ är strängar kallar vi α för ett prefix, γ ett suffix och β en delsträng till ω. OMD 2011 F10-7 OMD 2011 F10-8
Potenser Språk α n+1 α 0 = α α n = ɛ, n 0 Med ett språk på ett alfabet menas en mängd strängar på alfabetet. OMD 2011 F10-9 Operationer OMD 2011 F10-10 Ett reguljärt uttryck L 1 \ L 2 = L1 L 2 = {ω L1 ω L 2 L 1 L 2 = L1 L 2 = {u v u L1 v L 2 L 0 L k+1 = {ɛ = L L k L = L + k=0 L k = L L Ett språk motsvarande reguljära uttryck {0 ({1({0 {1) ) 0 (1 (0 1) ) beskriver språket som innehåller alla binära tal utan onödiga inledande nollor {0, 1, 10, 11, 100,... OMD 2011 F10-11 OMD 2011 F10-12
Reguljära uttryck Mängden av reguljära uttryck på alfabetet Σ definieras av är ett reguljärt uttryck ɛ är ett reguljärt uttryck om σ Σ så är σ ett reguljärt uttryck om α och β är reguljära uttryck så är (α β) ett reguljärt uttryck om α och β är reguljära uttryck så är (α β) ett reguljärt uttryck om α är ett reguljärt uttryck så är α ett reguljärt uttryck Example a (a b) (((a b) a) (b a) ) är reguljära uttryck på alfabetet {a, b. OMD 2011 F10-13 Precedens OMD 2011 F10-14 Semantik högst lägst (((a b) a) (b a) ) kan skrivas ((a b)a)(ba) L[ ] L[ɛ] L[σ] = = {ɛ = {σ, σ Σ L[α β] L[α β] L[α ] = L[α]L[β] = L[α] L[β] = (L[α]) OMD 2011 F10-15 OMD 2011 F10-16
Example L[ab] = L[a]L[b] = {a{b = {ab L[a b] = L[a] L[b] = {a {b = {a, b L[(a b)(a b)] = L[a b]l[a b] = {a, b{a, b = {aa, ab, ba, bb Example Det reguljära uttrycket (0 1) betecknar språket av alla binära strängar. L[(0 1) ] = (L[(0 1)]) = (L[0] L[1]) = ({0 {1) = {0, 1 = {ɛ, 0, 1, 00, 01, 10, 11, 000,.... OMD 2011 F10-17 OMD 2011 F10-18 Utvidgad notation Example (0 (1(0 1) )) beskriver språket av alla binära strängar utan extra inledande nollor, {0, 1, 10, 11, 100,... DIGIT = [0 9] NAT = DIGIT + INT = ( )?NAT FLOAT = INT. NAT OMD 2011 F10-19 OMD 2011 F10-20
Reguljära uttryck med Java Grammatik Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); Reguljära uttryck klarar inte av att beskriva mängden av aritmetiska uttryck. boolean b = Pattern.matches("a*b", "aaaaab"); Om vi tillåter att man sätter namn på reguljära uttryck och använder dessa rekursivt kan vi beskriva språk med mer komplicerad struktur. OMD 2011 F10-21 Grammatik för aritmetiska uttryck OMD 2011 F10-22 BNF-grammatik Backus Naur-form Ett uttryck består av en eller flera termer separerade av enkla plus- eller minus-tecken. En term består i sin tur av en eller flera faktorer separerade av enkla multiplikations- eller divisions- tecken. En faktor är ett tal, en variabel eller ett uttryck inom parenteser. expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= NUMBER NAME ( expr ) addop ::= + - mulop ::= * / OMD 2011 F10-23 OMD 2011 F10-24
Begrepp Som i Algol 60 Report syntaxsymboler, N = {expr, term, factor, addop, mulop slutsymboler, Σ = {+, -, *, /, (, ), NUMBER, NAME produktioner, R = {expr ::= term (addop term),... startsymbol, S = expr <expr> ::= <term> (<addop> <term>)* <term> ::= <factor> (<mulop> <factor>)* <factor> ::= NUMBER NAME ( <expr> ) <addop> ::= + - <mulop> ::= * / G = (N, Σ, R, S) OMD 2011 F10-25 Härledning L[G] OMD 2011 F10-26 expr term addop term factor addop term NUMBER addop term NUMBER addop term NUMBER + term NUMBER + factor NUMBER + NAME expr NUMBER + NAME L[G] G = (N, Σ, R, S) = {w Σ S w OMD 2011 F10-27 OMD 2011 F10-28
En härledning En annan härledning expr ::= expr "+" expr expr ::= expr "*" expr expr ::= INT expr ::= expr "+" expr expr ::= expr "*" expr expr ::= INT Härledning av INT + INT * INT. Härledningsträd Härledning av INT + INT * INT. Härledningsträd expr => expr + expr => expr expr + expr * expr => / \ INT + expr * expr => expr + expr INT + INT * expr => / \ INT + INT * INT INT expr * expr INT INT expr => expr * expr => expr expr + expr * expr => / \ INT + expr * expr => expr * expr INT + INT * expr => / \ INT + INT * INT expr + expr INT INT INT OMD 2011 F10-29 Tvetydig grammatik OMD 2011 F10-30 Syntaxanalys av aritmetiska uttryck En grammatik är tvetydig om det finns mer än ett härledningsträd för någon sträng i språket. Om en grammatik är tvetydig måste man försöka hitta en grammatik som inte är det och som genererar samma språk. I det aktuella fallet vill man ha en grammatik som respekterar gängse precedens för operatorerna. expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= ID INT ( expr ) addop ::= + - mulop ::= * / OMD 2011 F10-31 OMD 2011 F10-32
Syntaxanalys av en faktor factor ::= ID INT ( expr ) private Expr factor() { switch (token) { case Scanner.ID : String name = scanner.token(); return new Variable(name); case Scanner.INT : String number = scanner.token(); return Integer.parseInt(number); case ( : Expr e = expr(); // Check that token== ) return e; OMD 2011 F10-33 Kompilatorteknik Syntaxanalys av en term term ::= factor (mulop factor)* private Expr term() { Expr result, factor; result = factor(); while (token == * token == / ) { int op = token; factor = factor(); switch (op) { case * : result = new Mul(result, factor); break; case / : result = new Div(result, factor); break; return result; OMD 2011 F10-34 Lexikalanalys - Reguljära uttryck och automater Syntaxanalys - Recursive descent och LR-parsing Semantisk analys - Namn- och typkontroll Kodgenerering Aspektorienterad programmering - Vertyg: javacc, jastadd, ddd Projekt - Bygg en egen kompilator Kursen ges i årskurs 4. OMD 2011 F10-35