%top { #include "grammar.h" } %{ #include #include #include /* 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; } \"{str_not_escaped}+\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } \"{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; } {bytes_id} { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return RULE_IDENTIFIER; } ":" { return COLON; } [ \t]* { } "{" { POP_STATE; PUSH_STATE(raw_block); return BRACE_IN; } "meta" { POP_STATE; PUSH_STATE(meta); PUSH_STATE(wait_for_colon); return META; } "bytes" { POP_STATE; PUSH_STATE(bytes); PUSH_STATE(wait_for_colon); return BYTES; } "condition" { POP_STATE; PUSH_STATE(condition); PUSH_STATE(wait_for_colon); return CONDITION; } ":" { POP_STATE; return COLON; } "}" { POP_STATE; return BRACE_OUT; } %{ /* Définitions communes pour la section "meta:" */ %} {bytes_id} { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return INFO_KEY; } "=" { PUSH_STATE(meta_value); return ASSIGN; } "true" { POP_STATE; return TRUE_; } "false" { POP_STATE; return FALSE_; } -(0|[1-9][0-9]*) { POP_STATE; yylval->signed_integer = strtoll(yytext, NULL, 10); return SIGNED_INTEGER; } -0x[0-9a-f]+ { POP_STATE; yylval->signed_integer = strtoll(yytext, NULL, 16); return SIGNED_INTEGER; } (0|[1-9][0-9]*) { POP_STATE; yylval->unsigned_integer = strtoull(yytext, NULL, 10); return UNSIGNED_INTEGER; } 0x[0-9a-f]+ { POP_STATE; yylval->unsigned_integer = strtoull(yytext, NULL, 16); return UNSIGNED_INTEGER; } \"{str_not_escaped}*\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } \"{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... */ %} "true" { return TRUE_; } "false" { return FALSE_; } -(0|[1-9][0-9]*) { yylval->signed_integer = strtoll(yytext, NULL, 10); return SIGNED_INTEGER; } -0x[0-9a-f]+ { yylval->signed_integer = strtoll(yytext, NULL, 16); return SIGNED_INTEGER; } (0|[1-9][0-9]*) { yylval->unsigned_integer = strtoull(yytext, NULL, 10); return UNSIGNED_INTEGER; } 0x[0-9a-f]+ { yylval->unsigned_integer = strtoull(yytext, NULL, 16); return UNSIGNED_INTEGER; } [kK][bB] { return KB; } [mM][bB] { return MB; } [gG][bB] { return GB; } \"{str_not_escaped}*\" { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } \"{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:" */ %} "fullword" { return FULLWORD; } "nocase" { return NOCASE; } "private" { return PRIVATE; } "=" { PUSH_STATE(bytes_value); return ASSIGN; } %{ /* Définition de motif en texte brut */ %} \"{str_not_escaped}+\" { POP_STATE; yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 2; return PLAIN_TEXT; } \"{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-Za-z_][A-Za-z0-9_]* { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return NAME; } "((" { return MOD_GROUP_O; } "))" { return MOD_GROUP_C; } "(" { return PAREN_O; } ")" { return PAREN_C; } "," { return COMMA; } \"{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 */ %} "{" { POP_STATE; PUSH_STATE(bytes_hex); } "}" { POP_STATE; } "[" { PUSH_STATE(bytes_hex_range); return HOOK_O; } "-" { return MINUS; } "]" { POP_STATE; return HOOK_C; } "(" { return PAREN_O; } ")" { return PAREN_C; } "|" { return PIPE; } "~" { return TILDE; } {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; } [\?]{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; } {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 */ %} "/" { POP_STATE; printf(" -- regex\n"); PUSH_STATE(bytes_regex); } "/" { printf("exit regex\n"); POP_STATE; } "." { return DOT; } ({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; } ({reg_classes})+ { return REGEX_CLASSES; } %{ /* \[({regular_chars}|({regular_chars})-z|{reg_classes})+\] { */ %} "[" { PUSH_STATE(bytes_regex_range); printf(" !! entering range\n"); return HOOK_O; } "]" { POP_STATE; printf(" !! exiting range\n"); return HOOK_C; } ({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+ { printf("range: '%s'\n", yytext); return REGEX_RANGE; } "(" { return PAREN_O; } ")" { return PAREN_C; } "|" { return PIPE; } "*" { return MUL; } "+" { return PLUS; } "?" { return QUESTION; } "{" { PUSH_STATE(bytes_regex_quantifier); return BRACE_IN; } "," { return COMMA; } "}" { POP_STATE; return BRACE_OUT; } %{ /* Condition de correspondance */ %} "and" { return AND; } "or" { return OR; } "not" { return NOT; } "<" { return LT; } "<=" { return LE; } "==" { return EQ; } "!=" { return NE; } ">" { return GT; } ">=" { return GE; } "contains" { return CONTAINS; } "startswith" { return STARTSWITH; } "endswith" { return ENDSWITH; } "matches" { return MATCHES; } "icontains" { return ICONTAINS; } "istartswith" { return ISTARTSWITH; } "iendswith" { return IENDSWITH; } "iequals" { return IEQUALS; } "+" { return PLUS; } "-" { return MINUS; } "*" { return MUL; } "/" { return DIV; } "%" { return MOD; } "(" { return PAREN_O; } ")" { return PAREN_C; } "," { return COMMA; } "[" { return HOOK_O; } "]" { return HOOK_C; } "." { return DOT; } "|" { return PIPE; } "none" { return NONE; } "any" { return ANY; } "all" { return ALL; } "of" { return OF; } "them" { return THEM; } "in" { return IN; } ${bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID; } ${bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID; } #{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_COUNTER; } #{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_COUNTER; } @{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_START; } @{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_START; } !{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_LENGTH; } !{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_LENGTH; } ~{bytes_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_ID_END; } ~{bytes_fuzzy_id} { yylval->sized_cstring.data = yytext + 1; yylval->sized_cstring.len = yyleng - 1; return BYTES_FUZZY_ID_END; } [A-Za-z_][A-Za-z0-9_]* { yylval->sized_cstring.data = yytext; yylval->sized_cstring.len = yyleng; return NAME; } %{ /* Commentaires */ %} <*>"/*" { PUSH_STATE(comment); } "*/" { POP_STATE; } (.|\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; } \" { HANDLE_UNCOMPLETED_TOKEN; } \"{str_not_escaped}+ { HANDLE_UNCOMPLETED_TOKEN; } \"\\ { HANDLE_UNCOMPLETED_TOKEN; } \"\\x { HANDLE_UNCOMPLETED_TOKEN; } \"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } \"{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; } "m" { HANDLE_UNCOMPLETED_TOKEN; } "me" { HANDLE_UNCOMPLETED_TOKEN; } "met" { HANDLE_UNCOMPLETED_TOKEN; } "b" { HANDLE_UNCOMPLETED_TOKEN; } "by" { HANDLE_UNCOMPLETED_TOKEN; } "byt" { HANDLE_UNCOMPLETED_TOKEN; } "byte" { HANDLE_UNCOMPLETED_TOKEN; } "c" { HANDLE_UNCOMPLETED_TOKEN; } "co" { HANDLE_UNCOMPLETED_TOKEN; } "con" { HANDLE_UNCOMPLETED_TOKEN; } "cond" { HANDLE_UNCOMPLETED_TOKEN; } "condi" { HANDLE_UNCOMPLETED_TOKEN; } "condit" { HANDLE_UNCOMPLETED_TOKEN; } "conditi" { HANDLE_UNCOMPLETED_TOKEN; } "conditio" { HANDLE_UNCOMPLETED_TOKEN; } "t" { HANDLE_UNCOMPLETED_TOKEN; } "tr" { HANDLE_UNCOMPLETED_TOKEN; } "tru" { HANDLE_UNCOMPLETED_TOKEN; } "f" { HANDLE_UNCOMPLETED_TOKEN; } "fa" { HANDLE_UNCOMPLETED_TOKEN; } "fal" { HANDLE_UNCOMPLETED_TOKEN; } "fals" { HANDLE_UNCOMPLETED_TOKEN; } -0x { HANDLE_UNCOMPLETED_TOKEN; } 0x { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}* { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}*\\ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}*\\x { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}*\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } -0x { HANDLE_UNCOMPLETED_TOKEN; } 0x { HANDLE_UNCOMPLETED_TOKEN; } \"{str_not_escaped}* { HANDLE_UNCOMPLETED_TOKEN; } \" { HANDLE_UNCOMPLETED_TOKEN; } \"\\ { HANDLE_UNCOMPLETED_TOKEN; } \"\\x { HANDLE_UNCOMPLETED_TOKEN; } \"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \" { HANDLE_UNCOMPLETED_TOKEN; } \"\\ { HANDLE_UNCOMPLETED_TOKEN; } \"\\x { HANDLE_UNCOMPLETED_TOKEN; } \"\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\ { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\x { HANDLE_UNCOMPLETED_TOKEN; } \"{str_mixed}+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \"{str_not_escaped}+ { HANDLE_UNCOMPLETED_TOKEN; } {hbyte}([ ]*{hbyte})*[ ]*[0-9a-fA-F]/[^?] { HANDLE_UNCOMPLETED_TOKEN; } [\?]{2}([ ]*[\?]{2})*[ ]*[\?]/[^0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } {mbyte}([ ]*{mbyte})*[ ]*\?/[^?] { HANDLE_UNCOMPLETED_TOKEN; } {mbyte}([ ]*{mbyte})*[ ]*[0-9a-fA-F]/[^0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \\ { HANDLE_UNCOMPLETED_TOKEN; } \\x { HANDLE_UNCOMPLETED_TOKEN; } \\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } ({regular_chars})+\\ { HANDLE_UNCOMPLETED_TOKEN; } ({regular_chars})+\\x { HANDLE_UNCOMPLETED_TOKEN; } ({regular_chars})+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } ({reg_classes})+\\ ({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\ { HANDLE_UNCOMPLETED_TOKEN; } ({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\x { HANDLE_UNCOMPLETED_TOKEN; } ({regular_chars}|({regular_chars}-{regular_chars})|{reg_classes})+\\x[0-9a-fA-F] { HANDLE_UNCOMPLETED_TOKEN; } \\x { HANDLE_UNCOMPLETED_TOKEN; } \\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); } } %%