%top { #include "grammar.h" } %{ #include <assert.h> #include <stdbool.h> #include <stdlib.h> /* Tête de lecture pour conversions */ typedef union _read_ptr_t { const uint8_t *byte_pos; /* Lecture par blocs de 8 bits */ const uint16_t *hword_pos; /* Lecture par blocs de 16 bits*/ } read_ptr_t; #if __BYTE_ORDER == __LITTLE_ENDIAN # define MAKE_HWORD(ch1, ch2) ((uint16_t)(ch2 << 8 | ch1)) #elif __BYTE_ORDER == __BIG_ENDIAN # define MAKE_HWORD(ch1, ch2) ((uint16_t)(ch1 << 8 | ch2)) #else /* __PDP_ENDIAN et Cie... */ # error "Congratulations! Your byte order is not supported!" #endif /****************************************************************************** * * * Paramètres : src = liste d'octets à traiter. * * len = taille de cette liste. * * out = série d'octets bruts obtenue. [OUT] * * * * Description : Transcrit une série d'octets en en remplaçant certains. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void rost_unescape_string(const char *src, size_t len, sized_string_t *out) { read_ptr_t reader; /* Tête de lecture */ const bin_t *max; /* Fin du parcours */ uint16_t half; /* Moitié de mot */ bin_t byte; /* Octet à analyser */ bin_t *writer; /* Tête d'écriture */ reader.byte_pos = (const uint8_t *)src; max = reader.byte_pos + len; writer = out->bin_data; while (reader.byte_pos < max) { /** * La lecture par groupes de deux octets n'est pas forcément toujours * logique : pour "\nabc", la dernière lecture va considérer 'c"', * incluant ainsi le caractère '"' qui a été écarté pour l'appel. * * Le code est cependant suffisamment souple pour ignore le superflu. */ switch (*reader.hword_pos) { case MAKE_HWORD('\\', 'a'): reader.hword_pos++; *writer++ = '\a'; break; case MAKE_HWORD('\\', 'b'): reader.hword_pos++; *writer++ = '\b'; break; case MAKE_HWORD('\\', 't'): reader.hword_pos++; *writer++ = '\t'; break; case MAKE_HWORD('\\', 'n'): reader.hword_pos++; *writer++ = '\n'; break; case MAKE_HWORD('\\', 'v'): reader.hword_pos++; *writer++ = '\v'; break; case MAKE_HWORD('\\', 'f'): reader.hword_pos++; *writer++ = '\f'; break; case MAKE_HWORD('\\', 'r'): reader.hword_pos++; *writer++ = '\r'; break; case MAKE_HWORD('\\', 'e'): reader.hword_pos++; *writer++ = '\e'; break; case MAKE_HWORD('\\', '"'): reader.hword_pos++; *writer++ = '\"'; break; case MAKE_HWORD('\\', '\\'): reader.hword_pos++; *writer++ = '\\'; break; case MAKE_HWORD('\\', 'x'): reader.hword_pos++; /** * Le jeu des expressions régulières qui amène à l'appel de * cette fonction limite les caractères possibles à trois * ensembles : chiffres et lettres en majuscules et minuscules. * * La bascule des lettres en minuscules ramène les possibles * à deux ensembles uniquement, simplifiant ainsi les règles * de filtrage : aucun switch case n'est ainsi requis ! */ half = *reader.hword_pos++; #if __BYTE_ORDER == __LITTLE_ENDIAN byte = (half & 0xff); #elif __BYTE_ORDER == __BIG_ENDIAN byte = (half >> 8); #endif /* '0' ... '9' */ if (byte <= '9') *writer = (byte - '0'); /* 'A' ... 'F' || 'a' ... 'f' */ else { byte |= 0x20; *writer = 0xa + (byte - 'a'); } *writer <<= 4; #if __BYTE_ORDER == __LITTLE_ENDIAN byte = (half >> 8); #elif __BYTE_ORDER == __BIG_ENDIAN byte = (half & 0xff); #endif /* '0' ... '9' */ if (byte <= '9') *writer++ |= (byte - '0'); /* 'A' ... 'F' || 'a' ... 'f' */ else { byte |= 0x20; *writer++ |= 0xa + (byte - 'a'); } break; default: *writer++ = *reader.byte_pos++; break; } } out->len = writer - out->bin_data; } /****************************************************************************** * * * Paramètres : src = liste d'octets à traiter. * * len = taille de cette liste. * * out = série d'octets bruts obtenue. [OUT] * * * * Description : Transcrit une série d'octets en en remplaçant certains. * * * * Retour : - * * * * Remarques : - * * * ******************************************************************************/ static void rost_unescape_regex(const char *src, size_t len, sized_string_t *out) { read_ptr_t reader; /* Tête de lecture */ const bin_t *max; /* Fin du parcours */ uint16_t half; /* Moitié de mot */ bin_t byte; /* Octet à analyser */ bin_t *writer; /* Tête d'écriture */ reader.byte_pos = (const uint8_t *)src; max = reader.byte_pos + len; writer = out->bin_data; while (reader.byte_pos < max) { /** * La lecture par groupes de deux octets n'est pas forcément toujours * logique : pour "\nabc", la dernière lecture va considérer 'c"', * incluant ainsi le caractère '"' qui a été écarté pour l'appel. * * Le code est cependant suffisamment souple pour ignore le superflu. */ switch (*reader.hword_pos) { case MAKE_HWORD('\\', 'a'): reader.hword_pos++; *writer++ = '\a'; break; case MAKE_HWORD('\\', 'b'): reader.hword_pos++; *writer++ = '\b'; break; case MAKE_HWORD('\\', 't'): reader.hword_pos++; *writer++ = '\t'; break; case MAKE_HWORD('\\', 'n'): reader.hword_pos++; *writer++ = '\n'; break; case MAKE_HWORD('\\', 'v'): reader.hword_pos++; *writer++ = '\v'; break; case MAKE_HWORD('\\', 'f'): reader.hword_pos++; *writer++ = '\f'; break; case MAKE_HWORD('\\', 'r'): reader.hword_pos++; *writer++ = '\r'; break; case MAKE_HWORD('\\', 'e'): reader.hword_pos++; *writer++ = '\e'; break; case MAKE_HWORD('\\', '"'): reader.hword_pos++; *writer++ = '\"'; break; case MAKE_HWORD('\\', '\\'): reader.hword_pos++; *writer++ = '\\'; break; case MAKE_HWORD('\\', 'x'): reader.hword_pos++; /** * Le jeu des expressions régulières qui amène à l'appel de * cette fonction limite les caractères possibles à trois * ensembles : chiffres et lettres en majuscules et minuscules. * * La bascule des lettres en minuscules ramène les possibles * à deux ensembles uniquement, simplifiant ainsi les règles * de filtrage : aucun switch case n'est ainsi requis ! */ half = *reader.hword_pos++; #if __BYTE_ORDER == __LITTLE_ENDIAN byte = (half & 0xff); #elif __BYTE_ORDER == __BIG_ENDIAN byte = (half >> 8); #endif /* '0' ... '9' */ if (byte <= '9') *writer = (byte - '0'); /* 'A' ... 'F' || 'a' ... 'f' */ else { byte |= 0x20; *writer = 0xa + (byte - 'a'); } *writer <<= 4; #if __BYTE_ORDER == __LITTLE_ENDIAN byte = (half >> 8); #elif __BYTE_ORDER == __BIG_ENDIAN byte = (half & 0xff); #endif /* '0' ... '9' */ if (byte <= '9') *writer++ |= (byte - '0'); /* 'A' ... 'F' || 'a' ... 'f' */ else { byte |= 0x20; *writer++ |= 0xa + (byte - 'a'); } break; case MAKE_HWORD('\\', '{'): reader.hword_pos++; *writer++ = '{'; break; case MAKE_HWORD('\\', '}'): reader.hword_pos++; *writer++ = '}'; break; default: *writer++ = *reader.byte_pos++; break; } } out->len = writer - out->bin_data; } #define PUSH_STATE(s) yy_push_state(s, yyscanner) #define POP_STATE yy_pop_state(yyscanner) #define STOP_LEXER(msg, fbmsg) \ do \ { \ char *__text; \ int __ret; \ __ret = asprintf(&__text, "%s: '%s'", msg, yytext); \ if (__ret == -1) \ YY_FATAL_ERROR(fbmsg); \ else \ { \ YY_FATAL_ERROR(__text); \ free(__text); \ } \ } \ while (0) #define HANDLE_UNCOMPLETED_TOKEN \ STOP_LEXER("Uncompleted token in rule definition", "Undisclosed uncompleted token in rule definition") %} %option bison-bridge reentrant %option stack %option nounput %option noinput %option noyywrap %option noyy_top_state %option yylineno %option never-interactive %x inc_path %x rule_intro %x raw_block %x meta %x meta_value %x bytes %x bytes_value %x bytes_value_raw %x bytes_hex %x bytes_hex_range %x bytes_regex %x bytes_regex_quantifier %x bytes_regex_range %x condition %x wait_for_colon %x comment str_not_escaped [^\"\\] str_escaped \\a|\\b|\\t|\\n|\\v|\\f|\\r|\\e|\\\"|\\\\|\\x{hbyte} str_mixed ({str_not_escaped}|{str_escaped}) hbyte [0-9a-fA-F]{2} mbyte (\?[0-9a-fA-F]|[0-9a-fA-F]\?) reg_allowed [^^$.|/{}()\[\]*+?\\] reg_allowed_escaped \\^|\\$|\\\.|\\\||\\\/|\\\{|\\\}|\\\(|\\\)|\\\[|\\\]|\\\*|\\\+|\\\?|\\\\ reg_escaped \\a|\\t|\\n|\\v|\\f|\\r reg_byte \\x[0-9a-fA-F]{2} regular_chars {reg_allowed}|{reg_allowed_escaped}|{reg_escaped}|{reg_byte} reg_classes \\w|\\W|\\s|\\S|\\d|\\D|\\b|\\B bytes_id [A-Za-z_][A-Za-z0-9_]* bytes_fuzzy_id [\*A-Za-z_][\*A-Za-z0-9_]* %% "include" { PUSH_STATE(inc_path); return INCLUDE; } <inc_path>\"{str_not_escaped}+\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } <inc_path>\"{str_mixed}+\" { POP_STATE; rost_unescape_string(yytext + 1, yyleng - 2, tmp_0); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return ESCAPED_TEXT; } %{ /* Définition locale d'une règle */ %} "global" { return GLOBAL; } "private" { return PRIVATE; } "rule" { PUSH_STATE(rule_intro); return RAW_RULE; } <rule_intro>{bytes_id} { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return RULE_IDENTIFIER; } <rule_intro>":" { return COLON; } <rule_intro>[ \t]* { } <rule_intro>"{" { POP_STATE; PUSH_STATE(raw_block); return BRACE_IN; } <raw_block>"meta" { POP_STATE; PUSH_STATE(meta); PUSH_STATE(wait_for_colon); return META; } <raw_block,meta>"bytes" { POP_STATE; PUSH_STATE(bytes); PUSH_STATE(wait_for_colon); return BYTES; } <raw_block,meta,bytes>"condition" { POP_STATE; PUSH_STATE(condition); PUSH_STATE(wait_for_colon); return CONDITION; } <wait_for_colon>":" { POP_STATE; return COLON; } <raw_block,meta,bytes,condition>"}" { POP_STATE; return BRACE_OUT; } %{ /* Définitions communes pour la section "meta:" */ %} <meta>{bytes_id} { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return INFO_KEY; } <meta>"=" { PUSH_STATE(meta_value); return ASSIGN; } <meta_value>"true" { POP_STATE; return TRUE_; } <meta_value>"false" { POP_STATE; return FALSE_; } <meta_value>-(0|[1-9][0-9]*) { POP_STATE; yylval->signed_integer = strtoll(yytext, NULL, 10); return SIGNED_INTEGER; } <meta_value>-0x[0-9a-f]+ { POP_STATE; yylval->signed_integer = strtoll(yytext, NULL, 16); return SIGNED_INTEGER; } <meta_value>(0|[1-9][0-9]*) { POP_STATE; yylval->unsigned_integer = strtoull(yytext, NULL, 10); return UNSIGNED_INTEGER; } <meta_value>0x[0-9a-f]+ { POP_STATE; yylval->unsigned_integer = strtoull(yytext, NULL, 16); return UNSIGNED_INTEGER; } <meta_value>\"{str_not_escaped}*\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } <meta_value>\"{str_mixed}*\" { POP_STATE; rost_unescape_string(yytext + 1, yyleng - 2, tmp_0); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return ESCAPED_TEXT; } %{ /* A déplacer... */ %} <condition>"true" { return TRUE_; } <condition>"false" { return FALSE_; } <condition>-(0|[1-9][0-9]*) { yylval->signed_integer = strtoll(yytext, NULL, 10); return SIGNED_INTEGER; } <condition>-0x[0-9a-f]+ { yylval->signed_integer = strtoll(yytext, NULL, 16); return SIGNED_INTEGER; } <bytes_hex_range,bytes_regex_quantifier,condition>(0|[1-9][0-9]*) { yylval->unsigned_integer = strtoull(yytext, NULL, 10); return UNSIGNED_INTEGER; } <bytes_hex_range,bytes_regex_quantifier,condition>0x[0-9a-f]+ { yylval->unsigned_integer = strtoull(yytext, NULL, 16); return UNSIGNED_INTEGER; } <condition>[kK][bB] { return KB; } <condition>[mM][bB] { return MB; } <condition>[gG][bB] { return GB; } <condition>\"{str_not_escaped}*\" { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } <condition>\"{str_mixed}*\" { rost_unescape_string(yytext + 1, yyleng - 2, tmp_0); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return ESCAPED_TEXT; } %{ /* Définitions communes pour la section "bytes:" */ %} <bytes>"fullword" { return FULLWORD; } <bytes>"nocase" { return NOCASE; } <bytes>"private" { return PRIVATE; } <bytes>"=" { PUSH_STATE(bytes_value); return ASSIGN; } %{ /* Définition de motif en texte brut */ %} <bytes_value>\"{str_not_escaped}+\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } <bytes_value>\"{str_mixed}+\" { POP_STATE; rost_unescape_string(yytext + 1, yyleng - 2, tmp_0); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return ESCAPED_TEXT; } <bytes>[A-Za-z_][A-Za-z0-9_]* { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return NAME; } <bytes>"((" { return MOD_GROUP_O; } <bytes>"))" { return MOD_GROUP_C; } <bytes>"(" { return PAREN_O; } <bytes>")" { return PAREN_C; } <bytes>"," { return COMMA; } <bytes>\"{str_not_escaped}+\" { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } %{ /* Définition de motif en hexadécimal */ %} <bytes_value>"{" { POP_STATE; PUSH_STATE(bytes_hex); } <bytes_hex>"}" { POP_STATE; } <bytes_hex>"[" { PUSH_STATE(bytes_hex_range); return HOOK_O; } <bytes_hex_range>"-" { return MINUS; } <bytes_hex_range>"]" { POP_STATE; return HOOK_C; } <bytes_hex>"(" { return PAREN_O; } <bytes_hex>")" { return PAREN_C; } <bytes_hex>"|" { return PIPE; } <bytes_hex>"~" { return TILDE; } <bytes_hex>{hbyte}([ ]*{hbyte})*[ ]* { bool even; size_t i; bin_t byte; bin_t value; tmp_0->len = 0; even = true; for (i = 0; i < yyleng; i++) { byte = yytext[i]; switch (byte) { case ' ': continue; break; case '0' ... '9': value = (byte - '0'); break; case 'A' ... 'F': value = 0xa + (byte - 'A'); break; case 'a' ... 'f': value = 0xa + (byte - 'a'); break; } if (even) tmp_0->data[tmp_0->len] = (value << 4); else tmp_0->data[tmp_0->len++] |= value; even = !even; } assert(even); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return HEX_BYTES; } <bytes_hex>[\?]{2}([ ]*[\?]{2})*[ ]* { unsigned long long counter; size_t i; counter = 0; for (i = 0; i < yyleng; i++) if (yytext[i] == '?') counter++; assert(counter % 2 == 0); yylval->unsigned_integer = counter / 2; return FULL_MASK; } <bytes_hex>{mbyte}([ ]*{mbyte})*[ ]* { bool even; size_t i; bin_t byte; bin_t value; tmp_0->len = 0; tmp_1->len = 0; even = true; for (i = 0; i < yyleng; i++) { byte = yytext[i]; switch (byte) { case ' ': continue; break; case '?': even = !even; continue; break; case '0' ... '9': value = (byte - '0'); break; case 'A' ... 'F': value = 0xa + (byte - 'A'); break; case 'a' ... 'f': value = 0xa + (byte - 'a'); break; } if (even) { tmp_0->data[tmp_0->len++] = (value << 4); tmp_1->data[tmp_1->len++] = 0xf0; } else { tmp_0->data[tmp_0->len++] = value; tmp_1->data[tmp_1->len++] = 0x0f; } even = !even; } #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; tmp_1->data[tmp_1->len] = '\0'; #endif yylval->masked.tmp_values = tmp_0; yylval->masked.tmp_masks = tmp_1; return SEMI_MASK; } %{ /* Définition d'expressions régulières */ %} <bytes_value>"/" { POP_STATE; printf(" -- regex\n"); PUSH_STATE(bytes_regex); } <bytes_regex>"/" { printf("exit regex\n"); POP_STATE; } <bytes_regex>"." { return DOT; } <bytes_regex>({regular_chars})+ { rost_unescape_regex(yytext, yyleng, tmp_0); printf(" regular: '%s'\n", yytext); #ifndef NDEBUG /* Pour rendre plus lisibles les impressions de débogage */ tmp_0->data[tmp_0->len] = '\0'; #endif yylval->tmp_cstring = tmp_0; return REGEX_BYTES; } <bytes_regex>({reg_classes})+ { return REGEX_CLASSES; } %{ /* <bytes_regex>\[({regular_chars}|({regular_chars})-z|{reg_classes})+\] { */ %} <bytes_regex>"[" { PUSH_STATE(bytes_regex_range); printf(" !! entering range\n"); return HOOK_O; } <bytes_regex_range>"]" { POP_STATE; printf(" !! exiting range\n"); return HOOK_C; } <bytes_regex_range>({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+ { printf("range: '%s'\n", yytext); return REGEX_RANGE; } <bytes_regex>"(" { return PAREN_O; } <bytes_regex>")" { return PAREN_C; } <bytes_regex>"|" { return PIPE; } <bytes_regex>"*" { return MUL; } <bytes_regex>"+" { return PLUS; } <bytes_regex>"?" { return QUESTION; } <bytes_regex>"{" { PUSH_STATE(bytes_regex_quantifier); return BRACE_IN; } <bytes_regex_quantifier>"," { return COMMA; } <bytes_regex_quantifier>"}" { POP_STATE; return BRACE_OUT; } %{ /* Condition de correspondance */ %} <condition>"and" { return AND; } <condition>"or" { return OR; } <condition>"not" { return NOT; } <condition>"<" { return LT; } <condition>"<=" { return LE; } <condition>"==" { return EQ; } <condition>"!=" { return NE; } <condition>">" { return GT; } <condition>">=" { return GE; } <condition>"contains" { return CONTAINS; } <condition>"startswith" { return STARTSWITH; } <condition>"endswith" { return ENDSWITH; } <condition>"matches" { return MATCHES; } <condition>"icontains" { return ICONTAINS; } <condition>"istartswith" { return ISTARTSWITH; } <condition>"iendswith" { return IENDSWITH; } <condition>"iequals" { return IEQUALS; } <condition>"+" { return PLUS; } <condition>"-" { return MINUS; } <condition>"*" { return MUL; } <condition>"/" { return DIV; } <condition>"%" { return MOD; } <condition>"(" { return PAREN_O; } <condition>")" { return PAREN_C; } <condition>"," { return COMMA; } <condition>"[" { return HOOK_O; } <condition>"]" { return HOOK_C; } <condition>"." { return DOT; } <bytes>"|" { return PIPE; } <condition>"none" { return NONE; } <condition>"any" { return ANY; } <condition>"all" { return ALL; } <condition>"of" { return OF; } <condition>"them" { return THEM; } <condition>"in" { return IN; } <bytes,condition>${bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID; } <condition>${bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID; } <condition>#{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_COUNTER; } <condition>#{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_COUNTER; } <condition>@{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_START; } <condition>@{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_START; } <condition>!{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_LENGTH; } <condition>!{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_LENGTH; } <condition>~{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_END; } <condition>~{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_END; } <condition>[A-Za-z_][A-Za-z0-9_]* { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return NAME; } %{ /* Commentaires */ %} <*>"/*" { PUSH_STATE(comment); } <comment>"*/" { POP_STATE; } <comment>(.|\n) { } <*>"//"[^\n]* { } %{ /* Suppression du besoin de sauvegardes pour retours en arrière */ %} "i" { HANDLE_UNCOMPLETED_TOKEN; } "in" { HANDLE_UNCOMPLETED_TOKEN; } "inc" { HANDLE_UNCOMPLETED_TOKEN; } "incl" { HANDLE_UNCOMPLETED_TOKEN; } "inclu" { HANDLE_UNCOMPLETED_TOKEN; } "includ" { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\" { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"{str_not_escaped}+ { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"\\ { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"\\x { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } <inc_path>\"{str_mixed}+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } "g" { HANDLE_UNCOMPLETED_TOKEN; } "gl" { HANDLE_UNCOMPLETED_TOKEN; } "glo" { HANDLE_UNCOMPLETED_TOKEN; } "glob" { HANDLE_UNCOMPLETED_TOKEN; } "globa" { HANDLE_UNCOMPLETED_TOKEN; } "p" { HANDLE_UNCOMPLETED_TOKEN; } "pr" { HANDLE_UNCOMPLETED_TOKEN; } "pri" { HANDLE_UNCOMPLETED_TOKEN; } "priv" { HANDLE_UNCOMPLETED_TOKEN; } "priva" { HANDLE_UNCOMPLETED_TOKEN; } "privat" { HANDLE_UNCOMPLETED_TOKEN; } "r" { HANDLE_UNCOMPLETED_TOKEN; } "ru" { HANDLE_UNCOMPLETED_TOKEN; } "rul" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block>"m" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block>"me" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block>"met" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta>"b" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta>"by" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta>"byt" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta>"byte" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"c" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"co" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"con" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"cond" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"condi" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"condit" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"conditi" { HANDLE_UNCOMPLETED_TOKEN; } <raw_block,meta,bytes>"conditio" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"t" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"tr" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"tru" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"f" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"fa" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"fal" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>"fals" { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>-0x { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>0x { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>\"{str_mixed}* { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>\"{str_mixed}*\\ { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>\"{str_mixed}*\\x { HANDLE_UNCOMPLETED_TOKEN; } <meta_value>\"{str_mixed}*\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <condition>-0x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_hex_range,bytes_regex_quantifier,condition>0x { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"{str_not_escaped}* { HANDLE_UNCOMPLETED_TOKEN; } <condition>\" { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"\\ { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"\\x { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } <condition>\"{str_mixed}+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\" { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"\\ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_value>\"{str_mixed}+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes>\"{str_not_escaped}+ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_hex>{hbyte}([ ]*{hbyte})*[ ]*[0-9a-fA-F]/[^?] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_hex>[\?]{2}([ ]*[\?]{2})*[ ]*[\?]/[^0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_hex>{mbyte}([ ]*{mbyte})*[ ]*\?/[^?] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_hex>{mbyte}([ ]*{mbyte})*[ ]*[0-9a-fA-F]/[^0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>\\ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>({regular_chars})+\\ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>({regular_chars})+\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>({regular_chars})+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex>({reg_classes})+\\ <bytes_regex_range>({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\ { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex_range>({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex_range>({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex_range>\\x { HANDLE_UNCOMPLETED_TOKEN; } <bytes_regex_range>\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } %{ /* Actions par défaut */ %} <*>[ \t]+ { } <*>[\n] { static int ln = 1; if (0) printf("----------- %%< -------------- %%< ---- %d\n", ln++); } <*>. { char *msg; int ret; ret = asprintf(&msg, "Unhandled token in rule definition: '%s'", yytext); if (ret == -1) YY_FATAL_ERROR("Unhandled token in undisclosed rule definition"); else { YY_FATAL_ERROR(msg); free(msg); } } %%