Objektorienterad modellering och diskreta strukturer 11. Reguljära uttryck och grammatiker Sven Gestegård Robertz Datavetenskap, LTH 2015 Rekaputilation Vi har talat om I satslogik och härledning I predikatlogik och substitution I mängder och språk I reguljära uttryck Vi kommer att studera I reguljära uttryck och deras begränsning I grammatiker Rekapitulation 11. Reguljära uttryck och grammatiker 2/36 Alfabeten, strängar och språk Ett En alfabet sträng Med ett Rekapitulation är en ändlig icketom mängd symboler . på ett alfabet är en ändlig följd av symboler ur alfabetet. språk på ett alfabet menas en mängd strängar på alfabetet. 11. Reguljära uttryck och grammatiker 3/36 Operationer på språk Konkatenering M M L1 ◦ L2 = L1 L2 = {u ◦ v | u ∈ L1 ∧ v ∈ L2 } Lk : konkateneringen av exakt k strängar ur L M L0 = {} M Lk+1 = L ◦ Lk Kleene-stjärna, hölje ∗ M L = ∞ [ Lk k=0 Rekapitulation 11. Reguljära uttryck och grammatiker 4/36 Exempel (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 i i ab |i≥0 är inte reguljärt Reguljära uttryck : Exempel 11. Reguljära uttryck och grammatiker 10/36 Exempel: Reguljära uttryck och maskiner a ( (bc)*d) | ef* ) accepteras av Det reguljära uttrycket en tillståndsmaskin start q0 b a c q1 q2 q3 b e d q5 d q4 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 11/36 an b n är inte reguljärt Sats För ett reguljärt språk, L, ∀n . an bn ∈ L → ∃m 6= n . am bn ∈ L Bevis. Låt M vara en nit maskin sådan at L(M ) = L, och p vara antal tillstånd i maskinen Då gäller ∀n . an bn ∈ L → ∃k . ak bk ∈ L ∧ k > p Om |ak | > p så måste det nnas en cykel i M som passeras mer än en gång när ak accepteras. Låt j vara längden på cykeln. Då måste även ak+j bk ∈ L. (Ett extra varv i cykeln) Reguljära uttryck : Finita tillståndsmaskiner och reguljära uttryck 11. Reguljära uttryck och grammatiker 12/36 Pumplemmat För ett alfabet Σ gäller ∀L ⊆ Σ∗ . Regular(L) → ∃p ≥ 1 . ∀w ∈ L . |w| ≥ p → ∃x, y, z ∈ Σ∗ . w = xyz ∧ |y| ≥ 1 ∧ |xy| ≤ p∧ ∀i ≥ 0 . xy i z ∈ L →, nödvändigt men ej tillräckligt villkor, omvändningen gäller inte för en sträng w, |w| = p ... y start q0 ... x Reguljära uttryck : Finita tillståndsmaskiner och reguljära uttryck q ... qp z 11. Reguljära uttryck och grammatiker 13/36 Pumplemmat, bevisskiss 1 2 3 4 5 6 För varje reguljärt språk nns det en nit tillståndsmaskin (FSA) som accepterar språket Låt p vara antalet tillstånd i en sådan maskin För en sträng, w, sådan att |w| = p, låt q0 vara starttillståndet och q1 , . . . , qp vara tillstånden som passeras när w accepteras. Eftersom maskinen endast har p tillstånd måste det i denna följd av p + 1 tillstånd nnas något tillstånd som förekommer mer än en gång. Låt q vara ett sådant tillstånd. Tillståndsöverångarna som tar maskinen från första gången den är i q till nästa gång q passeras utgör någon sträng. Kalla den y . Maskinen kommer att acceptera en sträng som inte innehåller y som delsträng, och strängar som har y , upprepad ett godtyckligt antal gånger, som delsträng. Reguljära uttryck : Finita tillståndsmaskiner och reguljära uttryck 11. Reguljära uttryck och grammatiker 14/36 Reguljära uttryck: Utvidgad notation M DIGIT = [0 − 9] M NAT = DIGIT+ M INT = (−)?NAT M FLOAT = INT . NAT Namn får inte användas rekursivt. Reguljära uttryck : Finita tillståndsmaskiner och reguljära uttryck 11. Reguljära uttryck och grammatiker 15/36 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 -----. [ ] [^ ] ^ $ * {n} {n,m} 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. föregående element n gånger 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 16/36 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 17/36 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 18/36 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 Reguljära uttryck ExempelhasNextBigDecimal() på användning i Java och POSIX 11. Reguljära uttryck och grammatiker 19/36 Grammatik Reguljära uttryck klarar inte av att beskriva t ex. 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 20/36 Grammatik för S T T U an bn ::= T ::= {} ::= U := 'a' T 'b' Grammatiken kan skrivas kompaktare (men kanske inte läsbarare), tex: S ::= 'a' S 'b' | {} där {} beteckar tomma strängen Exempel: härledning av strängen aaabbb S ⇒ T ⇒ U ⇒ 'a' T 'b' ⇒ 'a' U 'b' ⇒ 'a' 'a' T 'b' 'b' ⇒ 'a' 'a' U 'b' 'b' ⇒ 'a' 'a' 'a' T 'b' 'b' 'b' ⇒ 'a' 'a' 'a' 'b' 'b' 'b' Grammatiker 11. Reguljära uttryck och grammatiker 21/36 Grammatik för aritmetiska uttryck I Ett uttryck består av en eller era plus- eller minus-tecken. I En term består i sin tur av en eller era faktorer separerade av enkla multiplikations- eller divisions- tecken. I En faktor är ett parenteser. Grammatiker , en tal variabel termer eller ett separerade av enkla uttryck inom 11. Reguljära uttryck och grammatiker 22/36 BNF-grammatik BackusNaur-form expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= NUMBER | NAME | '(' expr ')' addop ::= '+' | '-' mulop ::= '*' | '/' M G = (N, Σ, R, S) Grammatiker 11. Reguljära uttryck och grammatiker 23/36 Begrepp syntaxsymboler (icke terminalsymboler, nonterminal symbols) M N = {expr, term, factor, addop, mulop} slutsymboler, (terminalsymboler, terminal symbols) M Σ = {+, -, *, /, (, ), NUMBER, NAME} produktioner, R = {expr ::= term (addop term)∗, . . .} startsymbol, M S = expr M G = (N, Σ, R, S) Grammatiker 11. Reguljära uttryck och grammatiker 24/36 Som i Algol 60 Report Markera icketerminalsymboler (med < >) i stället för terminalsymboler. <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 25/36 Härledning expr ⇒ term addop term ⇒ factor addop term ⇒ NUMBER addop term ⇒ NUMBER addop term ⇒ NUMBER + term ⇒ NUMBER + factor ⇒ NUMBER + NAME expr Grammatiker : Härledning och syntaxanalys ⇒∗ NUMBER + NAME 11. Reguljära uttryck och grammatiker 26/36 L[G] Låt G vara en grammatik M G = (N, Σ, R, S) Denition Språket som genereras av grammatiken G är M L[G] = {w ∈ Σ∗ | S ⇒∗ w} Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 27/36 Härledning för en enkel grammatik expr ::= expr'+'expr expr ::= expr'*'expr expr ::= IN T Härledning av INT + INT * INT. expr => expr + expr => expr + expr * expr => INT + expr * expr => INT + INT * expr => INT + INT * INT Grammatiker : Härledning och syntaxanalys Härledningsträd expr / | \ expr + expr | / | \ INT expr * expr | | INT INT 11. Reguljära uttryck och grammatiker 28/36 En annan härledning expr ::= expr'+'expr expr ::= expr'*'expr expr ::= IN T Härledning av INT + INT * INT. expr => expr * expr => expr + expr * expr => INT + expr * expr => INT + INT * expr => INT + INT * INT Grammatiker : Härledning och syntaxanalys Härledningsträd expr / | \ expr * expr / | \ | expr + expr INT | | INT INT 11. Reguljära uttryck och grammatiker 29/36 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 30/36 Syntaxanalys av aritmetiska uttryck expr ::= term (addop term)* term ::= factor (mulop factor)* factor ::= ID | INT | '(' expr ')' addop ::= '+' | '-' mulop ::= '*' | '/' Härledning av INT + INT * INT. expr => term + term => term + factor * factor => factor + factor * factor => factor + INT * factor => factor + INT * INT INT + INT * INT Grammatiker : Härledning och syntaxanalys Härledningsträd expr / | \ term + term | / | \ factor factor * factor | | | INT INT INT 11. Reguljära uttryck och grammatiker 31/36 Syntaxanalys av en faktor f a c t o r : : = ID | INT | private Expr switch factor () ( token ) case : name = = token new V a r i a b l e ( name ) ; number = return '( ' : = scanner . token ( ) ; s c a n n e r . nextToken ( ) ; I n t e g e r . p a r s e I n t ( number ) ; : token Expr scanner . token ( ) ; s c a n n e r . nextToken ( ) ; S c a n n e r . INT String case { S c a n n e r . ID return case ') ' { String token '( ' expr = e token return s c a n n e r . nextToken ( ) ; = = expr ( ) ; // Check that t o k e n == ') ' s c a n n e r . nextToken ( ) ; e ; } } Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 32/36 Syntaxanalys av en term term : : = f a c t o r ( mulop f a c t o r ) ∗ private Expr Expr term ( ) result , result while = factor (); ( token int { factor ; op token factor switch = = == ' ∗' || token == '/ ') { token ; s c a n n e r . nextToken ( ) ; = factor (); ( op ) case ' ∗' { : result = new Mul ( r e s u l t , factor ); = new Div ( r e s u l t , factor ); break ; case '/ ' : result break ; } } return result ; } Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 33/36 Delar av BNF-grammatik för Java CompilationU nit ::= [P ackageDecl](ImportDecl)∗ (T ypeDecl)∗ P ackageDeclaration ::= 'package'N ame';' ImportDeclaration ::= 'import'N ame ["." '*']';' T ypeDecl ::= ClassDecl | Interf aceDecl | ';' ClassDecl ::= ("abstract" | 'nal' | "public")∗ CleanClassDecl CleanClassDecl ::= 'class'ID["extends" N ame] ClassBody ::= '{'(ClassBodyDecl)∗ '}' N ame ::= ID("." ID)∗ N ameList ::= N ame("," N ame)∗ ["implements" N ameList]ClassBody ... ... Around 100 nonterminals and 200 rules Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 34/36 Kompilatorer I Lexikalanalys - Reguljära uttryck och automater I Syntaxanalys - Recursive descent och LR-parsing I Semantisk analys - Namn- och typkontroll I Interpretering I Kodgenerering I d v s Bygg en egen kompilator I Vertyg: javacc, jastadd, ddd Kursen är valbar. Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 35/36 Sammanfattning Vi har talat om I reguljära uttryck I grammatiker Nästa föreläsning I relationer I funktioner I laboration 3: syntaxanalys (parsing) Grammatiker : Härledning och syntaxanalys 11. Reguljära uttryck och grammatiker 36/36
© Copyright 2024