Pokaż wyniki od 1 do 7 z 7

Temat: DSL (domain-specific language)

  1. #1

    Domyślnie DSL (domain-specific language)

    ** teoria **

    W tej notce pokażę Wam, jak w prosty sposób napisać prosty język programowania.
    Utworzenie od początku do końca języka programowania to sporo roboty (analiza
    leksykalna, syntaktyczna, semantyczna, kod pośredni, kod wynikowy lub maszyna
    wirtualna), lecz można skorzystać z prostszej drogi (która daje też mniej
    możliwości), a mianowicie utworzyć nowy język, który będzie wykorzystywany przez
    język już istniejący. Takie coś nazywa się DSL i jest dość popularne.

    DSL jest wykorzystywane m.in do budowy języków z których mają korzystać eksperci
    w danych dziedzinach, chodzi o to, iż programiści, projektanci nie zgłębiają się
    w dane zagadnienie (no np geologię, jakąś dziedzinę fizyki), tylko w konsultacji
    z ekspertami tej dziedziny budują język, który oni (tzn eksperci) wykorzystają
    do rozwiązywania problemów.

    DSL może być też wykorzystywane do tworzenia testów oprogramowania, do tworzenia
    zapytań, by wyciągnąć dane, etc.

    Najważniejsze decyzje, jakie musimy podjąć, to język, który wykorzystamy oraz
    składnia tego nowego języka. Składnia ta powinna być naturalna/poprawna dla
    języka, który wykorzystamy, powinna dobrze wyrażać problemy, rzeczy, które
    chcemy wyrazić w języku, ludzie, którzy będą ten język wykorzystywać powinni ją
    akceptować.

    Język, który wykorzystamy powinien być ekspresywny, giętki, jeżeli nie jest na
    tyle giętki, na ile nam trzeba trzeba zbudować preprocesor (coś jak w C), który
    przeleci pliki wejściowe i je zmodyfikuje, tak by były poprawne. Taki
    preprocesor może zajmować się również wstępną walidacją.

    Sugerowałbym język dynamicznie typizowany, np. Pythona albo Ruby.

    ** praktyka **

    Przykład będzie banalny, mianowicie implementacja (to się chyba Logo nazywa)
    języka, gdzie mamy żółwia i on chodzi po planszy, a my sterujemy jego ruchami.

    W przykładzie wykorzystamy Pythona, jeśli ktoś jest zainteresowany Rubym to na
    końcu jest link.

    Zastanówmy się co powinien mieć język do obsługi takiego żółwika? IMHO:
    * deklarowanie, jakie są rozmiary planszy, po której chodzi żółwik, np tak
    plansza(100, 50), na zapisanie planszy długiej na 100px i szerokiej na 50px

    * deklarowanie, gdzie jest początkowy punkt, w którym jest żółwik, np tak
    zaczynam(20, 30), by poinformować, iż punkt początkowy ma wsp (20, 30) licząc
    w pikselach

    * polecenia poruszania się w górę, dół, prawo i lewo, w takiej formie
    nazwa_kierunku(wartość w pikselach), np. lewo(10), prawo(20)

    * po skończonej wędrówce powinna być opcja, by zapisać wędrówkę do pliku
    graficznego, np taka zapisz("koniec.png")


    Zauważmy, że taka składnia jest poprawną składnią Pythona, jeżeli była by
    niepoprawna to albo trzeba by ją było zmienić albo napisać jakiś preprocesor
    (pierwsze rozwiązanie jest dużo lepsze, lecz nie zawsze możliwe).

    Poniżej zamieszczam przykładowy kod, który to realizuje, plik wejściowy i
    wygenerowane na jego podstawie wyjście.

    kod:

    Kod:
    #!/usr/bin/env python
    from PIL import Image
    import sys
    
    class Turtle:
        bg_color =  (200,200,200)
        line_color = (33, 66, 88)
        x = 0
        y = 0
    
        def compile(self, input_file):
            plansza = lambda x,y: self.plansza(x,y)
            zapisz = lambda name: self.zapisz(name)
            zaczynam = lambda x,y: self.zaczynam(x, y)
            lewo = lambda val: self.lewo(val)
            prawo = lambda val: self.prawo(val)
            gora = lambda val: self.gora(val)
            dol = lambda val: self.dol(val)
    
            for line in open(input_file, 'r').readlines():
                eval(line)
    
        def plansza(self, x_max, y_max):
            self.img = Image.new("RGB", (x_max, y_max), self.bg_color)
    
        def zapisz(self, output):
            self.img.save(output)
    
        def zaczynam(self, x_start, y_start):
            self.x = x_start
            self.y = y_start
    
        def prawo(self, val):
            for i in range(self.x, self.x+val):
                self.img.putpixel((i, self.y), self.line_color)
            self.x += val
    
        def lewo(self, val):
            for i in range(self.x-val, self.x):
                self.img.putpixel((i,self.y), self.line_color)
            self.x -= val
    
        def dol(self, val):
            for i in range(self.y, self.y+val):
                self.img.putpixel((self.x, i), self.line_color)
            self.y += val
    
        def gora(self, val):
            for i in range(self.y-val, self.y):
                self.img.putpixel((self.x, i), self.line_color)
            self.y -= val
    
    if __name__ == "__main__":
        input = sys.argv[1]
        t = Turtle()
        t.compile(input)
    plik wejściowy (pierwszy.zol):

    Kod:
    plansza(500, 500)
    zaczynam(300, 300)
    lewo(100)
    lewo(100)
    dol(10)
    lewo(10)
    gora(10)
    prawo(22)
    zapisz("ala124.png")

    uruchomienie:
    Kod:
    rgawron@foo:/opt/tutorial$ ./zolw.py pierwszy.zol
    wynikowy plik:


    Najważniejsza jest metoda compile, linijka z eval'em, który wykonuje nasz
    skrypt.

    Lambdy w procedurze compile używłem
    dlatego, iż do metod w obrębie klasy odwołujemy się poprzedzając je self, w
    naszym języku nie mamy tego self'a, nie chciałem go dodawać, więc teraz
    wywołujemy ten obiekt, któremu przypisana jest lambda a ona wywołuje metodę
    klasy.

    ** podsumowanie **

    Języki DSL mają specyficzne zastosowanie, nie są one zamiennikami normalnych
    "języków", służą one raczej do utworzenia języka w którym będzie można łatwo
    wyrazić dany problem, w którym można go wyrazić bardziej abstrakcyjnie.

    Podałem bardzo prosty przykład, nie traktujcie tego, jako wszystko, co języki
    klasy DSL potrafią. Na koniec podam linka do swojego (marnego) języka DSL, który
    http://rgawron.megiteam.pl/2010/01/22/dsl-ruby-vm/ wykonuje plik prostego asemblera i w ten sposób działa jak maszyna wirtualna. To
    jest link do notki na moim blogu. tam kod jest w Rubym (i jest paskudnie
    napisany ), no ale powyższy też nie jest zbyt dobry. Mógłby być bardziej
    zwięzły ale przez to trochę bardziej zaciemniony.

    Rozwiązanie tego problemu (czyli jak napisać program który z pliku wyjściowego
    wygeneruje obrazek) można było na wiele sposobów, poprzez wyrażenia regularne,
    maszyny stanów, kodując żywcem drabinkę if-else-for-etc albo pewnie i na tysiąc
    innych sposobów. Zaletą tego rozwiązania jest jednak to, iż integruje się ono z
    innym (czyli z macierzystym językiem), które jest już całkiem dobrym, wygodnym
    językiem (o ile dobrze wybierze się język).

    Do języka, który wam pokazałem można dorobić masę nowych rzeczy, np to, by
    żółwik mógł chodzić nie zostawiając za sobą śladu. Można by też napisać skrypt,
    generujący dane wejściowe na podstawie jakiegoś zdjęcia i żółwik rysował by jego
    kontury

    Jak się wam podobało? Zapraszam do dyskusji!

  2. #2
    Dawni Moderatorzy Avatar grzonu
    Dołączył
    26-12-2006
    Skąd
    Gdansk, Poland, Poland
    Posty
    1 392

    Domyślnie

    bardzo przydatne i ciekawe rozwiazanie nad którym się szczerze nigdy dłuzej nie zastanawiałem
    Oby wiecej takich postów które mierzą wyżej

    //jesli ci to nie przeszkadza to przykleje temat za kilka godzin
    Filmy online---Grzonu Blog

    1) Moje gg to nie pomoc techniczna w obsludze keyloggerow!!! Na gg i pw pomagam tylko w kwestiach organizacyjnych forum. Masz problem to pisz na forum.
    2) Nie zajmuje sie malware a uprzedzajac pytanie "czemu?" - bo taki mam kaprys!

  3. #3

    Domyślnie

    Heh, dzięki. BTW powoli się wgłębiam w temat i za jakiś czas opiszę budowę kompilatora, który pobiera kod w prostym asemblerze i produkuje binarkę, która śmiga pod Linuksem.

  4. #4
    Dawni Moderatorzy Avatar discovery44
    Dołączył
    14-08-2007
    Posty
    767

    Domyślnie

    za jakiś czas opiszę budowę kompilatora, który pobiera kod w prostym asemblerze i produkuje binarkę, która śmiga pod Linuksem.
    Czekam, czekam Ładnie.
    www.racjonalista.pl - "Racjonalista jest interaktywnym medium, którego nadrzędnymi wartościami są idee wolnej myśli oraz rozumnego kształtowania przekonań i życia."
    www.richarddawkins.net | Four Horsemen of Atheism | "Bóg urojony"

  5. #5
    Dawni Moderatorzy Avatar grzonu
    Dołączył
    26-12-2006
    Skąd
    Gdansk, Poland, Poland
    Posty
    1 392

    Domyślnie

    ja takze bedzie chetnie sie dokształce
    Jak zrobisz pod linuxa to ja chetnie przepisze pod winde
    Filmy online---Grzonu Blog

    1) Moje gg to nie pomoc techniczna w obsludze keyloggerow!!! Na gg i pw pomagam tylko w kwestiach organizacyjnych forum. Masz problem to pisz na forum.
    2) Nie zajmuje sie malware a uprzedzajac pytanie "czemu?" - bo taki mam kaprys!

  6. #6

    Domyślnie

    jeden z lepszych artykułów jakie czytałem w sieci, bardzo treściwy.

  7. #7

Uprawnienia

  • Nie możesz zakładać nowych tematów
  • Nie możesz pisać wiadomości
  • Nie możesz dodawać załączników
  • Nie możesz edytować swoich postów
  •