SlideShare uma empresa Scribd logo
1 de 23
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
Pliki weryfikowalne - XML
●

SAX

●

DOM

●

PULL

●

XSL

●

DTD

●

YAML
Język dziedzinowy - DSL
●

Graphviz - DOT

●

Yacc

●

SQL

●

HTML

●

VHDL
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 ::= ""
Flex i Bison
●

Flex – analizator leksykalny

●

Rozszerzona wersja programu lex

●

Generuje tablice przejść

●

Parsery LR i LL
Gramatyka pliku definicji
{definicje}
%%
{reguły}
%%
{procedury użytkownika}
Plik konfiguracyjny analizatora
leksylalnego
%%
,
n
rn
[^,nr]+

{return COMMA;}
{return NEWLINE;}
{return NEWLINE;}
{return ITEM;}
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;
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,
Problemy analizy
●

Shift/Reduce

●

Reduce/reduce

●

Stany początkowe

●

Semantyczne predykaty a[i] (Ruby)
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
Analizator leksykalny ANTLR
●

PCTTS

●

Dla leniwych

●

Analizator LL(*)

●

Przejrzysty kod

●

Generacja kodu Java,c#,Python,C++
Tryby pracy ANTLR
●

Analizator leksykalny

●

Tworzenie AST

●

Walker AST

●

Generowanie plików graphviz

●

Przetwarzanie AST

●

Język template
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
Przepływ w parserze ANTLR
Edytor ANTLRWorks
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' ;
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
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)
Testowanie
●

GUnit

●

Unittest z Pythona

●

Test Driven Development
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)
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:
.;;
Pytania?

Mais conteúdo relacionado

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

100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. 100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. Redge Technologies
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Wojciech Szymański
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Semihalf
 
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Semihalf
 
Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Semihalf
 
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018Semihalf
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?Brainhub
 
Python szybki start
Python   szybki startPython   szybki start
Python szybki startSages
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logówDivante
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPROIDEA
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Semihalf
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegroallegro.tech
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPLaravel Poland MeetUp
 
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016PROIDEA
 
Wirtualizacja urządzeń PCI (SR-IOV).
Wirtualizacja urządzeń PCI (SR-IOV).Wirtualizacja urządzeń PCI (SR-IOV).
Wirtualizacja urządzeń PCI (SR-IOV).Semihalf
 
Interfejs RS232C
Interfejs RS232CInterfejs RS232C
Interfejs RS232Crlutowsk
 

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

DSL - DYI
DSL - DYIDSL - DYI
DSL - DYI
 
100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego. 100 M pakietów na sekundę dla każdego.
100 M pakietów na sekundę dla każdego.
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.
 
Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.Hierarchia pamięci w systemach komputerowych.
Hierarchia pamięci w systemach komputerowych.
 
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
Masz wiadomość! Komunikacja wieloprocesorowa w praktyce.
 
Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.Architektura mikrokontrolera pisana słowem.
Architektura mikrokontrolera pisana słowem.
 
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018
Programuj wbrew regułom - Bug Legends Quiz Show. Semihalf Barcamp 25/04/2018
 
tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?tRPC - czy to koniec GraphQL?
tRPC - czy to koniec GraphQL?
 
Python szybki start
Python   szybki startPython   szybki start
Python szybki start
 
Agregacja i analiza logów
Agregacja i analiza logówAgregacja i analiza logów
Agregacja i analiza logów
 
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOpsPLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
PLNOG 22 - Krzysztof Załęski - Praktyczne zastosowanie narzędzi NetDevOps
 
Cw1 ir dod2
Cw1 ir dod2Cw1 ir dod2
Cw1 ir dod2
 
Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.Stosy sieciowe w przestrzeni użytkownika.
Stosy sieciowe w przestrzeni użytkownika.
 
Monitoring sieci
Monitoring sieciMonitoring sieci
Monitoring sieci
 
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
[WHUG] Wielki brat patrzy - czyli jak zbieramy dane o użytkownikach allegro
 
Automatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHPAutomatyzacja utrzymania jakości w środowisku PHP
Automatyzacja utrzymania jakości w środowisku PHP
 
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016
Konrad Kokosa - Pamięć w .NET - od ogólu do szczegółu- 4developers2016
 
EXADATA - Infrastruktura Przyszłości
EXADATA - Infrastruktura PrzyszłościEXADATA - Infrastruktura Przyszłości
EXADATA - Infrastruktura Przyszłości
 
Wirtualizacja urządzeń PCI (SR-IOV).
Wirtualizacja urządzeń PCI (SR-IOV).Wirtualizacja urządzeń PCI (SR-IOV).
Wirtualizacja urządzeń PCI (SR-IOV).
 
Interfejs RS232C
Interfejs RS232CInterfejs RS232C
Interfejs RS232C
 

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

  • 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
  • 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,
  • 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
  • 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)
  • 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: .;;