Successfully reported this slideshow.
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.pr...
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
::=...
Flex i Bison
●

Flex – analizator leksykalny

●

Rozszerzona wersja programu lex

●

Generuje tablice przejść

●

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

{return COMMA;}
{return NEWLINE;}
{return NEWLINE;}
{retur...
Kod Bisona
%token COMMA NEWLINE ITEM

%%
csv_file : line_list | line_list line;
line_list : line_list line newline | line ...
Program wynikowy we Bison
static const yytype_uint8 yytranslate[] =
{
0,

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 ra...
Analizator leksykalny ANTLR
●

PCTTS

●

Dla leniwych

●

Analizator LL(*)

●

Przejrzysty kod

●

Generacja kodu Java,c#,...
Tryby pracy ANTLR
●

Analizator leksykalny

●

Tworzenie AST

●

Walker AST

●

Generowanie plików graphviz

●

Przetwarza...
Przetwarzanie drzew AST
●

Kompilator c kiedyś:
●

●

C z rozwiniętymi makrami

●

Asembler

●

●

Źródło w C

Plik .o + l...
Przepływ w parserze ANTLR
Edytor ANTLRWorks
Gramatyka CSV w ANTLR
grammar csv;
options {

language=Python; }

file : record (NEWLINE record)* EOF ;
record : (quoted_f...
Zrozumiały kod (Python)
def liczba(self, ):
w = None; p = None
try:
try:
# WrocPy.g:9:19: (p= CYFRY )

# WrocPy.g:9:21: p=...
Wywołanie funkcji – jak w
ręcznych parserach
def mIDS(self, ):
try:
_type = IDS
_channel = DEFAULT_CHANNEL
# WrocPy.g:14:4...
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...
Definicja symboli gramatyki
grammar WrocPy;
options { language=Python; backtrack=true; }
@members {
def emitErrorMessage(s...
Pytania?
Upcoming SlideShare
Loading in …5
×

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

466 views

Published on

Published in: Technology
  • Be the first to comment

  • Be the first to like this

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

  1. 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. 2. Pliki weryfikowalne - XML ● SAX ● DOM ● PULL ● XSL ● DTD ● YAML
  3. 3. Język dziedzinowy - DSL ● Graphviz - DOT ● Yacc ● SQL ● HTML ● VHDL
  4. 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. 5. Flex i Bison ● Flex – analizator leksykalny ● Rozszerzona wersja programu lex ● Generuje tablice przejść ● Parsery LR i LL
  6. 6. Gramatyka pliku definicji {definicje} %% {reguły} %% {procedury użytkownika}
  7. 7. Plik konfiguracyjny analizatora leksylalnego %% , n rn [^,nr]+ {return COMMA;} {return NEWLINE;} {return NEWLINE;} {return ITEM;}
  8. 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. 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. 10. Problemy analizy ● Shift/Reduce ● Reduce/reduce ● Stany początkowe ● Semantyczne predykaty a[i] (Ruby)
  11. 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. 12. Analizator leksykalny ANTLR ● PCTTS ● Dla leniwych ● Analizator LL(*) ● Przejrzysty kod ● Generacja kodu Java,c#,Python,C++
  13. 13. Tryby pracy ANTLR ● Analizator leksykalny ● Tworzenie AST ● Walker AST ● Generowanie plików graphviz ● Przetwarzanie AST ● Język template
  14. 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. 15. Przepływ w parserze ANTLR
  16. 16. Edytor ANTLRWorks
  17. 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. 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. 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. 20. Testowanie ● GUnit ● Unittest z Pythona ● Test Driven Development
  21. 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. 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. 23. Pytania?

×