[21:01] <@Gynvael>: ok ;> zaczynamy
[21:01] <@Gynvael>: ;>
[21:02] <@Gynvael>: witam wszystkich licznie zgromadzonych na 11nastej czesci wykladow z podstaw C
[21:02] <@Gynvael>: chociaz w sumie wiekszosc podstaw juz za nami
[21:02] <@Gynvael>: i zaczyna sie to co IMHO jest ciekawe ;>
[21:02] <@Gynvael>: czyli wykorzystywanie podstaw do pisania jakiegos tam bardziej uzytecznego stuffu
[21:02] <@Gynvael>: dzisiaj bedzie o parserkach
[21:03] <@Gynvael>: co to jest parser ? wiki (angielskie) jak go zapytalem powiedzialo mi cos takiego
[21:03] <@Gynvael>: "Parsing is the process of splitting up a continuous stream of characters (read from a file or keyboard input, for example) into meaningful tokens, and then building a parse tree from those tokens. The name is by analogy with the usage in grammar and linguistics."
[21:03] <@Gynvael>: czyli...
[21:03] <@Gynvael>: W wolnym tlumaczeniu oznacza to mniej wiecej: "Parsing jest czynnoscia polegajaca na rozbijaniu nieprzerwanego strumienia znakow (wczytanego z pliku badz klawiatury, na przyklad) na znaczace czesci, a nastepnie zbudowanie drzewa z tych czesci. Nazwa zostala wzieta z analogicznej czynnosci stosowanej w gramatyce i jezykoznastwie.".
[21:04] <@Gynvael>: slowiniki.onet.pl twierdza natomiast ze
[21:04] <@Gynvael>: parse (Ectaco-Poland)
[21:04] <@Gynvael>: v,
[21:04] <@Gynvael>: 1 analizowac
[21:04] <@Gynvael>: 2 rozbior
[21:04] <@Gynvael>: 3 zrobic rozbior zdania
[21:04] <@Gynvael>: ok.. fajne definicje.. ale po co to komu ;>
[21:04] <@Gynvael>: wiec..
[21:04] <@Gynvael>: zalozmy taka teoretyczna sytuacje
[21:04] <@Gynvael>: piszemy gierke..
[21:04] <@Gynvael>: gra ma jakies tam opcje.. jak to gry maja ;>
[21:05] <@Gynvael>: rozdzielczosc, glosnosc, jasnosc obrazu, etc ;>
[21:05] <@Gynvael>: i ma swoj config
[21:05] <@Gynvael>: niektore gry maja konfigi w postaci plikow .ini
[21:05] <@Gynvael>: ktore to maja forme:
[21:05] <@Gynvael>: [sekcja]
[21:05] <@Gynvael>: nazwa = wartosc
[21:05] <@Gynvael>: przykladowo:
[21:05] <@Gynvael>: [dzwiek]
[21:05] <@Gynvael>: glosnosc=90%
[21:05] <@Gynvael>: muzyka=tak
[21:05] <@Gynvael>: odglosy_przyrody=nie
[21:05] <@Gynvael>: [grafika]
[21:05] <@Gynvael>: rozdzielczosc=800x600
[21:05] <@Gynvael>: glebia_kolorow=32
[21:06] <@Gynvael>: i teraz, gra sobie przy uruchomieniu ten config wczytuje
[21:06] <@Gynvael>: czesc gry, ktora jest odpowiedzialna
[21:06] <@Gynvael>: za analize, tzn przerobienie tego czytelnego dla nas textu, na cos czytelne dla komputera/programu/programisty
[21:06] <@Gynvael>: nazywa sie wlasnie parserem
[21:07] <@Gynvael>: nei jest to jedyne zastosowanie parserow
[21:07] <@Gynvael>: innym moze byc na przyklad kompilator jakiegos jezyka programowania
[21:07] <@Gynvael>: powiedzmy takiego C ;>
[21:07] <@Gynvael>: printf("ala ma kota %s", "nyo");
[21:08] <@Gynvael>: nam cos to mowi, procesorowi zupelnie nic
[21:08] <@Gynvael>: wiec przed wogole proba skompilowania czegokolwiek
[21:08] <@Gynvael>: musi to najpierw zostac sparsowane/przeanalizowane
[21:08] <@Gynvael>: (podzielone na tokeny, etc)
[21:08] <@Gynvael>: innym przykladem moze byc HTML albo XML
[21:08] <@Gynvael>: ala ma kota
[21:09] <@Gynvael>: zanim przegladarka bedzie wiedziec ze to ma byc pogrubione, musi to sobei sparsowac i to zrozumiec ;>
[21:09] <@Gynvael>: a jeszcze innym przykladem, moze byc np protokol IRCa (ktory jest textowy chciec neichciec) ;>
[21:10] <@Gynvael>: zarowno servery jak i programy klienckie irca (te ktore wlasnie uzywacie) w tle niezauwazalnie dla nikogo sobie parsuja to co dostaja od serva
[21:10] <@Gynvael>: zeby wmiare ladnie wam to wyswietlic
[21:10] <@Gynvael>: ;>
[21:10] <@Gynvael>: parserow wszedzie jest full i jeszcze troche ;>
[21:10] <@Gynvael>: wiec wypadalo by je choc troche umiec pisac ;>
[21:10] <@Gynvael>: zacznijmy od prostych plikow konfiguracyjnych
[21:11] <@Gynvael>: http://gynvael.lunarii.org/temp/simple.cfg
[21:11] <@Gynvael>: o tego typu
[21:11] <@Gynvael>: jak widac mamy tam cos takiego:
[21:11] <@Gynvael>: ala = ma kota
[21:11] <@Gynvael>: kot = ma ale
[21:11] <@Gynvael>: (w sumie to ze ala ma kota wiecie juz z poprzednich wykladow, ale nvm)
[21:12] <@Gynvael>: ^^
[21:12] <@Gynvael>: teraz tak
[21:12] <@Gynvael>: najpierw wprowadze pojecie tokenow ;>
[21:12] <@Gynvael>: token to w sumie nierozdzielna czesc napisu
[21:12] <@Gynvael>: czyli cos co dla kompa moze juz cos znaczyc
[21:12] <@Gynvael>: przykladowo tam sa 3 tokeny ;>
[21:12] <@Gynvael>: "ala" to nazwa
[21:13] <@Gynvael>: "=" oznacza "koneic nazwy, zaczyna sie wartosc"
[21:13] <@Gynvael>: a "ma kota" to wartosc ;>
[21:13] <@Gynvael>: dla programisty powyzszy napis
[21:13] <@Gynvael>: czyli
[21:13] <@Gynvael>: "ala = ma kota"
[21:13] <@Gynvael>: powinien zostac rozlozony na nastepujace pola/tokeny
[21:14] <@Gynvael>: wazne elementy, te ktore nalezy zapamietac, bede oznaczal nawiasami ostrymi < >
[21:14] <@Gynvael>: a te ktore nalezy pominac [ ]
[21:14] <@Gynvael>: wiec tak
[21:14] <@Gynvael>: "[whitespace][whitespace]=[whitespace]"
[21:15] <@Gynvael>: hehe ja loguje, spoko ;>
[21:15] <@Gynvael>: whitespace to SPACJA badz TAB
[21:15] <@Gynvael>: czyli jakis odstep
[21:15] <@Gynvael>: ktory mogl by tam byc np dla przejrzystosci wrzucony
[21:15] <@Gynvael>: nazwa to nazwa
[21:15] <@Gynvael>: potem jest =, ktore po prostu musi tam byc
[21:15] <@Gynvael>: jak widac miedzy nazwa a = moga byc jakies odstepy
[21:16] <@Gynvael>: tak samo miedzy = a wartoscia
[21:16] <@Gynvael>: to co wyzej podaje to jest umowny zarowno zapis
[21:16] <@Gynvael>: jak i definicje ;>
[21:16] <@Gynvael>: zalezne od przykladu ;>
[21:16] <@Gynvael>: ok
[21:16] <@Gynvael>: czyli wiemy z czym mamy do czyniena
[21:16] <@Gynvael>: teraz mozemy pomyslec nad jakas funkcja z libc ktora sie do tego nada
[21:17] <@Gynvael>: odrazu podpowiem ze *scanf jest do tego odpowiednie
[21:17] <@Gynvael>: o scanf bylo juz poprzednio pare razy, wiec sie w ta rodzine funkcji nie bede zaglebial
[21:17] <@Gynvael>: zrobmy narazie prosty przyklad ktory po prostu odczyta wszystkie poprawne pola (poprawne pole to takie ktore wyglada jak wyzej)
[21:17] <@Gynvael>: i wypisze je w jakiejs innej formie na ekran
[21:19] <@Gynvael>: http://gynvael.vexillium.org/simple.c
[21:19] <@Gynvael>: http://gynvael.vexillium.org/simple.cfg
[21:19] <@Gynvael>: te dwa pliki powinny byc w tym samym katalogu
[21:19] <@Gynvael>: kompilujemy i odpalamy
[21:20] <@Gynvael>: ok
[21:21] <@Gynvael>: rzucmy okiem jak tam program dziala
[21:21] <@Gynvael>: najpierw jest standardowe otwarcie pliku tekstowego do odczytu
[21:21] <@Gynvael>: cfg = fopen("simple.cfg", "r");
[21:21] <@Gynvael>: if(cfg == NULL)
[21:21] <@Gynvael>: etc
[21:22] <@Gynvael>: ehehehe nie narzekaj ;>
[21:22] <@Gynvael>: polecam dos2unix ;>
[21:22] <@Gynvael>: ok
[21:22] <@Gynvael>: nowa funkcja moze byc perror
[21:22] <@Gynvael>: perror pobiera ostatni kod bledu (zmienna globalna errno, standardowo w clibie jest)
[21:23] <@Gynvael>: i wypisuje text o bledzie w tej postaci
[21:23] <@Gynvael>: argument_perror: text bledu
[21:23] <@Gynvael>: przykladowo gdyby usunac simple.cfg z tego katalogu
[21:23] <@Gynvael>: perror("simple.cfg") wygeneruje nastepujacy napis
[21:23] <@Gynvael>: 21:24:47 LiTeStEp >simple
[21:23] <@Gynvael>: simple.cfg: No such file or directory
[21:24] <@Gynvael>: ok
[21:24] <@Gynvael>: wiec otwieramy plik (cfg)
[21:24] <@Gynvael>: sprawdzamy czy sie dobrze otworzyl
[21:24] <@Gynvael>: jesli nei to wychodzimy z programu
[21:24] <@Gynvael>: nastepnie jest petla nieskonczona while(1)
[21:24] <@Gynvael>: a w niej:
[21:24] <@Gynvael>: ret = fscanf(cfg, "%64s = %64[^\n]", name, value);
[21:25] <@Gynvael>: fscanf jest funkcja analogiczna do scanf, tyle ze zamiast z stdin, to wczytuje string z pliku
[21:25] <@Gynvael>: zwraca ilosc poprawnie odczytanych pol, czyli tak jak scanf
[21:26] <@Gynvael>: teraz tak
[21:26] <@Gynvael>: cfg to plik oczywiscie
[21:26] <@Gynvael>: "%64s = %64[^\n]" to scanfowy zapis "[whitespace][whitespace]=[whitespace]"
[21:26] <@Gynvael>: scanf pomija sam wszelkie spacje
[21:27] <@Gynvael>: przynajmniej te z poczatku ;>
[21:27] <@Gynvael>: kazda inna spacja jest traktowana jako "jedna lub wiecej spacji"
[21:27] <@Gynvael>: czyli w sumie wymusilem tutaj spacje miedzy nazwa a = a wartoscia ;>
[21:28] <@Gynvael>: %64s to wczytanie nazwy
[21:28] <@Gynvael>: 64 to oznaczenie ze ma byc wczytane MAXYMALNIE 64 znaki
[21:28] <@Gynvael>: takie zabespieczenie anty haxxorskie ;>
[21:28] <@Gynvael>: potem = ktore musi byc
[21:28] <@Gynvael>: a potem %64[^\n] czyli wczytanie do stringa wszystkiego co nie jest koncem linii
[21:28] <@Gynvael>: ale nie wiecej niz 64 znaki
[21:29] <@Gynvael>: %s przerywa wczytywanie po napotkaniu na whitespace ;>
[21:29] <@Gynvael>: natomiast %[^\n] przerywa dopiero po dojechaniu do konca linii
[21:30] <@Gynvael>: niom
[21:30] <@Gynvael>: czyli to wczytuje 2 pola
[21:30] <@Gynvael>: miedzy ktorymi jest " = "
[21:30] <@Gynvael>: z tym ze drugie pole moze zawierac spacje
[21:30] <@Gynvael>: po tym mamy dwa sprawdzenia
[21:31] <@Gynvael>: czy fscanf napotkal na koniec pliku
[21:31] <@Gynvael>: i czy udalo sie odczytac poprawna ilosc pol (czyli pominiecie niepoprawnych linii)
[21:31] <@Gynvael>: a na koncu wypisanei printfem tego co wczytalismy
[21:32] <@Gynvael>: potem jest zamkniecie i koniec
[21:32] <@Gynvael>: jak widac ten przyklad jest niedoskonaly ;> poniewaz wymusza przynajmniej jeden whitespace miedzy wartoscia a = a nazwa
[21:32] <@Gynvael>: jak by zrobic zeby nie trzeba dawac tam spacji ?
[21:32] <@Gynvael>: metod jest pare
[21:33] <@Gynvael>: 1) zamiast jednego fscanf, zrobic wczytanie linii do buforka
[21:33] <@Gynvael>: i korzystajac z sscanf i tego co zwraca ustalic czy tam jest "= " " = " czy moze "=" albo " =" ;>
[21:33] <@Gynvael>: natomiast to jest ofc srednia metoda
[21:34] <@Gynvael>: ew mozna zrobic inaczej
[21:35] <@Gynvael>: mianowicie nie korzystac z fscanf
[21:35] <@Gynvael>: tylko najpierw wczytac calosc do buforka
[21:35] <@Gynvael>: po czym:
[21:35] <@Gynvael>: zrobic wszystko recznie
[21:35] <@Gynvael>: 1) ominac poczatkowe spacje
[21:35] <@Gynvael>: 2) wczytac nazwe (np za pomoca wlasnie sscanf)
[21:35] <@Gynvael>: 3) ominac spacje jesli sa jakeis
[21:35] <@Gynvael>: 4) sprawdzic czy natknelismy sie na =
[21:35] <@Gynvael>: 5) ominac spacje...
[21:36] <@Gynvael>: 6) i wczytac wartosc
[21:36] <@Gynvael>: ok
[21:36] <@Gynvael>: jak widac pare razy uzylismy omijania spacji
[21:36] <@Gynvael>: wypadalo by siec zrobic funkcje ktora to robi
[21:37] <@Gynvael>: ofc nalezy pamietac ze jako spacje, chodzi nam o ' ' oraz '\t'
[21:37] <@Gynvael>: lor na priva napisz co chcesz ;>
[21:37] <@Gynvael>: kk ? ;>
[21:37] <@Gynvael>: bedzie latwiej
[21:37] <@Gynvael>: ;>>
[21:37] <@Gynvael>: ok
[21:37] <@Gynvael>: funkcja omijajaca wyglada tak:
[21:37] <@Gynvael>: char *skip_whitespace(char *what) {
[21:38] <@Gynvael>: while(*what = ' ' || *what = '\t') what++;
[21:38] <@Gynvael>: return what;
[21:38] <@Gynvael>: }
[21:38] <@Gynvael>: czyli po prostu funkcja przesuwa wskaznik
[21:38] <@Gynvael>: do poki nie ominie wszystkich spacji ;>
[21:38] <@Gynvael>: jesli nie bylo zadnych spacji, to nic nie omija
[21:38] <@Gynvael>: e
[21:38] <@Gynvael>: ant_: ma racje ;>
[21:38] <@Gynvael>: nie = tylko ==
[21:38] <@Gynvael>: ;>
[21:39] <@Gynvael>: a
[21:39] <@Gynvael>: ktos mnie jeszcze poprawil na privie
[21:39] <@Gynvael>: ;>
[21:39] <@Gynvael>: w razie gdy *what natrafi na '\0'
[21:39] <@Gynvael>: powinien przerwac
[21:39] <@Gynvael>: wiec || *what == '\0'
[21:39] <@Gynvael>: i juz komplet ;>
[21:39] <@Gynvael>: e
[21:39] <@Gynvael>: ...
[21:40] <@Gynvael>: nie
[21:40] <@Gynvael>: w8
[21:40] <@Gynvael>: zadnego *what == '\0' nie moze byc --;
[21:40] <@Gynvael>: eh zamieszaliscie mnie --;
[21:40] <@Gynvael>: char *skip_whitespace(char* what)
[21:40] <@Gynvael>: { while(*what == ' ' || *what == '\t') what++; return what;
[21:40] <@Gynvael>: }
[21:41] <@Gynvael>: funkcja powinna wygladac tak ;>
[21:41] <@Gynvael>: czyli
[21:41] <@Gynvael>: dopoki what wskazuje na spacje badz tab, wtedy przesuwamy what
[21:41] <@Gynvael>: ktos mi zarzuca na privie ze funkcja zaklada ze sa spacje
[21:41] <@Gynvael>: szczerze to nei wiem czemu miala by tak zakladac
[21:41] <@Gynvael>: zalozmy ze nie ma spacji
[21:41] <@Gynvael>: wtedy warunek nie jest spelniony
[21:41] <@Gynvael>: wiec what sie nie przesuwa
[21:41] <@Gynvael>: wiec nic sie nei dzieje
[21:42] <@Gynvael>: natomiast jesli natrafi na \0, to warunek tez nie jest spelniony
[21:42] <@Gynvael>: wiec petla sie skonczy
[21:42] <@Gynvael>: teraz tak
[21:42] <@Gynvael>: ok mamy funkcje do omijania spacji
[21:43] <@Gynvael>: teraz wczytywanie pol
[21:43] <@Gynvael>: mozemy do tego uzyc po prostu scanf
[21:43] <@Gynvael>: prawdopodobnie mozemy wtedy uzyc %n do wczytania dlugosci pola
[21:44] <@Gynvael>: czyli
[21:44] <@Gynvael>: sscanf(pointer, "%s%n", name, &wielkosc); pointer+=wielkosc;
[21:44] <@Gynvael>: ofc %64s bedzie lepsze
[21:44] <@Gynvael>: potem znowu omijanie spacji
[21:45] <@Gynvael>: sprawdzenie czy pointer wskazuje na =
[21:45] <@Gynvael>: if(*pointer != '=') continue;
[21:45] <@Gynvael>: pointer++;
[21:45] <@Gynvael>: ominiecie spacji
[21:45] <@Gynvael>: i wczytanie wartosci
[21:45] <@Gynvael>: tyle
[21:45] <@Gynvael>: teraz jak to wyglada w praktyce:
[21:48] <@Gynvael>: w8 zaraz wrzuce przyklad na serv-- lagi..
[21:50] <@Gynvael>: o
[21:50] <@Gynvael>: wrzucilo sie ;>
[21:50] <@Gynvael>: http://gynvael.vexillium.org/simple_b.c
[21:51] <@Gynvael>: nie wiem czy wspominalem o %n
[21:51] <@Gynvael>: %n wrzuca ilosc wczytanych do tej pory znakow do zmiennej do ktorej poda sie pointer
[21:51] <@Gynvael>: czyli jesli mamy "%s%n" i %s wczyta 10 znakow
[21:51] <@Gynvael>: to %n ustawi wartosc zmiennej na 10
[21:52] <@Gynvael>: http://gynvael.lunarii.org/temp/simple_b.c
[21:52] <@Gynvael>: jak by ktos nie mogl z tamtego sciagnac
[21:52] <@Gynvael>: ok
[21:52] <@Gynvael>: tyle wstepu
[21:52] <@Gynvael>: za chwile bedzie kapka algorytmow czyli bardzo prosta kolejka
[21:52] <@Gynvael>: a potem zrobimy sobie prosty(prymitywny) jezyk skryptowy
[21:52] <@Gynvael>: ;>
[21:53] <@Gynvael>: pytanka ?
[21:53] d0ubl3_j: tak
[21:53] ant_: nein
[21:53] phoenix: ta
[21:53] G0blin: hmmmm
[21:53] d0ubl3_j: moge zaopiekowac sie ala po wykladach?:p
[21:53] phoenix: tylko moent'
[21:53] phoenix: lol
[21:53] lor: ja biore kota :P
[21:53] phoenix: d0ubl3_j: tobie jedno w glowie
[21:53] <@Gynvael>: d0ubl3_j: ;p
[21:54] d0ubl3_j: phoenix: tez by ci bylo ;p
[21:54] G0blin: Gynvael: wiesz, ze jak slucham sonaty arctici podczas gry w sc mi rosnie apm ? :P
[21:54] d0ubl3_j: jak bys machal schematy blokowe ;p
[21:54] <@Gynvael>: G0blin ja tez, szeczegoolnie Destruction Preventer
[21:54] phoenix: Gynvael: mam juz
[21:54] <@Gynvael>: ;p
[21:54] phoenix: Gynvael: tyo ta k
[21:54] <@Gynvael>: phoenix: ?;>
[21:54] phoenix: Gynvael: "%64s = %64[^\n
[21:54] Sp3c0: to juz koniec ?
[21:54] phoenix: ]
[21:54] <@Gynvael>: Sp3c0: nie ;> przerwa
[21:54] <@Gynvael>: ;>
[21:54] <@Gynvael>: na pytania
[21:54] <@Gynvael>: ;>
[21:54] Sp3c0: to koniec wykladu ?
[21:54] <@Gynvael>: Sp3c0: przerwa na pytania ;>
[21:54] phoenix: i tyo ^ robii to ze nie zwaraca uwagi na spacje ?
[21:55] cli`: ja mam pytanie
[21:55] Sp3c0: o sory napisalem 2 x to samo ..
[21:55] G0blin: Gynvael: a przy preventerze nie probowalem, na razie najlepsze wyniki dla wolf&raven [21:55] cli`: czy będziemy robić takie rzeczy w asmie? ^_^
[21:55] defc0n: juz koniec?
[21:55] defc0n: hmm zaspalem :D
[21:55] <@Gynvael>: phoenix: ojc ;> to bylo na poprzednim wykladzie ;> [^\n] znaczy "dowolne znaki OPROCZ (^) znaku nowej linii (\n)"
[21:55] d0ubl3_j: PRZERWA NA PYTANIA :P
[21:55] G0blin: cli`: kiedys na pewno
[21:55] <@Gynvael>: czyli ^ to OPROCZ
[21:55] ant_: *straszny burdel* jak na czacie
[21:55] ant_: ;/
[21:55] <@Gynvael>: cli`: pewnie tak ;>
[21:55] phoenix: aaa
[21:55] phoenix: Gynvael: aha ;]
[21:55] phoenix: Gynvael: skleroze mam
[21:55] <@Gynvael>: ;>
[21:55] defc0n: burza mozgow
[21:55] lor: off: gynv pamietasz o algorytmach ?? :>
[21:55] phoenix: nyo bylo to pamietam..
[21:56] <@Gynvael>: lor: tak tak, juz mam jednego chetnego ;>
[21:56] lor: siest ;)
[21:56] <@Gynvael>: lor: tylko jeszcze termin musze ustalic ;>
[21:56] G0blin: ^^
[21:56] <@Gynvael>: ^^
[21:56] lor: czyzby goblin ??
[21:56] lor: ;)
[21:56] Karql: no kontynujcie
[21:56] <@Gynvael>: tya ;>
[21:56] <@Gynvael>: ok
[21:56] Karql: ja tu zeszyt przepisuje
[21:56] d0ubl3_j: oO
[21:56] Karql: ale jestem z wami:D
[21:56] <@Gynvael>: jeszcze jakies pytania ?
[21:56] d0ubl3_j: tak
[21:56] d0ubl3_j: ale to na priv
[21:56] G0blin: Gynvael: jak na razie proscizna :P
[21:57] phoenix: tak
[21:57] d0ubl3_j: bo musze zadanie zrobic na jutro ;p
[21:57] cli`: d0ubl3_j: o alę? :)
[21:57] d0ubl3_j: ne
[21:57] phoenix: czy bedzie cos wiecej o tym ?
[21:57] d0ubl3_j: o case in uml ;p
[21:57] d0ubl3_j: jak to wygalda
[21:57] lor: dj: "ile ala ma tych kotow ?? " ;)
[21:57] <@Gynvael>: d0ubl3_j: ee mnie nie pytaj ;p
[21:57] <@Gynvael>: lol
[21:57] <@Gynvael>: ;p
[21:57] <@Gynvael>: ok
[21:57] phoenix: Nekrataal: priv
[21:57] <@Gynvael>: a jakies pytanka na temat ?
[21:57] G0blin: co znaczy 1/2duplex?
[21:57] <@Gynvael>: G0blin: ze albo wysyla albo odbiera
[21:57] G0blin: (half-duplex)
[21:57] <@Gynvael>: ;p
[21:57] ayufan: Gynvael a co powiesz o lexerze i syntax tree? :>
[21:58] G0blin: a spoko :P
[21:58] <@Gynvael>: ayufan: oo czesc ayu ;>
[21:58] <@Gynvael>: ayufan: szczerze ? nie lubie automatow ;ppp i siebie za to ze ich nie lubie ;p
[21:58] G0blin: wlasnie czytam pod lawka o talku :P
[21:58] <@Gynvael>: ayufan: odczulem to jak pisalem parser to jezyka typu C++ ;p
[21:58] ayufan: no
[21:58] adam_i: Gynvael: ty prawie wszytkich znasz
[21:59] <@Gynvael>: ;p
[21:59] <@Gynvael>: dobra
[21:59] <@Gynvael>: lecimy dalej ?;>
[21:59] lor: tia
[21:59] ant_: 1
[21:59] phoenix: d0ubl3_j: tez brzydko piszesz?
[21:59] <@Gynvael>: ok
[21:59] <@Gynvael>: tyo lecimy dalej
[21:59] d0ubl3_j: tez ;p
[21:59] <@Gynvael>: dobra
[21:59] <@Gynvael>: teraz 3 slowa na temat kolejek
[21:59] <@Gynvael>: pointerki mam nadzieje ze pamietacie ?;>
[22:00] <@Gynvael>: zalozmy sobie ze mamy taka strukture
[22:00] <@Gynvael>: struct node { struct node *nastepny; int dane; }
[22:00] <@Gynvael>: czyli zawiera wskaznik na nastepny node i jakies dane
[22:00] <@Gynvael>: i zalozmy ze mamy sobei pointer
[22:00] <@Gynvael>: struct node *poczatek;
[22:00] <@Gynvael>: poczatek = NULL;
[22:00] <@Gynvael>: i to w sumie jest podstawa listy
[22:00] <@Gynvael>: lista to LISTA JAKIS TAM ELEMENTOW
[22:01] <@Gynvael>: do prostej listy mozemy cos dodac
[22:01] <@Gynvael>: czyli tworzymy nowa strukturke (obiekt) typu struct node
[22:01] <@Gynvael>: ustawiamy nastepny = poczatek;
[22:01] <@Gynvael>: i poczatek = ten_nowy_obiekt;
[22:01] <@Gynvael>: co to daje ?
[22:01] <@Gynvael>: przykladowo
[22:01] <@Gynvael>: poczatek -> NULL;
[22:02] <@Gynvael>: tworzymy nowy obiekt i wrzucamy mu do danych 1
[22:02] <@Gynvael>: [1] <=- to on ;>
[22:02] <@Gynvael>: ustawiamy zeby 1->nastepny wskazywal na to co poczatek, czyli NULL
[22:02] <@Gynvael>: [1]->NULL
[22:02] <@Gynvael>: i ustawiamy zeby poczatek wskazywal na niego
[22:02] <@Gynvael>: poczatek -> [1] -> NULL
[22:02] <@Gynvael>: a teraz jeszzcze jeden dodamy
[22:02] <@Gynvael>: [2]
[22:02] <@Gynvael>: [2] wskazyuje na to na co poczatek
[22:03] <@Gynvael>: [2]->[1]->NULL
[22:03] <@Gynvael>: i poczatek wskazuje na [2]
[22:03] <@Gynvael>: poczatek -> [2] -> [1] -> NULL
[22:03] <@Gynvael>: ew, tak mozna dodawac i dodawac
[22:03] <@Gynvael>: majac np liste
[22:03] <@Gynvael>: poczatek -> [5] -> [8] -> [2] -> [1] -> NULL
[22:03] <@Gynvael>: mozemy bardzo latwo znalesc jakis element z listy
[22:04] <@Gynvael>: wystarczy ze stworzymy struct node *iter; (iterator ;> takie cos co np chodzi po liscie ;p)
[22:04] <@Gynvael>: iter = poczatek
[22:04] <@Gynvael>: i teraz sprawdzamy
[22:04] <@Gynvael>: iter -> [5] teraz
[22:04] <@Gynvael>: sprawdczamy czy iter->dane == szukane
[22:04] <@Gynvael>: powiedzmy ze szukamy czy w liscie jest 2
[22:04] <@Gynvael>: wiec wykonujemy nastepujace kroki:
[22:04] <@Gynvael>: czy iter pokazuje na cos ? (iter==NULL) ? nie ? wychodzimy
[22:05] <@Gynvael>: czy iter->dane == szukane ? tak ? zwracamy ze znajduje sie to na liscie
[22:05] <@Gynvael>: nie ? idziemy na nastepny element, czyli karzemy iterowi wskazywac na nastepny element tego na co wskazuje
[22:05] <@Gynvael>: czyli iter = iter-> nastepny
[22:05] <@Gynvael>: i od poczatku to samo
[22:06] <@Gynvael>: czyli
[22:06] <@Gynvael>: poczatek -> [5] -> [8] -> [2] -> [1] -> NULL
[22:06] <@Gynvael>: iter = poczatek (oznacze za pomoca ( ) elemetn na ktory wskazuje iter)
[22:06] <@Gynvael>: poczatek -> ([5]) -> [8] -> [2] -> [1] -> NULL
[22:06] <@Gynvael>: 5 == 2 ? nie , idziemy dalej
[22:06] <@Gynvael>: poczatek -> [5] -> ([8]) -> [2] -> [1] -> NULL
[22:06] <@Gynvael>: 8 ==2 ? nie .. idziemy dalej
[22:06] <@Gynvael>: poczatek -> [5] -> [8] -> ([2]) -> [1] -> NULL
[22:06] <@Gynvael>: 2 == 2 ? tak ;> zwracamy ze jest na liscie
[22:07] <@Gynvael>: wiecej o listach bedzie na wykladach z algorytmow ;>
[22:07] <@Gynvael>: narazie nam tyle potrzeba
[22:07] <@Gynvael>: ok
[22:07] <@Gynvael>: i teraz, do tego poczatkowego programu do parsowania configow
[22:07] <@Gynvael>: wrzucamy taka prosta liste
[22:07] <@Gynvael>: po czym przy kazdej wczytanej opcji wrzucamy ja na liste wraz z wartoscia
[22:08] <@Gynvael>: a potem powiedzmy ze znajdziemy na liscie elementy ala i kot
[22:08] <@Gynvael>: http://gynvael.vexillium.org/simple2.c
[22:08] <@Gynvael>: te 3 pierwsze funkcje tam robia to co mowilem wyzej
[22:08] <@Gynvael>: + usuwaja wszystko z listy
[22:08] <@Gynvael>: jesli ktos nie znal list wczesniej, to proponuje zeby przyjrzal sie temu
[22:09] <@Gynvael>: zmiana w whileu jest zamiast printf dodanie do listy
[22:09] <@Gynvael>: dodaj_do_listy(&lista, name, value);
[22:09] <@Gynvael>: potem jest zamkniecie pliku
[22:09] <@Gynvael>: i wczytanie wartosci z listy
[22:09] <@Gynvael>: btw szukanie na liscie jest tutaj tak zrobione, ze zwraca wartosc opcji
[22:09] <@Gynvael>: czyli pointer na pierwszy znak zapamietanej wartosci
[22:09] <@Gynvael>: ;>
[22:09] <@Gynvael>: printf("wg configu ala %s\n", znajdz_na_liscie(lista,"ala"));
[22:09] <@Gynvael>: printf("wg configu kot %s\n", znajdz_na_liscie(lista,"kot"));
[22:10] <@Gynvael>: znajdz_na_liscie(lista,"nazwa_opcji");
[22:10] <@Gynvael>: o to wlasnie szuka na liscie jakiejs opcji
[22:10] <@Gynvael>: po czym zwraca jej wartosc
[22:10] <@Gynvael>: kompilujemy i odpalamy
[22:10] <@Gynvael>: 21:55:28 LiTeStEp >gcc simple2.c -Wall -pedantic -o simple2.exe
[22:10] <@Gynvael>: 22:15:12 LiTeStEp >simple2
[22:10] <@Gynvael>: wg configu ala ma kota
[22:10] <@Gynvael>: wg configu kot ma ale
[22:10] <@Gynvael>: to w sumie byl taki mally OT na temat wykorzystania troche bardizej normalnego configow
[22:11] <@Gynvael>: tak szczerze to powiem ze list raczej sie do tego nie uzywa (uzywa sie drzewka binarne i hash-listy), ale listy tez mozna ;>
[22:12] <@Gynvael>: pytania ?
[22:12] Mkzm: glodny jestem :]
[22:12] <@Gynvael>: ja tesh ;p
[22:12] Mkzm: :)
[22:12] dot_zmora: kto wygra mecz?
[22:12] <@Gynvael>: dot_zmora: polska!
[22:12] lor: a ja sie najadlem ;P
[22:12] <@Gynvael>: ;>
[22:12] ant_: duzo jeszcze zostalo? bo spac mi sie chce ;/
[22:12] d0ubl3_j: lor: btw
[22:13] <@Gynvael>: ant_: ehehehe
[22:13] Mkzm: Gynvael:a ja mam pytanie o argc :)
[22:13] d0ubl3_j: fajnie ze zamiesciles topic na forum
[22:13] d0ubl3_j: skad kto jest ;p
[22:13] ant_: jak 2 godziny/godzina to ide spac
[22:13] lor: a co poznales kogos ?? :)
[22:13] <@Gynvael>: ant_: z 30 minut, ostatni przyklad ;>
[22:13] cli`: 3 godziny
[22:13] G0blin: lol......
[22:13] d0ubl3_j: lor: ta 2 osob ;p
[22:13] lor: a ja nikogo ;P
[22:13] Mkzm: :]
[22:13] G0blin: zachowujecie sie jak na obowiazkowej lekcji
[22:13] ant_: oka to zostane z wami :)
[22:13] d0ubl3_j: jedna lazi do tej samej budy (budynek)
[22:13] d0ubl3_j: a druga
[22:13] lor: no ale spox ze komus sie przydalo ;P
[22:13] Mkzm: znowu nie przylalzem na wyklad :(
[22:13] G0blin: Gynvael robi to za darmo wiec sie zachowujcie
[22:13] <@Gynvael>: http://gynvael.lunarii.org/temp/lista.gif <=- lor'a ilustracja do list
[22:13] G0blin: :P
[22:14] ant_: G0blin: co ty gadasz
[22:14] d0ubl3_j: to syn polonistki z gimnazjum mojej :PP
[22:14] <@Gynvael>: ehehe
[22:14] <@Gynvael>: ok
[22:14] lor: hehe jaki ten swiat maly
[22:14] <@Gynvael>: lecimy dalje
[22:14] <@Gynvael>: ;>
[22:14] d0ubl3_j: nom
[22:14] ant_: G0blin: spac mi sie chce, wole sluchac
[22:14] <@Gynvael>: Mkzm: to na priv
[22:14] ant_: ale moge nie wytrzymac :)
[22:14] d0ubl3_j: ok ja spadam ;>
[22:14] d0ubl3_j: pa
[22:14] ant_: dobra lecmy :)
[22:14] <@Gynvael>: ok
[22:14] <@Gynvael>: -=221133=- <@Gynvael> http://gynvael.lunarii.org/temp/lista.gif <=- lor'a ilustracja do list
[22:14] <@Gynvael>: jak by ktos w ogoolnym harmidrze nie zauwazyl
[22:14] <@Gynvael>: ;>
[22:15] <@Gynvael>: ok
[22:15] <@Gynvael>: teraz pobawmy sie innym parserkiem
[22:15] <@Gynvael>: rowniez na scanf'ach
[22:16] <@Gynvael>: mianowicie zalozmy ze chcemy robic bardzo prosty jezyk skryptowy
[22:16] <@Gynvael>: taki ktory praktycznie nie wymaga zadnej skomplikowanej analizy, rozkladu na drzewa, tworzenia notacji polskiej, etc
[22:16] <@Gynvael>: zalozmy niech on bedzie wygladal tak:
[22:16] <@Gynvael>: INSTRUKCJA argumenty
[22:16] <@Gynvael>: PRINT "hello world"
[22:16] <@Gynvael>: np tak
[22:17] <@Gynvael>: zalozmy ze beda 3 polecenia jeszcze oprocz PRINT
[22:17] <@Gynvael>: SET nazwa_zmiennej wartosc/zmienna
[22:17] <@Gynvael>: ADD nazwa_zmiennej wartosc/zmienna
[22:17] <@Gynvael>: SUB nazwa_zmiennej wartosc/zmienna
[22:17] <@Gynvael>: przy czym w SET wartosc to moze byc np 11 albo "abcd" i obie wersje powinny byc ok
[22:18] <@Gynvael>: papa
[22:18] <@Gynvael>: PRINT wartosc/zmienna (tak dla scislosci)
[22:18] <@Gynvael>: i teraz
[22:18] <@Gynvael>: najpierw rzucmy okiem na podzial
[22:18] <@Gynvael>: [whitespace] [22:18] <@Gynvael>: tak jest zawsze
[22:19] <@Gynvael>: z tym ze argumenty moga byc oddzielone spacjami
[22:20] <@Gynvael>: co z tego wiemy
[22:20] <@Gynvael>: ze:
[22:20] <@Gynvael>: 1) musimy odczytac nazwe instrukcji
[22:20] <@Gynvael>: 2) po niej musi byc whitespace, jako ze KAZDA instrukcja ma argumenty.. mozemy z tego skorzystac w naszym wypadku do detekcji bledow ;>
[22:21] <@Gynvael>: 3) po tym sa argumenty.. ale raz sa 2, raz jeden...
[22:21] <@Gynvael>: narazie niech nas nie interesuja argumenty ;>
[22:22] <@Gynvael>: po prostu odczytajmy nazwe instrukcji i sprawdzmy czy jest whitespace
[22:22] <@Gynvael>: http://gynvael.vexillium.org/hello.x
[22:22] <@Gynvael>: http://gynvael.vexillium.org/hello2.x
[22:22] <@Gynvael>: http://gynvael.vexillium.org/hello3.x
[22:22] <@Gynvael>: to sa przykladowe programiki ;>
[22:22] <@Gynvael>: ok
[22:22] <@Gynvael>: wiec
[22:22] <@Gynvael>: najpierw punkty 1) 2)
[22:23] <@Gynvael>: najpierw wrzucmy cala linie do buforka
[22:23] <@Gynvael>: fgets(buf, sizeof(buf), src);
[22:23] <@Gynvael>: potem sprawdzmy czy nie koniec pliku
[22:23] <@Gynvael>: a teraz zamiast scanf, zrobmy inaczej
[22:23] <@Gynvael>: znajdzmy pierwsza spacje (bo musi byc)
[22:23] <@Gynvael>: za pomoca strchr
[22:23] <@Gynvael>: space = strchr(buf, ' ');
[22:23] <@Gynvael>: space == NULL ? blad ;>
[22:24] <@Gynvael>: majac adres peirwszej spacji, mozemy policzyc jakiej wielkosci (tj ile liter) ma nazwa instrukcji
[22:24] <@Gynvael>: wielkosc_polecenia = (int)(space - buf);
[22:24] <@Gynvael>: majac to
[22:24] <@Gynvael>: mozemy wykorzystac polecenie strncmp do porownania nazw instrukcji z tymi ktore znamy
[22:24] <@Gynvael>: i jesli znajdziemy, to do wywolania jakijs funkcji
[22:25] <@Gynvael>: ktora bedzie sie meczyc z argumentami za nas ;>
[22:25] <@Gynvael>: if(strncmp(buf, "PRINT", wielkosc_polecenia) == 0) ret = cmd_print(space+1);
[22:25] <@Gynvael>: else if(strncmp(buf, "SET", wielkosc_polecenia) == 0) ret = cmd_set(space+1);
[22:25] <@Gynvael>: else if(strncmp(buf, "ADD", wielkosc_polecenia) == 0) ret = cmd_add(space+1);
[22:25] <@Gynvael>: else if(strncmp(buf, "SUB", wielkosc_polecenia) == 0) ret = cmd_sub(space+1);
[22:25] <@Gynvael>: ofc moze sie zdarzyc
[22:25] <@Gynvael>: ze programista probowal uzyc jakiegos polecenia ktorego nei ma
[22:25] <@Gynvael>: wtedy zglaszamy blad; >
[22:25] <@Gynvael>: ok
[22:25] <@Gynvael>: space+1 to adres argumentow
[22:26] <@Gynvael>: czyli tego co jest po spacji
[22:26] <@Gynvael>: wiec mamy 4 funkcje
[22:26] <@Gynvael>: kazda z nich zwraca inta (0 jesli all ok)
[22:26] <@Gynvael>: i pobiera argumenty i cos tam robi
[22:26] <@Gynvael>: ;>
[22:26] <@Gynvael>: teraz zalozmy ze mamy globalna liste zmiennych ;>
[22:26] <@Gynvael>: "zmienne" niech tak sie zwie
[22:27] <@Gynvael>: i zacznijmy od cmd_print bo to najprostsze
[22:27] <@Gynvael>: PRINT moze byc wywolany albo ze zmienna albo z wartoscia
[22:27] <@Gynvael>: czyli
[22:27] <@Gynvael>: PRINT x
[22:27] <@Gynvael>: PRINT "Hello World"
[22:27] <@Gynvael>: zauwazmy pewna oczywista roznice
[22:28] <@Gynvael>: jesli PRINT dostaje stala wartosc, to sa " "
[22:28] <@Gynvael>: a jesli zmienna, to nie ma " "
[22:28] <@Gynvael>: mozemy wiec uzyc sscanf i tego co ta funkcja zwraca do sprawdzenia ktora to z mozliwosci
[22:28] <@Gynvael>: int cmd_print(char *arg)
[22:28] <@Gynvael>: zalozmy ze taki jest typ tej funkcji
[22:29] <@Gynvael>: mamy sobie jakis tam buf
[22:29] <@Gynvael>: ret = sscanf(arg, "\"%[^\"]\"", buf);
[22:29] <@Gynvael>: i za pomoca tego wczytujemy (a przynajmniej probojemy) to co jest miedzy cudzyslowiami
[22:29] <@Gynvael>: jesli ret == 1, to sie udalo i po prostu robimy puts(buf)
[22:29] <@Gynvael>: a jesli nie
[22:29] <@Gynvael>: to sprawdzamy czy to moze zmienna
[22:30] <@Gynvael>: ret = sscanf(arg, "%[A-Za-z_]", buf);
[22:30] <@Gynvael>: jesli ret == 1, to wczytujemy jej wartosc z listy
[22:30] <@Gynvael>: i wypisujemy ja na ekran
[22:30] <@Gynvael>: a jesli nei to zglaszamy blad
[22:31] <@Gynvael>: tyle jesli chodzi o PRINT
[22:31] <@Gynvael>: z SET jest podobna bajka
[22:31] <@Gynvael>: tyle ze sa 3 opcje
[22:31] <@Gynvael>: SET zmienna zmienna
[22:31] <@Gynvael>: SET zmienna "wartosc"
[22:31] <@Gynvael>: SET zmienna 1234
[22:31] <@Gynvael>: i tez musimy je po kolei sprawdzac
[22:31] <@Gynvael>: http://gynvael.vexillium.org/runx.c
[22:32] <@Gynvael>: hello world
[22:32] <@Gynvael>: 10
[22:32] <@Gynvael>: czyli dziala ;>
[22:32] <@Gynvael>: w programie tym nie sa wypelnione SUB i ADD
[22:32] <@Gynvael>: wypelnienie tych funkcji (cmd_add i cmd_sub) bedzie jednym z zadanek na liscie
[22:33] <@Gynvael>: ;>
[22:33] <@Gynvael>: pytania ?
[22:33] ant_: koniec?
[22:33] <@Gynvael>: ant_: za chwile, ejszcze pare linkow dam
[22:34] <@Gynvael>: ok
[22:34] <@Gynvael>: widze ze wszyscy juz pozasypiali ;> (noo wiekszosc ;>)
[22:34] <@Gynvael>: wiec podam pare linkow na koniec
[22:35] <@Gynvael>: 1) warto sie zapoznac z forma zapisu z czego sie skladaja pola roznych protokolow opisanych w RFC
[22:35] <@Gynvael>: http://www.faqs.org/rfcs/rfc1459.html
[22:35] <@Gynvael>: np
[22:35] <@Gynvael>: ::= [':' ] [22:35] <@Gynvael>: ::= | [ '!' ] [ '@' ]
[22:35] <@Gynvael>: mowie o tym ;>
[22:35] <@Gynvael>: jak sie to zapozna, to wszelkie parserki pisze sie latwo
[22:36] <@Gynvael>: 2) za tydzien beda prawdopodobnie dalej parsery (automaty stanow)
[22:36] <@Gynvael>: 3) podam dwa linki do swoich (nie zawsze skonczonych) artow o parsingu
[22:36] <@Gynvael>: a noz cos ciekawego tam wyczytacie
[22:37] <@Gynvael>: http://gynvael.lunarii.org/temp/parsing.html
[22:37] <@Gynvael>: http://gynvael.vexillium.org/?stuff=http_parse.stuff
[22:37] <@Gynvael>: 4) jutro rano albo dzisiaj w nocy pojawia sie kolejne zadanka na liscie z C
[22:37] <@Gynvael>: 5) btw gmail.com cos nie lubi plikow .exe i .rar w zalacznikach, wiec zadanka starajcie sie podsylac w formie niespakowanej i samych zrodel
[22:38] <@Gynvael>: ;>
[22:38] <@Gynvael>: ok tyle
[22:38] <@Gynvael>: do zobaczenia za tydzien
[22:38] Karql: Gynvael: chcesz loga:D?
[22:38] ant_: [22:38] <@Gynvael>: Karql: na mejla plz ;>
[22:38] <@Gynvael>: =^^=
[22:38] Karql: juz tylko poskladam:D