Re2c

Re2c
Typ bezplatný a open source software a generátor lexikálního analyzátoru [d]
Zapsáno v C a C++
Operační systém multiplatformní
První vydání 1994 [1]
Nejnovější verze
Stát aktivní
webová stránka re2c.org
 Mediální soubory na Wikimedia Commons

re2c ( r egular e xpression t o c , r egular e xpression t o kod ) je bezplatný open source generátorový nástroj , který generuje rychlé a snadno vložitelné lexery orientované na práci s jazyky: C , C++ , Go , Rust .

Nástroj byl původně vytvořen Peterem  Bumbulisem a popsán ve svém článku [3] , později byl re2c uvolněn do veřejné domény a od té doby je spravován dobrovolníky [4] .

Nástroj se liší od svých známějších analogů (jako je lex a flex ) v tom, že má flexibilní interakční rozhraní (vygenerovaný kód interaguje s externím programem pomocí primitiv), generuje optimalizované netabulkové lexery, podporuje capture (extrakce submatch ) založené na deterministických konečných automatech s tagy (TDFA).

Nástroj se používá hlavně v projektech, kde je vyžadována vysoká rychlost syntaxe , jako je Ninja [5] a PHP [6] .

Filosofie

Hlavním cílem re2c je generovat rychlé lexery [3] , které jsou alespoň tak rychlé jako rozumně optimalizované ručně psané C lexery . Namísto použití tradičního tabulkového přístupu kóduje re2c vygenerovaný stavový stroj přímo ve formě podmínek a srovnání. Výsledkem je, že program je rychlejší než jeho tabulkový protějšek [3] a mnohem snadněji se ladí a rozumí. Navíc tento přístup často vede k menším lexerům [3] , protože re2c používá řadu optimalizací, jako je minimalizace DFA a konstrukce tunelových automatů [7] . Další skvělou vlastností re2c je jeho flexibilní rozhraní. Namísto použití fixní šablony programu umožňuje re2c programátorovi napsat většinu kódu rozhraní a přizpůsobit vygenerovaný lexer libovolnému danému prostředí. Hlavní myšlenkou je, že re2c by mělo být pro programátora abstrakcí s nulovými náklady a použití nástroje by nikdy nemělo způsobit pomalejší běh programu než odpovídající ručně kódovaná implementace.

Funkce

Implementace je založena na algoritmu "lookahead-TDFA" [10] [11] [12] ;

Syntaxe

Program re2c může obsahovat libovolný počet /*!re2c ... */bloků. Každý blok se skládá z posloupnosti pravidel, definic a konfigurací (lze je kombinovat, ale obvykle je nejlepší dát nejprve konfigurace, pak definice a pak pravidla). Pravidla mají tvar - REGEXP { CODE }nebo REGEXP := CODE;, kde REGEXPje regulární výraz a CODE- je blok kódu C. Když REGEXPse shoduje se vstupním řetězcem, řídicí tok se přenese do odpovídajícího bloku CODE. Existuje jedno speciální pravidlo: výchozí pravidlo s *namísto REGEXP, spustí se, pokud žádná jiná pravidla neodpovídají. re2c má sémantiku chamtivé shody – pokud se shoduje více pravidel, upřednostňuje se pravidlo odpovídající delší předponě, pokud konfliktní pravidla odpovídají stejné předponě, pak má přednost dřívější pravidlo. Definice mají formu NAME = REGEXP;(a podle toho NAME { REGEXP }v režimu kompatibilním s Flex). Konfigurace mají tvar re2c:CONFIG = VALUE;, kde CONFIGje název konkrétní konfigurace a VALUEje to buď číslo nebo řetězec. Pro pokročilejší použití nahlédněte do oficiálního manuálu re2c [20] .

Regulární výrazy

re2c používá pro regulární výrazy následující syntaxi:

Třídy znaků a řetězcové literály mohou obsahovat následující sekvence escape: \a, \b, \f, \n, \r, \t, \v, \\, osmičkové \oooa šestnáctkové \xhh, \uhhhh, \Uhhhhhhhh.

Příklady kódu

Příklady programů v různých jazycích

Následuje příklad jednoduchého programu re2c v souboru example.re . Kontroluje, že všechny vstupní argumenty jsou desetinná čísla. Kód pro re2c je zarámován v komentářích /*!re2c ... */[21] .

C :

// re2c $INPUT -o $OUTPUT -i --case-ranges #include <assert.h> bool lex ( const char * s ) { const char * YYCURSOR = s ; /*!re2c re2c:yyfill:enable = 0; re2c:define:YYCTYPE = char; číslo = [1-9][0-9]*; číslo { return true; } * { return false; } */ } int main () { tvrdit ( lex ( "1234" )); návrat 0 ; }

Vzhledem k tomu, že příkaz $ re2c -is -o example.c example.regeneruje níže uvedený kód ( example.c ). Obsah komentáře /*!re2c ... */je nahrazen deterministickým konečným automatem zakódovaným jako podmíněné skoky a porovnání, zbytek programu je doslovně zkopírován do výstupního souboru. Existuje několik možností pro generování kódu, obvykle re2c používá operátor switch, ale může používat vnořené operátory if(jako v tomto příkladu s volbou -s) nebo generovat bitmapy a tabulky skoků . Která možnost je lepší závisí na kompilátoru C , uživatelům re2c se doporučuje experimentovat.

/* Generováno re2c */ // re2c $INPUT -o $OUTPUT -i --case-ranges #include <assert.h> bool lex ( const char * s ) { const char * YYCURSOR = s ; { char yych ; yych = * YYCURSOR ; přepínač ( yych ) { případ '1' ... '9' : goto yy2 ; výchozí : goto yy1 ; } yy1 : ++ YYCURSOR ; { return false ; } yy2 : yych = *++ YYCURSOR ; přepínač ( yych ) { případ '0' ... '9' : goto yy2 ; výchozí : goto yy3 ; } yy3 : { return true ; } } } int main () { tvrdit ( lex ( "1234" )); návrat 0 ; }

jít :

//go:generate re2go $INPUT -o $OUTPUT -i hlavní balíček func lex ( str řetězec ) { var kurzor int /*!re2c re2c:define:YYCTYPE = byte; re2c:define:YYPEEK = "str[kurzor]"; re2c:define:YYSKIP = "kurzor += 1"; re2c:yyfill:enable = 0; číslo = [1-9][0-9]*; číslo { vrátit } * { panika("chyba!") } */ } func main () { lex ( "1234\x00" ) } // Kód vygenerovaný re2c, NEUPRAVUJTE. //go:generate re2go $INPUT -o $OUTPUT -i hlavní balíček func lex ( str řetězec ) { var kurzor int { var yych byte yych = str [ kurzor ] přepínač ( yych ) { velikost písmen '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' : goto yy2 výchozí : goto yy1 } yy1 : kurzor += 1 { panika ( "chyba!" ) } yy2 : kurzor += 1 yych = str [ kurzor ] přepínač ( yych ) { velikost písmen '0' , '1' , '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' : goto yy2 výchozí : goto yy3 } yy3 : { vrátit } } } func main () { lex ( "1234\x00" ) }

Rez :

// re2rust $INPUT -o $OUTPUT fn lex ( s : & [ u8 ]) -> bool { nech mut kurzor = 0 ; /*!re2c re2c:define:YYCTYPE = u8; re2c:define:YYPEEK = "*s.get_unchecked(kurzor)"; re2c:define:YYSKIP = "kurzor += 1;"; re2c:yyfill:enable = 0; číslo = [1-9][0-9]*; číslo { return true; } * { return false; } */ } fn main () { tvrdit! ( lex ( b"1234 \0 " )); } /* Generováno re2c */ // re2rust $INPUT -o $OUTPUT fn lex ( s : & [ u8 ]) -> bool { nech mut kurzor = 0 ; { #[allow(unused_assignments)] nech mut yych : u8 = 0 ; let mut yystate : useize = 0 ; ' yyl : smyčka { stav shody { 0 => { yych = nebezpečné { * s . get_unchecked ( kurzor )}; kurzor += 1 ; odpovídat yych { 0x31 ..= 0x39 => { yystate = 2 ; pokračovat 'yyl ; } _ => { yystate = 1 ; pokračovat 'yyl ; } } } 1 => { return false ; } 2 => { yych = nebezpečné { * s . get_unchecked ( kurzor )}; odpovídat yych { 0x30 .. = 0x39 _ kurzor += 1 ; yystate = 2 ; pokračovat 'yyl ; } _ => { yystate = 3 ; pokračovat 'yyl ; } } } 3 => { return true ; } _ => { panika! ( "interní chyba lexera" ) } } } } } fn main () { tvrdit! ( lex ( b"1234 \0 " )); }

Softwarové projekty využívající re2c

Viz také

Poznámky

  1. (nespecifikovaný název) - doi:10.1145/176454.176487
  2. https://github.com/skvadrik/re2c/releases/tag/3.0 - 2022.
  3. 1 2 3 4 Bumbulis Peter , Donald D. Cowan. RE2C: všestrannější generátor skenerů (anglicky)  // Association for Computing Machinery, New York, NY, Spojené státy americké: časopis. - 1993. - 3-12 ( vol. 2 , č. 1-4 ). - S. 70-84 . ISSN 1057-4514 . doi : 10.1145 / 176454.176487 .  
  4. re2c:  autoři . Získáno 11. února 2022. Archivováno z originálu dne 21. července 2011.
  5. 1 2 Ninja : build.ninja  . Ninja. Získáno 11. února 2022. Archivováno z originálu dne 5. května 2022.
  6. 1 2 Vytváření PHP  . Interní kniha PHP. Získáno 11. února 2022. Archivováno z originálu dne 8. května 2021.
  7. Joseph Grosch. Efficient Generation of Table-Driven Scanners  (anglicky)  // Software: Practice and Experience 19 : magazine. - 1989. - S. 1089-1103 .
  8. Extrakce submatch,  dokumentace re2c . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  9. Ville Laurikari. NFA s tagovanými přechody, jejich převod na deterministické automaty a aplikace na regulární výrazy  //  Seventh International Symposium on String Processing and Information Retrieval, 2000. SPIRE 2000. Proceedings. : časopis. - 2000. Archivováno 8. února 2022.
  10. Ulya Trofimovich (2017). „Označené deterministické konečné automaty s výhledem dopředu“. arXiv : 1907.08837 .
  11. Ulja Trofimovič. RE2C - generátor lexerů založený na dopředném TDFA  //  Software Impacts: magazine. - 2020. - Sv. 6 . - doi : 10.1016/j.simpa.2020.100027 .
  12. Ulya, Trofimovich Lookahead TDFA v obrazech (slides)  (anglicky) (PDF) (2021). Získáno 11. února 2022. Archivováno z originálu dne 27. ledna 2022.
  13. re2c:  Podpora kódování . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  14. re2c:  Rozhraní programu . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  15. ↑ re2c : Uložitelný stav  . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  16. re2c:  Podmínky spuštění . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  17. re2c:  Kostra . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  18. re2c:  Varování . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  19. ↑ Vizualizace , dokumentace re2c  . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  20. re2c: Uživatelská příručka (C  ) . Získáno 11. února 2022. Archivováno z originálu 31. ledna 2022.
  21. re2c . Získáno 11. února 2022. Archivováno z originálu 16. února 2022.
  22. SpamAssassin (sa-compile  ) . Získáno 11. února 2022. Archivováno z originálu dne 20. ledna 2022.
  23. BRL-CAD (nástroje: re2c  ) . Získáno 11. února 2022. Archivováno z originálu dne 11. února 2022.
  24. Proces  sestavení . Získáno 11. února 2022. Archivováno z originálu dne 20. ledna 2022.
  25. Projekt Yasm Modular Assembler: Klíčové vnitřní  vlastnosti . Získáno 11. února 2022. Archivováno z originálu dne 20. ledna 2022.
  26. probuď se  . _ Získáno 11. února 2022. Archivováno z originálu dne 11. února 2022.

Odkazy