Flex lexical analyser

Technology
12 hours ago
8
4
2
Avatar
Author
Albert Flores

Flex lexical analyser je v informatice nástroj, který generuje zdrojový kód pro lexikální analyzátor v jazyce C. Jde o GNU variantu programu Lex. Používá se často spolu s generátorem syntaktického analyzátoru yacc nebo jeho vylepšenou alternativou GNU bison. Flex byl vytvořen Vernem Paxsonem v jazyce C v roce 1987. Byl překládán pomocí Ratfor generátoru, který byl v té době veden Jefem Poskanzerem.

Existuje podobný nástroj pro jazyk C++, který se jmenuje flex++, který je součástí balíčku Flex. V současné době Flex podporuje generování kódu pouze pro jazyky C a C++ (flex++). +more Vygenerovaný kód není závislý na žádné runtime nebo externí knihovně (s výjimkou paměťově alokované), pokud je na ní vstup také závislý. To může být užitečné v embedded systémech a podobných situacích, kde tradiční operační systém nebo C runtime zařízení nemusí být k dispozici.

Příklad lexikálního analyzátoru

Toto je příklad scanneru, který nevyužívá Flex pro naučný programovací jazyk PL/0. Uznávané symboly jsou: '+', '-', '*', '/', '=', '(', ')', ',', ';', '. +more', ':=', '', '', '', '>', '>='; čísla: 0-9 {0-9}; identifikátory: a-zA-Z {a-zA-Z0-9} a klíčová slova: begin, call, const, do, end, if, odd, procedure, then, var, while.

Užití externích proměnných:

FILE *source /* The source file */ int cur_line, cur_col, err_line, err_col /* For error reporting */ int num /* Last number read stored here, for the parser */ char id[] /* Last identifier read stored here, for the parser */ Hashtab *keywords

Volání externích rutin:

error(const char msg[]) /* Report an error */ Hashtab *create_htab(int estimate) /* Create a lookup table */ int enter_htab(Hashtab *ht, char name[], void *data) /* Add an entry to a lookup table */ Entry *find_htab(Hashtab *ht, char *s) /* Find an entry in a lookup table */ void *get_htab_data(Entry *entry) /* Returns data from a lookup table */ FILE *fopen(char fn[], char mode[]) /* Opens a file for reading */ fgetc(FILE *stream) /* Read the next character from a stream */ ungetc(int ch, FILE *stream) /* Put-back a character onto a stream */ isdigit(int ch), isalpha(int ch), isalnum(int ch) /* Character classification */

Externí typy:

Symbol /* An enumerated type of all the symbols in the PL/0 language */ Hashtab /* Represents a lookup table */ Entry /* Represents an entry in the lookup table */

Skenování je odstartováno voláním init_scan, který pochází ze zdrojového souboru. Pokud je zdrojový soubor úspěšně otevřen, parser zavolá getsym, který opakovaně vrací po sobě jdoucí symboly ze zdrojového souboru.

Srdce scanneru - getsym - by měl být přímočarý. Zaprvé by měl přeskočit všechny mezery. +more Dále jsou získané znaky klasifikovány. Jestliže znak reprezentuje více symbolů, musí se provést další zpracování. Čísla jsou převedena do vnitřní formy a identifikátory jsou kontrolovány, zda nejsou klíčovým slovem.

int read_ch(void) { int ch = fgetc(source); cur_col++; if (ch == '\n') { cur_line++; cur_col = 0; } return ch; }

void put_back(int ch) { ungetc(ch, source); cur_col--; if (ch == '\n') cur_line--; }

Symbol getsym(void) { int ch;

while ((ch = read_ch) != EOF && ch

'>') return neq; if (ch

'=') return leq; put_back(ch); return lss; case '>': ch = read_ch; if (ch == '=') return geq; put_back(ch); return gtr; default: if (isdigit(ch)) { num = 0; do { /* no checking for overflow. */ num = 10 * num + ch - '0'; ch = read_ch; } while ( ch . +more= EOF && isdigit(ch)); put_back(ch); return number; } if (isalpha(ch)) { Entry *entry; id_len = 0; do { if (id_len .

Nyní můžete porovnat kód, který byl vygenerovaný Flexem s ručně psaným kódem.

%{ #include "y.tab.h" %}

digit [0-9] letter [a-zA-Z]

%% "+" { return PLUS; } "-" { return MINUS; } "*" { return TIMES; } "/" { return SLASH; } "(" { return LPAREN; } ")" { return RPAREN; } ";" { return SEMICOLON; } "," { return COMMA; } ". " { return PERIOD; } ":=" { return BECOMES; } "=" { return EQL; } "" { return NEQ; } "" { return GTR; } "=" { return GEQ; } "begin" { return BEGINSYM; } "call" { return CALLSYM; } "const" { return CONSTSYM; } "do" { return DOSYM; } "end" { return ENDSYM; } "if" { return IFSYM; } "odd" { return ODDSYM; } "procedure" { return PROCSYM; } "then" { return THENSYM; } "var" { return VARSYM; } "while" { return WHILESYM; } {letter}({letter}|{digit})* { yylval. +moreid = (char *)strdup(yytext); return IDENT; } {digit}+ { yylval. num = atoi(yytext); return NUMBER; } [ \t\n\r] /* skip whitespace */ . { printf("Unknown character [%c]\n",yytext[0]); return UNKNOWN; } %%.

int yywrap(void){return 1;}

Přibližně 50 řádků kódu Flex versus 100 řádků ručně psaného kódu.

Flex++

Flex++ je nástroj pro vytváření programu pro parsování jazyka. Tento program vytváří parser generátor. Toto je hlavní instance programu Flex.

Tyto programy fungují jako parséry znaků a tokenů pomocí použití deterministického konečného automatu. Tento stroj je podmnožinou Turingových strojů. +more Syntaxe je založená na použití regulárních výrazů.

Flex nabízí dva různé způsoby, jak generovat scannery. Primárně generuje kód jazyka C kompilovaný do C++ knihoven. +more Flex++, rozšíření Flexu, se používá pro generování C++ kódu a tříd. Flex++ třídy a kód vyžadují kompilátor pro vytvoření lexikálních programů a programů porovnávajících vzory. Flex, alternativní jazykový parser, zanedbává generovaní parsovacího scanneru v C kódu. C++ scanner generovaný pomocí Flex++ obsahuje hlavičkový soubor FlexLexer. h, který definuje rozhraní dvou C++ generovaných tříd.

Související články

Lex (software)

Externí odkazy

[url=http://www. root. +morecz/clanky/flex-fast-lexical-analyzer-generator/]Článek „fast lexical analyzer generator“[/url] na root. cz * [url=http://sweb. cz/malyzelenyhnus/flex/flex. html]Článek o flexu[/url] * [url=http://www. gnu. org/software/flex/]Originální dokumentace[/url].

5 min read
Share this post:
Like it 8

Leave a Comment

Please, enter your name.
Please, provide a valid email address.
Please, enter your comment.
Enjoy this post? Join Cesko.wiki
Don’t forget to share it
Top