abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 09:11 | Bezpečnostní upozornění

    Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.

    Ladislav Hagara | Komentářů: 0
    včera 20:00 | Komunita

    V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.

    Ladislav Hagara | Komentářů: 0
    včera 19:22 | IT novinky

    Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).

    Ladislav Hagara | Komentářů: 0
    30.4. 22:33 | Nová verze

    Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.

    Ladislav Hagara | Komentářů: 0
    30.4. 17:44 | Zajímavý článek

    Devadesátková hra Brány Skeldalu prošla portací a je dostupná na platformě Steam. Vyšel i parádní blog autora o portaci na moderní systémy a platformy včetně Linuxu.

    karkar | Komentářů: 0
    30.4. 12:11 | Humor

    Lidi dělají divné věci. Například spouští Linux v Excelu. Využít je emulátor RISC-V mini-rv32ima sestavený jako knihovna DLL, která je volaná z makra VBA (Visual Basic for Applications).

    Ladislav Hagara | Komentářů: 7
    30.4. 10:44 | IT novinky

    Revolut nabídne neomezený mobilní tarif za 12,50 eur (312 Kč). Aktuálně startuje ve Velké Británii a Německu.

    Ladislav Hagara | Komentářů: 29
    30.4. 09:55 | IT novinky

    Společnost Amazon miliardáře Jeffa Bezose vypustila na oběžnou dráhu první várku družic svého projektu Kuiper, který má z vesmíru poskytovat vysokorychlostní internetové připojení po celém světě a snažit se konkurovat nyní dominantnímu Starlinku nejbohatšího muže planety Elona Muska.

    Ladislav Hagara | Komentářů: 7
    30.4. 09:33 | IT novinky

    Poslední aktualizací začal model GPT-4o uživatelům příliš podlézat. OpenAI jej tak vrátila k předchozí verzi.

    Ladislav Hagara | Komentářů: 0
    30.4. 08:11 | Nová verze

    Google Chrome 136 byl prohlášen za stabilní. Nejnovější stabilní verze 136.0.7103.59 přináší řadu novinek z hlediska uživatelů i vývojářů. Podrobný přehled v poznámkách k vydání. Opraveno bylo 8 bezpečnostních chyb. Vylepšeny byly také nástroje pro vývojáře.

    Ladislav Hagara | Komentářů: 0
    Jaký filesystém primárně používáte?
     (58%)
     (1%)
     (9%)
     (21%)
     (4%)
     (1%)
     (2%)
     (0%)
     (1%)
     (3%)
    Celkem 499 hlasů
     Komentářů: 19, poslední 30.4. 11:32
    Rozcestník

    Yapgen - parser generator

    6.6.2015 19:11 | Přečteno: 1308× | Vývoj software | Výběrový blog | poslední úprava: 7.6.2015 09:20

    Chtěl by jsem vám představit jeden ze svých projektů, na kterém jsem začal pracovat už v rámci diplomové práce (8 let zpět). Od té doby jsem jej párkrát využil při implementaci úkolů se kterými jsem se setkal v praxi. V případě, že nikoho nebude zajímat, nevadí, alespoň jsem pročistil starý kód a umístil jej na veřejné úložiště. Jedná se o program yapgen, který používám pro generování překladačů.

    Program yapgen, jehož jméno vychází z tradice pojmenování lexikálních a syntaktických analyzátorů, slouží k rychlému prototypování, testování a generování lexikálního a syntaktického analyzátoru.

    Základní funkce

    Překladač je definován souborem obsahujícím popis lexikálního a syntaktického analyzátoru. Tento soubor může obsahovat i sémantická pravidla generovaného jazyka, která jsou popsána skripty v programovacím jazyce LUA. Z popisu jazyka je programem yapgen vygenerován překladač, který je možné otestovat nad vstupním řetězcem, nebo uložit jeho zdrojový kód v jazyce C/C++.

    Postup při tvorbě překladače

    Standardní postup při tvorbě nového překladače je následující: Autor vygeneruje triviální překladač, a k němu odpovídající vstupní řetězce. Prostřednictvím programu yapgen testuje funkci překladače na vstupních řetězcích a postupně rozšiřuje popis jazyka o nové požadované funkce. V okamžiku, kdy se autor dostane do bodu, kdy je s popisem svého překladače spokojen vygeneruje C/C++ zdrojový kód, který použije ve svém projektu.

    Použití programu yapgen

    Program yapgen akceptuje následující tři argumenty. Argument --parser_descr <file> odkazuje na soubor obsahující popis překladače k vygenerování. Tento soubor obsahuje popis regulárních výrazů terminálních symbolů a pravidel gramatiky jazyka. Parametr --parser_save_cc <file> odkazuje na cílový soubor, do kterého je vygenerován kód překladače v jazyce C++. Výsledný soubor obsahuje implementaci lexikálního a syntaktického analyzátoru přijímaného jazyka. Poslední argument --source <file> odkazuje na soubor obsahující řetězec, který je použit jako vstupní řetězec vygenerovaného překladače.

    Příklady použití programu yapgen

    Vygenerování překladače:

    ./yapgen --parser_descr demo_exp.rules

    Vygenerování překladače a jeho spuštění nad vstupním řetězcem:

    ./yapgen --parser_descr demo_exp.rules --source demo_exp.src

    Vygenerování překladače a následné vygenerování C++ kódu překladače:

    ./yapgen --parser_descr demo_exp.rules --parser_save_cc demo_exp.cc

    Popis jazyka

    Regulární výrazy

    Terminální symboly gramatiky přijímaného jazyka jsou popsány množinou regulárních výrazů. Na základě těchto regulárních výrazů se generuje lexikální analyzátor rozpoznávající symboly ve vstupním řetězci.

    Zápis terminálních symbolů

    Jednotlivé terminální symboly jsou zapisovány v následujícím formátu:

    <id> {<regexp>}

    Kde <id> zastupuje název (identifikátor) regulárního výrazu, a <regexp> zastupuje kód obsahující regulární výraz. Terminální symboly mohou být pojmenovány standardními identifikátory, známými například z jazyka C.

    oct_i32_const {'0'.<07>*}
    dec_i32_const {<19>.d*}
    hex_i32_const {'0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*}
    
    _SKIP_    {w.w*}
    _SKIP__   {'#'.!'\n'*.'\n'}
    _SKIP___  {"//".!'\n'*.'\n'}
    _SKIP____ {"/*".(!'*'+('*'.!'/'))*."*/"}
    _END_     {'\0'}

    Terminální symboly, jejichž jméno obsahuje podřetězec _SKIP_ jsou tímto způsobem označeny jako symboly ignorované syntaktickou analýzou generovaného překladače. Tímto způsobem se často ve zdrojovém kódu jazyka označují bíle znaky a komentáře.

    Terminální symboly, jejichž jméno obsahuje podřetězec _END_ jsou označeny jako tzv. ukončovací terminály, při jejichž přijetí ze zdrojového řetězce akcí shift dochází k ukončení rozkladu vstupního řetězce. Jako hodnota ukončovacího terminálu se často používá znak \0 identifikující konec vstupního řetězce.

    Základní komponenty regulárních výrazů

    Regulární výrazy popisující terminální symboly jazyka se skládají z následujících komponent, které je možné kombinovat prostřednictvím níže popsaných operátorů.

    Zástupný symbol

    Zastupuje jeden znak z předdefinované množiny znaků.

    Znak

    Zastupuje jeden znak identifikovaný zápisem v apostrofech '<char>'.

    Negace znaku

    Zastupuje libovolný znak lišící se od znaku uvedeného v uvozovkách. Pro znak uvedený v uvozovkách může být použita stejná notace jako v případě komponenty Znak: !'<char>'.

    !'a'
    '"'.(!'"'+'\\'.'"')*.'"'

    Řetězec znaků

    Zastupuje řetězec znaků, které jsou popsány znaky uvedenými na jednotlivých pozicích řetězce. Pro znaky na jednotlivých pozicích řetězce je možné použít stejnou notaci jako v případě komponenty Znak: "<char><char>...".

    "if"
    "else"
    "multi\nline"
    "/*".(!'*'+('*'.!'/'))*."*/"

    Rozsah znaků

    Zastupuje znak, jehož ordinární hodnota se nachází v rozmezí od ordinární hodnoty prvního znaku do ordinární hodnoty druhého znaku včetně krajních hodnot. Pro identifikaci prvního a posledního znaku je možné použít stejnou notaci jako v případě komponenty Znak: <<char><char>>.

    <19>.d*
    '0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*

    Množina znaků

    Zastupuje jeden znak z uvedené množiny znaků. Pro identifikaci jednotlivých znaků v množině je možné použít stejnou notaci jako v případě komponenty Znak: [<char><char>...].

    '\''.'\\'.[abfnrtv\\?\'"].'\''
    '0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*.[lL]

    Znaky s výjimkou

    Zastupuje jeden znak, který se nenachází v uvedené množině znaků. Pro identifikaci jednotlivých znaků v množině je možné použít stejnou notaci jako v případě komponenty Znak: |<char><char>...|.

    '"'.(|"|+'\\'.'"')*.'"'

    Operátory regulárních výrazů

    Nad výše uvedenými základními komponentami regulárních výrazů je možné používat následující operátory.

    Konkatenace

    Binární operátor .. Pro přijetí regulárního výrazu je nutné přijmout levou a následně pravou stranu operátoru.

    "Hello".' '."world"
    <19>.d*
    'x'.(<09>+<af>+<AF>).(<09>+<af>+<AF>+e)

    Alternativa

    Binární operátor +. Pro přijetí regulárního výrazu je nutné přijmout levou nebo pravou stranu operátoru.

    "i8"+"i16"+"i32"+"i64"+"u8"+"u16"+"u32"+"u64"+"f32"+"f64"
    ('_'+l).('_'+l+d)*
    'x'.(<09>+<af>+<AF>).(<09>+<af>+<AF>+e)

    Iterace

    Unární operátor *. Pro přijetí regulárního výrazu je nutné přijmout operand 0 až n-krát. Operand je umístěn před symbolem operátoru *.

    <19>.d*
    ('_'+l).('_'+l+d)*

    Uvedené operátory jsou seřazeny podle priority (sestupně) následovně: iterace, konkatenace a alternativa.

    Závorky v regulárních výrazech

    Kulaté závorky () zvyšují prioritu uzavřeného regulárního podvýrazu obdobně jako závorky v aritmetických výrazech.

    Pravidla gramatiky

    Samotný jazyk je popsán SLR(1) gramatikou, která je dostatečně silná pro popis obecného programovacího jazyka. Gramatika jazyka je definována výše uvedeným popisem terminálních symbolu, výčtem neterminálních symbolů a pravidly gramatiky skládajících se z terminálních a neterminálních symbolů.

    Neterminální symboly gramatiky se zapisují do ostrých (angle) závorek.

    <start>
    <program>

    Pravidla gramatiky jsou zapisovány v následujícím formátu:

    <head> -> <item> <item> ... ->> {<code>}

    Kde, <head> je neterminál reprezentující hlavičku pravidla. Hlavička pravidla je od jeho těla oddělena znaky ->. Tělo pravidla obsahuje posloupnost terminálních a neterminálních symbolů (<item>), které jsou od sémantického kódu pravidla odděleny znaky ->>. Sémantický kód reprezentovaný zdrojovým kódem v jazyce LUA je uzavřen ve složených závorkách {}. V případě, že je potřeba v sémantickém kódu použít symbol } je nutné před něj vložit znak zpětného lomítka \}.

    <command> -> <if_condition> <if_body> ->> {}
    <if_condition> -> if <condition> ->> {print('if condition')}
    <if_body> -> <command>           ->> {print('if statement')}
    <if_body> -> <if_else> <command> ->> {print('if else statement')}
    <if_else> -> <command> else      ->> {print('if else')}

    Sémantická pravidla jazyka

    Sémantická pravidla jazyka jsou při prototypování překladače zapsána prostřednictvím skriptů v jazyce LUA.

    Voláním funkce rule_body s jedním parametrem n reprezentujícím celé číslo je možné získat řetězec odpovídající podřetězci zdrojového řetězce, který je reprezentován n-tou položkou těla pravidla, podle kterého proběhla redukce.

    Další vlastnosti

    Vygenerovaný analyzátor je jednoprůchodový. To znamená, že terminální symboly rozpoznané lexikálním analyzátorem jsou okamžitě zpracovány na vstupu syntaktické analýzy, bez nutnosti jejich zaznamenávání.

    Příklad tvorby překladače

    V této části uvádím příklad inkrementální tvorby překladače vyhodnocujícího jednoduché aritmetické výrazy.

    Základní kostra překladače

    První soubor pravidel vytvoří analyzátor, který je schopný na vstupu přijmout řetězec obsahující pouze bílé znaky (mezera, tabulátor nový řádek).

    init_code: {}
    
    terminals:
      _SKIP_ {w.w*}
      _END_ {'\0'}
    
    nonterminals:
      <start>
      <end_check>
    
    rules:
       <start> -> <end_check> ->> {}
       <end_check> -> _END_ ->> {}

    Analyzátor rozpoznává dva terminální symboly, kde první symbol zastupuje posloupnost bílých znaků, a druhý zastupuje znak označující konec řetězce. Volání lexikálního analyzátoru akceptují ukazatel na znaky řetězce a jeho délku, a při překročení délky vstupního řetězce automaticky generují symbol '\0' na vstupu. Hodnota ukončujícího terminálu není omezena na symbol \0, ale může nabývat libovolné hodnoty, kterou je možné popsat regulárním výrazem.

    Jak již bylo uvedeno v rámci popisu regulárních výrazů všechny terminály, které ve svém názvu obsahují podřetězec _SKIP_ jsou syntaktickou analýzou ignorovány. V případě, že terminální symbol obsahující ve svém názvu podřetězec _END_ je přesunut na LALR rozkladový zásobník syntaktické analýzy (což znamená že neterminál nacházející se nalevo od tohoto symbolu byl kompletně přijat) je rozklad vstupního řetězce ukončen.

    Z výše uvedeného vyplývá, že analyzátor vygenerovaný na základě prvního souboru pravidel v podstatě čeká na přijetí znaku '\0'.

    Seznam terminálních symbolů

    Druhý soubor pravidel popisuje analyzátor, který na vstupu rozeznává terminální symboly reprezentující celočíselné konstanty.

    init_code: {print('init_code')}
    
    terminals:
      oct_int {'0'.<07>*}
      dec_int {<19>.d*}
      hex_int {'0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*}
    
      _SKIP_ {w.w*}
      _END_ {'\0'}
    
    nonterminals:
      <start>
      <end_check>
      <program>
      <item_list>
      <item>
      <A>
    
    rules:
      <start> -> <end_check> ->> {}
    
      <end_check> -> <program> _END_ ->> {}
      <end_check> -> _END_ ->> {}
    
      <program> -> <item_list> ->> {}
    
      <item_list> -> <item> <item_list> ->> {}
      <item_list> -> <item> ->> {}
    
      <item> -> <A> ->> {}
    
      <A> -> oct_int ->> {print('constant: '..rule_body(0))}
      <A> -> dec_int ->> {print('constant: '..rule_body(0))}
      <A> -> hex_int ->> {print('constant: '..rule_body(0))}

    Příklad řetězce akceptovaného vygenerovaným překladačem:

    10
    0x10 125 02
    07

    Výstup generovaný při spuštění překladače nad uvedeným vstupním řetězcem.

    init_code
    constant: 10
    constant: 0x10
    constant: 125
    constant: 02
    constant: 07

    Množina terminálních symbolů byla rozšířena o reprezentace celočíselných konstant. Gramatika popisující jazyk byla rozšířena o pravidla generující seznam celočíselných konstant.

    K posledním třem pravidlům byly přiřazeny sémantické kódy, které se interpretují v případě redukce podle pravidla, ke kterému jsou přiřazeny. Sémantické kódy uvedené v druhém souboru pravidel vypisují na standardní výstup informace o rozpoznaném terminálním symbolu.

    V souboru je uveden i inicializační sémantický kód, který je zapsán za klíčovým slovem init_code. Tento sémantický kód je interpretován vždy na začátku rozkladu vstupního řetězce.

    Vyhodnocení výrazů

    Třetí soubor pravidel popisuje překladač, který v rámci svých sémantických pravidel vyhodnocuje jednoduché výrazy nad celočíselnými konstantami.

    init_code: {s = {\}}
    
    terminals:
      oct_int {'0'.<07>*}
      dec_int {<19>.d*}
      hex_int {'0'.[xX].(<09>+<af>+<AF>).(<09>+<af>+<AF>)*}
    
      lr_br {'('}
      rr_br {')'}
    
      plus {'+'}
      minus {'-'}
      asterisk {'*'}
      slash {'/'}
      percent {'%'}
    
      _SKIP_ {w.w*}
      _END_ {'\0'}
    
    nonterminals:
      <start>
      <end_check>
      <program>
      <item_list>
      <item>
      <C>
      <B>
      <A>
    
    rules:
      <start> -> <end_check> ->> {}
    
      <end_check> -> <program> _END_ ->> {}
      <end_check> -> _END_ ->> {}
    
      <program> -> <item_list> ->> {}
    
      <item_list> -> <item> <item_list> ->> {}
      <item_list> -> <item> ->> {}
    
      <item> -> <C>           ->> {print("result: "..s[#s])}
      <C> -> <C> plus <B>     ->> {s[#s-1] = s[#s-1] + table.remove(s)}
      <C> -> <C> minus <B>    ->> {s[#s-1] = s[#s-1] - table.remove(s)}
      <C> -> <B>              ->> {}
      <B> -> <B> asterisk <A> ->> {s[#s-1] = s[#s-1] * table.remove(s)}
      <B> -> <B> slash <A>    ->> {s[#s-1] = s[#s-1] / table.remove(s)}
      <B> -> <B> percent <A>  ->> {s[#s-1] = s[#s-1] % table.remove(s)}
      <B> -> <A>              ->> {}
      <A> -> lr_br <C> rr_br  ->> {}
    
      <A> -> oct_int ->> {table.insert(s,tonumber(rule_body(0),8))}
      <A> -> dec_int ->> {table.insert(s,tonumber(rule_body(0),10))}
      <A> -> hex_int ->> {table.insert(s,tonumber(rule_body(0)))}

    Příklad řetězce akceptovaného vygenerovaným překladačem:

    10 - 010
    5*(10 + 5) - 0x10
    10*3 - 10*2

    Výstup generovaný při spuštění překladače nad uvedeným vstupním řetězcem.

    result: 2
    result: 59
    result: 10

    Seznam terminálních symbolů byl rozšířen o kulaté závorky a pět základních aritmetických operátorů. Gramatika popisující přijímaný jazyk byla rozšířena o pravidla popisující jednoduché aritmetické výrazy. Vyhodnocování výrazů v rámci sémantických kódů se provádí pomocí zásobníku:

    Priorita operátorů v aritmetických výrazech je určena posloupností neterminálních symbolu <A>,<B> a <C>.

    Kompilace C like kódu

    V posledním příkladu popíši překladač kódu odvozeného z jazyka C, který používám pro překlad C zápisu do JIT instrukcí knihovny libjit. Řetězce zmiňovaného jazyka popisují funkce, jejichž kód se generuje prostřednictvím knihovny libjit. Následují příklady dvou vstupních řetězců:

    i32 fact(i32 n)
    {
      i32 res = 1;
      while (n > 1) res *= n--;
      return res;
    }
    i32 test(i8 *data,u32 count)
    {
      i64 *ptr = (i64 *)data;
      i64 *ptr_end = ptr + count;
      do {
        *ptr = fact(*ptr);
      } while(++ptr < ptr_end);
    
      return 0;
    }

    Soubor popisující překladač přijímající podmnožinu jazyka C je k nalezení zde. Příklad překladače pro JIT kompilace zde uvádím spíše jen proto, aby jsem ukázal, že je možné yapgen použít pro generování skutečného překladače, a ne pouze výše uvedených hraček.

    Generátor používám pro generování překladačů, které jsou aktuálně nasazené v reálných aplikacích. Zdrojové kódy je možné najít na yapgen.

    Použití programu yapgen v praxi

    V této kapitole, která nebyla součástí původního příspěvku je uvedeno pár příkladů použití programu yapgen k vygenerování překladače používaného v praxi.

    Komunikace prostřednictvím RS485

    Vyvinuli jsme aktivní elektroměr, jehož komunikace je popsána v normě ČSN EN 62056-21. Komunikace je rozdělená na pomyslné pakety, které mohou být částečně binární, protože kontrolní BCC znak může nabývat libovolné hodnoty.

    Protože komunikace po sériové lince není rozdělena na zprávy, musí komunikující program rozpoznat jednotlivé pakety v bloku dat načtených prostřednictvím sériového rozhraní. Úloha více-méně odpovídá identifikaci terminálních symbolů ve zdrojovém řetězci.

    Yapgen byl využit jako rozpoznávač těchto terminálních symbolů, a z vygenerovaného C/C++ souboru byla použita jeho část popisující lexikální analyzátor. Vygenerovaný kód se používá jako součást firmware vyvinutého elektroměru. Soubor popisující pravidla pro rozpoznání jednotlivých paketů v rámci komunikace je k nalezení zde.

    Programovací jazyk uclang

    Protože jsem byl mladý a zvědavý jal jsem se prostřednictvím programu yapgen vytvořit skriptovací jazyk. Tento jazyk v průběhu let evolvoval do použitelného stavu. K dnešnímu dni je využíván v reálných aplikacích nasazených na embedded zařízeních a v implementaci serverového řešení pro sběr dat a jejich vyhodnocování.

    Jsem si samozřejmě vědom argumentů typu: není potřeba další skriptovací jazyk, vše je již vyřešeno a děláš zbytečnou práci. Jelikož vývoj jazyka začal ze zvědavosti, tak některé z výše uvedených argumentů postrádají smysl, ale protože se jazyk vyvinul v něco co je možné použít při řešení skutečných úloh pokusím se v některém z následujících blogů obhájit jeho místo na slunci.

    Jazyk uclang je používán k řešení úloh v praxi, a v rámci jeho implementace byl použit program yapgen. Následující překladače a nástroje byly při implementaci jazyka uclang vygenerovány pomocí programu yapgen.

    Uclang parser

    Překladač jazyka uclang: uclang_parser.

    JIT parser

    Překladač funkcí zapsaných v pseudo C jazyce: jit_parser. Rozpoznávač datového typu z jeho textového popisu jit_types.

    Generátor dokumentace z komentářů

    Nalezení komentáře ve zdrojovém souboru: docu_extract. Zpracování jednoho komentáře: docu_comment.

    JSON parser

    Překladač JSON zápisů pro jejich přímý import do objektů jazyka uclang: json.

    Code/decode parser

    Parser pro řetězec popisující binární data, do kterých budou převedeny objekty v rámci metod Pack.code#2 a Pack.decode#1: pack_code.

    Regexp parser

    Překladač pro regulární výrazy používané v programu yapgen, a také v modulu parser jazyka uclang: regexp.

    String format parser

    Překladač pro rozklad formátovacího řetězce používaného při formátování řetězců: string_format.

    To by měly být všechny výskyty překladačů generovaných pomocí programu yapgen vyskytující se v jazyce uclang.

           

    Hodnocení: 100 %

            špatnédobré        

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    Komentáře

    Vložit další komentář

    Bystroushaak avatar 6.6.2015 20:45 Bystroushaak | skóre: 36 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Pěkné, dal jsem tučňáka.
    6.6.2015 23:43 Radek Miček | skóre: 23 | blog: radekm_blog
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Samotný jazyk je popsán SLR(1) gramatikou, která je dostatečně silná pro popis obecného programovacího jazyka.
    To znamená odstranit konflikty z gramatiky? To není příliš pohodlné, ne?
    7.6.2015 02:47 Ivorne | blog: Ivorne
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Já si ani nemyslím, že by LALR gramatiky byly z praktického hlediska o tolik silnější.
    7.6.2015 07:01 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: Yapgen - parser generator

    Ano to je pravda je nutné vyřešit SLR(1) konflikty vznikající v rozkladové tabulce. SLR(1) gramatika byla zvolena jako dostačující pro řešení původní úlohy v rámci které program yapgen vznikl.

    Bedňa avatar 6.6.2015 23:49 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Fajn len by potešil príklad z praxe.
    Od té doby jsem jej párkrát využil při implementaci úkolů se kterými jsem se setkal v praxi.
    KERNEL ULTRAS video channel >>>
    7.6.2015 09:21 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: Yapgen - parser generator

    Rozšířil jsem zápisek o pár příkladů z praxe.

    Bedňa avatar 8.6.2015 23:13 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Dík moc.
    KERNEL ULTRAS video channel >>>
    xkucf03 avatar 7.6.2015 12:18 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše C vs. C/C++

    BTW: když píšeš „C/C++“, co to znamená? Umí to generovat zdroják v obou jazycích nebo to generuje C, které se dá přeložit i kompilátorem pro C++?

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    7.6.2015 15:14 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: C vs. C/C++

    Třetí možnost je správně: generuje to zdrojový soubor pro kompilátor C++, kde z C++ jsou používány následující funkce, které nebyly součástí jazyka C: metody ve strukturách (třídách), reference, datový typ bool, výčtový typ, a možná některé další.

    Ale to není tak důležité, protože v případě potřeby je možné vygenerovat výsledný zdrojový soubor v libovolném jazyce (dostatečně silném). Tvrdá práce: generování DFA (Deterministický Konečný Automat) a LALR tabulky je již hotová a generování C/C++ souboru je v podstatě jen export algoritmů na těmito dvěma strukturami.

    Příklady vygenerovaných .cc souborů odpovídajících překladačům popsaným v kapitolce "Příklad tvorby překladače" je uveden na: 1, 2, 3.

    Uvedené soubory obsahují dvě základní funkce recognize_terminal a parser_parse_source_string, které dělají všechnu práci.

    7.6.2015 13:28 Odin1918 | skóre: 6 | blog: Valhalla
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Je to OT, ale proc zmizel posledni Leosuv blog? Cenzura?
    xkucf03 avatar 7.6.2015 13:32 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Leošův zápisek

    To je mi dost divné. Sice nebyl nijak moc kvalitní, v podstatě o ničem, ale zápisky Miriam tu taky zůstávají (byť třeba ne na titulní stránce). A protože pod ním byly komentáře, nemohl ho běžný uživatel (jako autor) smazat. Leoš asi není běžný uživatel…

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    Luboš Doležel (Doli) avatar 8.6.2015 16:48 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
    Rozbalit Rozbalit vše Re: Leošův zápisek
    Tuhle operaci může udělat jen uživatel root. Pokusím se zjistit, co se stalo.
    Luboš Doležel (Doli) avatar 8.6.2015 17:05 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
    Rozbalit Rozbalit vše Re: Leošův zápisek
    Bohužel jsem neviděl tu cache, ale podle logu mazání provedu uživatel číslo 1. Takže autor.
    7.6.2015 14:18 manasekp | skóre: 29 | blog: manasekp | Brno
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Taky jsem si toho vsiml. V google cache to jeste je.
    BIOKOMP | Cas od casu se pokousim nekoho srazit k zemi abych se tam nevalel sam.
    Bystroushaak avatar 7.6.2015 14:43 Bystroushaak | skóre: 36 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    xkucf03 avatar 7.6.2015 15:40 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše A sklep máte?

    Ad patička:

    Výhodná nabídka; Romantická kvelbená kóje v Kyjově (se záchodem!)

    To je včetně toho pozemku nad tím nebo to je cena jen za díru v zemi a ty cihly? Kupuješ? Podle kabelů to vypadá, že elektřina tam je. Šlo by tam udělat datacentrum a menší kancelář. Na zahradě by se postavil stožár a bylo by :-)

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    Bystroushaak avatar 7.6.2015 18:01 Bystroushaak | skóre: 36 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: A sklep máte?
    Kupuješ?
    Spíš jsem chtěl morálně podpořit majitele v jeho originálně snaze prodat kvelbenou kóji.
    Petr Tomášek avatar 9.6.2015 10:54 Petr Tomášek | skóre: 39 | blog: Vejšplechty
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    ani to už ne...
    multicult.fm | monokultura je zlo | welcome refugees!
    8.6.2015 13:09 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Já bych dal nedostatečou, protože používáš "unsigned" tam, kde se hodí a je více správné použít "size_t". Např. na platformě, kde je numeric_limit<unsigned>::max() 0xffff a numeric_limit<size_t>::max() 0xffffffffffffffff, tak příliš omezuješ. Na platformě, kde je to zase naopak, zase "lžeš", protože tvrdíš, že dokážeš pracovat s něčím, co nejde naalokovat. (to, že takovou platformu neznáš, nebo že není, nikoho neomlouvá). Třeba na ČVUT v různých předmětech programování dávají nedostatečnou za jednu chybu běžně. A tohle chyba je. Ale nic si z toho nedělej, i často používané knihovny, jako je Qt, jsou plné chyb. Např. Qt tvrdí, že dokáže ze souboru do paměti načíst numeric_limit<int64_t>::max() bytů i na x86-32, přitom to neumí.
    Bystroushaak avatar 8.6.2015 13:26 Bystroushaak | skóre: 36 | blog: Bystroushaakův blog | Praha
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    A poslal jsi patch?

    Jak jde jinak život?
    8.6.2015 16:10 zuzanak | skóre: 10 | blog: zuzanak
    Rozbalit Rozbalit vše Re: Yapgen - parser generator

    Nepochybně máš pravdu, bohužel jsem si zvykl používat základní datové typy tak, že počítám s platností následujících tvrzení:

    sizeof(void *)        == sizeof(long unsigned)
    sizeof(int)           == 4
    sizeof(unsigned)      == 4
    sizeof(char)          == 1
    sizeof(long long int) == 8
    sizeof(float)         == 4
    sizeof(double)        == 8

    A až narazím na platformu, na které to nebude platit, tak si budu trhat vlasy a vzpomenu si na tebe.

    8.6.2015 23:38 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    sizeof(void *) == sizeof(long unsigned)
    Tohle třeba neplatí na Windows, teda né že mi Windows není ukradenej, ale stejně. Pro nějaké takové prasárničky typu pointer na číslo existuje (u)intptr_t.
    sizeof(unsigned) == 4
    S tímhle nepochodíš na různých mikroprocesorech. Na těch "hloupých" typu atmega, to je např. 2.
    sizeof(char) == 1
    Tohle platí vždycky. Ať už má char 8 nebo 256 bitů, pořád to 1 byte, protože byte je totéž co char.
    vlastikroot avatar 8.6.2015 18:44 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator

    Je neco spatnyho na tom, ze vubec nepouzivam size_t a vsechny velikosti mam pevne omezene napr. uint8_t nebo int64_t a naprosto ignoruju architekturu? Mam porad trochu problem s endianness, ale jinak se muzu spolehnout, ze bude kod fungovat vsude stejne (hlavne na 8bit AVR).

    Uplne jsem ale prestal pouzivat packed struktury, to je zlo.

    We will destroys the Christian's legion ... and the cross, will be inverted
    8.6.2015 23:46 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Pokud program běží na ne-POSIX systému či nějaké té zvláštní architektuře, tak tvé číselné typy nemusí existovat. Chceš-li zaručit kompatibilitu, měl bys použít (u)int_leastN_t typ (kde N je těch 8, 16, 32, 64), které musí existovat a zároveň jsou to nejmenší typy, které mohou nabývat požadovaných hodnot, mohou ale nabývat i více, takže je třeba maskovat některé bitové operace. Popř. jejich fast verze, které jsou "rychlé", ale nejsou nejmenší. Na platformách, kde např. existuje uint8_t bude uint_least8_t stejný typ jako uint8_t. Na POSIX systémech uint8_t existovat bude (protože ty vyžadují 8bit char).

    Ano, packed struktury jsou zlo. Proto je lepší rozvrhnout prvky od největšího po nejmenší, tak aby nevznikaly zbytečné paddingy. Taky je ale dobré u větších struktur uvažovat cacheline procesoru a nerozhazovat často používané prvky na různá místa a dělat kompromisy.
    Bedňa avatar 8.6.2015 23:54 Bedňa | skóre: 34 | blog: Žumpa | Horňany
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Takže navrhuješ overovanie typov podľa architektúry, alebo pretekanie premenných podľa architektúry?
    KERNEL ULTRAS video channel >>>
    9.6.2015 00:24 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Proč? Potřebuju-li velikost něčeho co rvu do paměti, vím, že size_t pro to stačí. Potřebuju-li něco s nějakou minimální velikostí, použiju jeden z (u)int_leastN_t typů, pro ukládání bytů použiju char/unsigned char (popř. uint_least8_t, nebo dokonce uint8_t pokud jsem si 100% pokuď vyžaduju 8bit char a tento požadavek uvedu někde třeba v dokumentaci). A nebo použiju i ty základní typy, unsigned má garanci (2^16-1) a více, size_t taky, unsigned long long má garanci (2^64-1), atd, stačí si najít minimální rozsahy a použít typ, co se hodí nejvíce k danému účelu. Konstanty v limits.h (popř climits) lze použít i pro podmíněnou kompilaci, nevidím problém v tom je použít, k tomu přeci jsou.
    vlastikroot avatar 9.6.2015 18:26 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator

    A co kdyz nemam vubec problem s minimalni velikosti, ale potrebuju presne urcite nasobky 8bitu? Napr. kdyz zpracovavam HW udaje a potrebuju 1:1 bitovou reprezentaci. Nebo treba kdyz rozebiram a skladam sitove pakety.

    Taky moc se mi nelibi, ze bych vsude psal uint_least32_t misto uint32_t, je to delsi zapis a neprinasi funkcionalitu ani prehlednost.

    We will destroys the Christian's legion ... and the cross, will be inverted
    10.6.2015 21:11 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    A co kdyz nemam vubec problem s minimalni velikosti, ale potrebuju presne urcite nasobky 8bitu? Napr. kdyz zpracovavam HW udaje a potrebuju 1:1 bitovou reprezentaci. Nebo treba kdyz rozebiram a skladam sitove pakety.
    Na platformě, kde neexistuje 8bit typ toho nedocílíte a musíte použít typ větší (a třeba z něho použít jen 8 bitů, to je na vás) a na platformě, kde existuje, tak ho použijete. A když ho vyžadujete, tak není problém otestovat, jestli je nadefinováno nějaké UINTN_MAX makro a kydnout tam #error s vysvětlením proč a co, než nechat kompilaci selhat na nějaké chybě, která třeba nic neřekne potenciálnímu "kompilovači" vašeho kódu. A jestli se vám zdají jména dlouhé, tak použijte kratší, jazyk k tomu poskytuje prostředky (typedef, using).
    vlastikroot avatar 10.6.2015 21:42 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Na jake platforme neexistuje 8bit? Da se k takove realne dostat jako obycejny smrtelnik?
    We will destroys the Christian's legion ... and the cross, will be inverted
    Luboš Doležel (Doli) avatar 11.6.2015 13:31 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Mám pocit, že tohle má jen 16bitový datový typ (je v tom nějaký Analog Devices DSP), takže i ASCII stringy mají 16 bitů na znak. Portoval jsem z toho kód na Android a bylo to někdy docela peklo.
    vlastikroot avatar 11.6.2015 17:45 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    DSP bych do toho nepocital, to by me nikdy nenapadlo, ze by muj kod mohl bezet na DSP. Je urcen pouze pro MCU a CPU.
    We will destroys the Christian's legion ... and the cross, will be inverted
    11.6.2015 15:15 deda.jabko | skóre: 23 | blog: blog co se jmenuje "každý den jinak" | za new york city dvakrát doleva a pak už se doptáte
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Na platformě, kde neexistuje 8bit typ toho nedocílíte a musíte použít typ větší (a třeba z něho použít jen 8 bitů, to je na vás) a na platformě, kde existuje, tak ho použijete.

    Toto je naprosto absurdni situace, ktera by mohla nastat v drevnich dobach pocitacu typu PDP-XY, kdy jeste nebyl byte obecne prijatou jednotkou pro ulozeni informace a velikost slova byla definovana moznostmi hardwaru.

    Napr. architektura SPARC nebo treba JVM pracuji interne s 32bitovyma hodnotama a jen pri praci s pameti vyuzivaji typy s mensim rozsahem... a nikomu to vetsi problemy necini, protoze prekladac se o to postara sam.
    Asi před rokem se dostali hackeři na servry Debianu a ukradli jim zdrojové kódy.
    11.6.2015 16:32 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Jde hlavně o překladač, ano. Klidně bych teď mohl napsat C kompilátor (kdybych měl čas), který na x86 bude mít 16bit char a váš kód tam pak klekne na obskurní chybě, protože je tu váš předpoklad, že máte 8bit char, který však nikde neuvedete a nikde ho nevynucujete, popř. neuvede jiný předpoklad, který ho implikuje (třeba POSIX).
    vlastikroot avatar 11.6.2015 17:38 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Na takovej kompilator se muzu vykaslat. U nekterych projektu kaslu i na ten microsofti.
    We will destroys the Christian's legion ... and the cross, will be inverted
    xkucf03 avatar 11.6.2015 20:50 xkucf03 | skóre: 49 | blog: xkucf03
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    kdybych měl čas

    Čemu se teď vlastně věnuješ? Nechceš se někdy rozepsat v blogu?

    Mám rád, když se lidé přou, znamená to, že vědí, co dělají, a že mají směr. Frantovo.cz, SQL-DK, Relational pipes
    11.6.2015 22:08 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Věnuju se úvaze o důvodu mého bytí. Věnuju se opakováním, že nemám na nic čas, přitom vůbec nic nedělám. Momentálně to mám disassemblerovanou binárku jedný hry, skládám z toho zdrojový kód v C++. Pak tu překládám bytecode z lua skriptů zpět na skripty, který musí dát opět schodný bytecode. No a tímhle trávím celý den, a proto nemám na nic čas. Taky jsem potřeboval jít k doktorovi, protože mám zánět předkožky (asi mi to tam začíná hnít, protože neprovozuji pohlavní styk), ale nemám na něj. Takže si dvacetkrát denně omývám bimbase a doufám, že to zmizí. A když ne, tak mi asi upadne.
    11.6.2015 22:12 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    A pořád uvažuji, co mám jít dělat. Pořád si nevím rady jak a kde si najít práci. Já se ani nemám jít kam podívat, na cestu daleko nemám a do tří hodin pěšky toho tu moc není (3+3 hodiny cesta, 8 hodin práce a 8 hodin spánek, 1 hodina snídaně a výprava do práce, 1 hodina mytí a příprava na spánek = 24hod).
    11.6.2015 22:14 Jardík
    Rozbalit Rozbalit vše Re: Yapgen - parser generator
    Jó a ještě mám pořád problém s tím varletem, to taky zlobí. A pak ještě začíná bolet ten zub, jak mám 2 roky vypadlou plombu.

    Založit nové vláknoNahoru

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.