Objektorienterad modellering och diskreta strukturer 11. Reguljära uttryck och grammatiker Sven Gestegård Robertz Datavetenskap, LTH 2014
Rekaputilation Vi har talat om satslogik och härledning predikatlogik och substitution mängder och språk reguljära uttryck Vi kommer att studera reguljära uttryck och deras begränsning grammatiker Rekapitulation 11. Reguljära uttryck och grammatiker 2/32
Alfabeten, strängar och språk Ett alfabet är en ändlig icketom mängd vars element kallas symboler. En sträng på ett alfabet är en ändlig följd av symboler ur alfabetet. Med ett språk på ett alfabet menas en mängd strängar på alfabetet. Rekapitulation 11. Reguljära uttryck och grammatiker 3/32
Operationer på språk Konkatenering L 1 L 2 = L1 L 2 = {u v u L1 v L 2 } L k : konkateneringen av exakt k strängar ur L L 0 L k+1 = {ɛ} = L L k Kleene-stjärna, hölje L = k=0 L k Rekapitulation 11. Reguljära uttryck och grammatiker 4/32
Ett reguljärt uttryck Ett språk {0} ({1} ({0} {1}) ) motsvarande reguljära uttryck 0 (1 (0 1) ) beskriver språket som innehåller alla binära tal utan onödiga inledande nollor {0, 1, 10, 11, 100,...} Rekapitulation 11. Reguljära uttryck och grammatiker 5/32
Reguljära uttryck Mängden av reguljära uttryck på alfabetet Σ denieras av Denition ä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 Rekapitulation 11. Reguljära uttryck och grammatiker 6/32
Exempel a (a b) (((a b) a) (b a) ) är reguljära uttryck på alfabetet {a, b}. De tre första uttrycken beskriver {a} {ab} och det tredje språket som innnehåller, bland andra, strängarna aa ba aaba bababa Rekapitulation 11. Reguljära uttryck och grammatiker 7/32
Semantik Reguljära språk Värdet av ett reguljärt uttryck är ett reguljärt språk. Denition Mängden av reguljära språk på alfabetet Σ denieras av L[ ] = L[α β] = L[α]L[β] L[ɛ] = {ɛ} L[α β] = L[α] L[β] L[σ] = {σ}, σ Σ L[α ] = (L[α]) Kommentar Notera att L[ɛ] = {ɛ} = L[ ], varför L[ɛ] kan utelämnas från denitionen. Rekapitulation 11. Reguljära uttryck och grammatiker 8/32
Exempel: Reguljära uttryck och maskiner Det reguljära uttrycket a ( (bc)*d) ef* ) accepteras av maskinen b c a start q 0 q 1 q 2 q 3 b e d q 4 d q 5 f Ett språk är reguljärt omm det kan accepteras av en nit tillståndsmaskin. Reguljära uttryck : Finita tillståndsmaskiner och reguljära uttryck 11. Reguljära uttryck och grammatiker 9/32
Exempel 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} L[ab ] = L[a]L[b ] = {a} {b} = {a, ab, abb, abbb...b} Reguljära uttryck : Exempel 11. Reguljära uttryck och grammatiker 10/32
Exempel 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,...}. Exempel (0 (1(0 1) )) beskriver språket av alla binära strängar utan extra inledande nollor, {0, 1, 10, 11, 100,...} Exempel Språket { a i b i i 0 } är inte reguljärt Reguljära uttryck : Exempel 11. Reguljära uttryck och grammatiker 11/32
Utvidgad notation DIGIT = [0 9] NAT = DIGIT + INT = ( )?NAT FLOAT = INT. NAT Namn får inte användas rekursivt. Reguljära uttryck : Exempel 11. Reguljära uttryck och grammatiker 12/32
Reguljära uttryck enligt POSIX Syntax för de grundläggande delarna i reguljära uttryck så som de skrivs i Java och verktyg som grep, sed, awk m.. symbol matchar ------ --------------------------------------------------------------------. ett godtyckligt tecken (utom radbrytningar). [ ] ett av tecknen inom klamrarna. [^ ] ett tecken som inte finns mellan klamrarna. ^ början av en sträng. I radbaserade verktyg, första tecknet på en rad. $ slutet av en sträng eller eller (tecknet före) en radbrytning. * föregående ellement noll eller fler gånger. {n} föregående element n gånger {n,m} föregående element minst n, max m gånger Kommentarer: * är en kortform för {0,} : noll eller flera + är en kortform för {1,} : en eller flera? är en kortform för {0,1} : noll eller ett.* matchar alla strängar Reguljära uttryck : Exempel på användning i Java och POSIX 11. Reguljära uttryck och grammatiker 13/32
Reguljära uttryck med Java java.util.regex boolean b = Pattern.matches("a*b", "aaaaab"); Pattern p = Pattern.compile("a*b"); Matcher m = p.matcher("aaaaab"); boolean b = m.matches(); Reguljära uttryck : Exempel på användning i Java och POSIX 11. Reguljära uttryck och grammatiker 14/32
java.util.scanner Ett agrant brott mot principen om enkelt ansvar. public final class Scanner implements Iterator<String> public Scanner(Readable source) public Scanner(InputStream source) public Scanner(InputStream source, String charsetname) public Scanner(File source) public Scanner(File source, String charsetname) public Scanner(String source) public Scanner(ReadableByteChannel source) public Scanner(ReadableByteChannel source, String charsetname) public void close() public IOException ioexception() public Pattern delimiter() public Scanner usedelimiter(pattern pattern) public Scanner usedelimiter(string pattern) public Locale locale() public Scanner uselocale(locale locale) public int radix() public Scanner useradix(int radix) public MatchResult match() public String tostring() public boolean hasnext() public String next() public void remove() public boolean hasnext(string pattern) public String next(string pattern) public boolean hasnext(pattern pattern) public String next(pattern pattern) public boolean hasnextline() public String nextline() public String findinline(string pattern) Reguljära uttryck : Exempel på användning i Java och POSIX 11. Reguljära uttryck och grammatiker 15/32
java.util.scanner public String findwithinhorizon(string pattern, int horizon) public String findwithinhorizon(pattern pattern, int horizon) public Scanner skip(pattern pattern) public Scanner skip(string pattern) public boolean hasnextboolean() public boolean nextboolean() public boolean hasnextbyte() public boolean hasnextbyte(int radix) public byte nextbyte() public byte nextbyte(int radix) public boolean hasnextshort() public boolean hasnextshort(int radix) public short nextshort() public short nextshort(int radix) public boolean hasnextint() public boolean hasnextint(int radix) public int nextint() public int nextint(int radix) public boolean hasnextlong() public boolean hasnextlong(int radix) public long nextlong() public long nextlong(int radix) public boolean hasnextfloat() public float nextfloat() public boolean hasnextdouble() public double nextdouble() public boolean hasnextbiginteger() public boolean hasnextbiginteger(int radix) public BigInteger nextbiginteger() public BigInteger nextbiginteger(int radix) public boolean hasnextbigdecimal() Reguljära uttryck : Exempel på användning i Java och POSIX 11. Reguljära uttryck och grammatiker 16/32
Grammatik Reguljära uttryck klarar inte av att beskriva mängden av aritmetiska uttryck. 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. Grammatiker 11. Reguljära uttryck och grammatiker 17/32
Grammatik för aritmetiska uttryck Ett uttryck består av en eller era termer separerade av enkla plus- eller minus-tecken. En term består i sin tur av en eller era faktorer separerade av enkla multiplikations- eller divisions- tecken. En faktor är ett tal, en variabel eller ett uttryck inom parenteser. Grammatiker 11. Reguljära uttryck och grammatiker 18/32
BNF-grammatik BackusNaur-form expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= NUMBER NAME '(' expr ')' addop ::= '+' '-' mulop ::= '*' '/' Grammatiker 11. Reguljära uttryck och grammatiker 19/32
Begrepp syntaxsymboler (icke terminalsymboler, nonterminal symbols) N = {expr, term, factor, addop, mulop} slutsymboler, (terminalsymboler, terminal symbols) Σ = {+, -, *, /, (, ), NUMBER, NAME} produktioner, R = {expr ::= term (addop term),...} startsymbol, S = expr G = (N, Σ, R, S) Grammatiker 11. Reguljära uttryck och grammatiker 20/32
Som i Algol 60 Report <expr> ::= <term> (<addop> <term>)* <term> ::= <factor> (<mulop> <factor>)* <factor> ::= NUMBER NAME ( <expr> ) <addop> ::= + - <mulop> ::= * / Exempel Härledning av 1 + x Grammatiker 11. Reguljära uttryck och grammatiker 21/32
Härledning expr term addop term factor addop term NUMBER addop term NUMBER + term NUMBER + factor NUMBER + NAME expr NUMBER + NAME Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 22/32
L[G] Låt G vara en grammatik G = (N, Σ, R, S) Denition Språket som genereras av grammatiken G är L[G] = {w Σ S w} Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 23/32
Härledning för en enkel grammatik expr ::= expr'+'expr expr ::= expr'*'expr expr ::= INT 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 Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 24/32
En annan härledning expr ::= expr'+'expr expr ::= expr'*'expr expr ::= INT 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 expr + expr INT INT INT Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 25/32
Tvetydig grammatik En grammatik är tvetydig om det nns 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. Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 26/32
Syntaxanalys av aritmetiska uttryck expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= ID INT '(' expr ')' addop ::= '+' '-' mulop ::= '*' '/' Härledning av INT + INT * INT. Härledningsträd expr => expr term + term => / \ term + factor * factor => term + term factor + factor * factor => / \ factor + INT * factor => factor factor * factor factor + INT * INT INT + INT * INT INT INT INT Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 27/32
Syntaxanalys av en faktor f a c t o r : : = ID INT ' ( ' e x p r ' ) ' p r i v a t e Expr f a c t o r ( ) { s w i t c h ( t o k e n ) { c a s e S c a n n e r. ID : S t r i n g name = s c a n n e r. t o k e n ( ) ; t o k e n = s c a n n e r. nexttoken ( ) ; r e t u r n new V a r i a b l e ( name ) ; c a s e S c a n n e r. INT : S t r i n g number = s c a n n e r. t o k e n ( ) ; t o k e n = s c a n n e r. nexttoken ( ) ; r e t u r n I n t e g e r. p a r s e I n t ( number ) ; c a s e ' ( ' : t o k e n = s c a n n e r. nexttoken ( ) ; Expr e = e x p r ( ) ; // Check t h a t t o k e n == ') ' t o k e n = s c a n n e r. nexttoken ( ) ; r e t u r n e ; } } Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 28/32
Syntaxanalys av en term term : : = f a c t o r ( mulop f a c t o r ) p r i v a t e Expr term ( ) { Expr r e s u l t, f a c t o r ; r e s u l t = f a c t o r ( ) ; w h i l e ( t o k e n == ' ' t o k e n == ' / ' ) { i n t op = t o k e n ; t o k e n = s c a n n e r. nexttoken ( ) ; f a c t o r = f a c t o r ( ) ; s w i t c h ( op ) { c a s e ' ' : r e s u l t = new Mul ( r e s u l t, f a c t o r ) ; b r e a k ; c a s e ' / ' : r e s u l t = new Div ( r e s u l t, f a c t o r ) ; b r e a k ; } } r e t u r n r e s u l t ; } Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 29/32
Delar av BNF-grammatik för Java CompilationUnit P ackagedeclaration ImportDeclaration T ypedecl ::= [P ackagedecl](importdecl) (T ypedecl) ::= 'package'n ame';' ::= 'import'name ["." '*']';' ::= ClassDecl InterfaceDecl ';' ClassDecl ::= ("abstract" 'nal' "public") CleanClassDecl CleanClassDecl ::= 'class'id["extends" N ame] ["implements" N amelist]classbody ClassBody ::= '{'(ClassBodyDecl) '}'... Name ::= ID("." ID) NameList ::= Name("," Name)... Around 100 nonterminals and 200 rules Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 30/32
Kompilatorer Lexikalanalys - Reguljära uttryck och automater Syntaxanalys - Recursive descent och LR-parsing Semantisk analys - Namn- och typkontroll Interpretering Kodgenerering d v s Bygg en egen kompilator Vertyg: javacc, jastadd, ddd Kursen är valbar. Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 31/32
Sammanfattning Vi har talat om reguljära uttryck grammatiker Nästa föreläsning relationer funktioner laboration 4: syntaxanalys (parsing) Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 32/32