Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksykalnej i TDD w Pythonie

  • 127 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
127
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Aby wąż giętki robił to co wymyśli głowa, czyli słów kilka o analizie leksykalnej i TDD w Pythonie Adam Przybyła <adam.przybyla@gmail.com> (mail i JID) @AdamPrzybyla (Creative Commons CC-by-nd) WrocPY - Wrocław 2013
  • 2. Pliki weryfikowalne - XML ● SAX ● DOM ● PULL ● XSL ● DTD ● YAML
  • 3. Język dziedzinowy - DSL ● Graphviz - DOT ● Yacc ● SQL ● HTML ● VHDL
  • 4. Opis CSV w EBNF CSV file -------file ::= [ header ] { line } header line ::= [ { entry separator } entry ] newline ::= [ { entry separator } entry ] newline entry ::= character+ | { character* " separator " } | " entry newline entry " newline ::= n separator ::= , character ::= a|b|..|A|B|..|0|1|.. escapedQuote ::= ""
  • 5. Flex i Bison ● Flex – analizator leksykalny ● Rozszerzona wersja programu lex ● Generuje tablice przejść ● Parsery LR i LL
  • 6. Gramatyka pliku definicji {definicje} %% {reguły} %% {procedury użytkownika}
  • 7. Plik konfiguracyjny analizatora leksylalnego %% , n rn [^,nr]+ {return COMMA;} {return NEWLINE;} {return NEWLINE;} {return ITEM;}
  • 8. Kod Bisona %token COMMA NEWLINE ITEM %% csv_file : line_list | line_list line; line_list : line_list line newline | line newline | line_list newline | newline; line : line comma | line item | item | comma; comma : COMMA ; newline : NEWLINE;
  • 9. Program wynikowy we Bison static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
  • 10. Problemy analizy ● Shift/Reduce ● Reduce/reduce ● Stany początkowe ● Semantyczne predykaty a[i] (Ruby)
  • 11. Flex z kernelem ● Filtr klasyfikujący ruch w sieci w kernelu ● https://github.com/AdamPrzybyla/layer7-flex ● Kilka razy szybsze rozwiązanie niż oryginalne, oparte o wyrażenia regularne
  • 12. Analizator leksykalny ANTLR ● PCTTS ● Dla leniwych ● Analizator LL(*) ● Przejrzysty kod ● Generacja kodu Java,c#,Python,C++
  • 13. Tryby pracy ANTLR ● Analizator leksykalny ● Tworzenie AST ● Walker AST ● Generowanie plików graphviz ● Przetwarzanie AST ● Język template
  • 14. Przetwarzanie drzew AST ● Kompilator c kiedyś: ● ● C z rozwiniętymi makrami ● Asembler ● ● Źródło w C Plik .o + linkowanie Kompilator C teraz: ● Kolejne modyfikacje drzew AST
  • 15. Przepływ w parserze ANTLR
  • 16. Edytor ANTLRWorks
  • 17. Gramatyka CSV w ANTLR grammar csv; options { language=Python; } file : record (NEWLINE record)* EOF ; record : (quoted_field | unquoted_field) (COMMA (quoted_field | unquoted_field))* ; quoted_field : DQUOTE ( CHAR | COMMA | DQUOTE DQUOTE | NEWLINE)* DQUOTE ; unquoted_field : CHAR* ; CHAR : 'u0000' .. 'u0009' | 'u000b' .. 'u000c' | 'u000e' .. 'u0021' | 'u0023' .. 'u002b' | 'u002d' .. 'uffff' ; COMMA : 'u002c' ; DQUOTE : 'u0022' ; NEWLINE : 'u000d'? 'u000a' | 'u000d' ;
  • 18. Zrozumiały kod (Python) def liczba(self, ): w = None; p = None try: try: # WrocPy.g:9:19: (p= CYFRY ) # WrocPy.g:9:21: p= CYFRY p = self.match(self.input, CYFRY, self.FOLLOW_CYFRY_in_liczba33) if self._state.backtracking == 0: w=p except RecognitionException, re: self.reportError(re) self.recover(self.input, re) finally: pass return w
  • 19. Wywołanie funkcji – jak w ręcznych parserach def mIDS(self, ): try: _type = IDS _channel = DEFAULT_CHANNEL # WrocPy.g:14:4: ( ( 'a' .. 'z' )+ ( '0' .. '9' )* ) # WrocPy.g:14:9: ( 'a' .. 'z' )+ ( '0' .. '9' )* pass # WrocPy.g:14:9: ( 'a' .. 'z' )+ cnt1 = 0 while True: #loop1 alt1 = 2 LA1_0 = self.input.LA(1)
  • 20. Testowanie ● GUnit ● Unittest z Pythona ● Test Driven Development
  • 21. Test ANTLR3 def test_liczba(self): s="1234" w=parserek(s).liczba() self.assertEqual(w.text,s) def test_nie_liczba(self): s="A1234" w=parserek(s).liczba() self.assertFalse(w)
  • 22. Definicja symboli gramatyki grammar WrocPy; options { language=Python; backtrack=true; } @members { def emitErrorMessage(self, msg): pass } liczba returns [w]: p=CYFRY {w=p}; zmienna returns [w]: p=IDS {w=p}; przypisanie returns [w]: p=IDS '=' p1=CYFRY {w=[p,p1]}; IDS: 'a'..'z' + '0'..'9' * ; CYFRY: '0'..'9' + ; WS: .;;
  • 23. Pytania?