| { | { | ||||
| regex_t reg; | regex_t reg; | ||||
| lexer_token_class tokenClass; | lexer_token_class tokenClass; | ||||
| int matched; | |||||
| regmatch_t pmatch; | |||||
| }; | }; | ||||
| static struct token_reg regex(const char* str, lexer_token_class tokenClass) | static struct token_reg regex(const char* str, lexer_token_class tokenClass) | ||||
| struct token_reg res = | struct token_reg res = | ||||
| { | { | ||||
| reg, | reg, | ||||
| tokenClass | |||||
| tokenClass, | |||||
| 0 | |||||
| }; | }; | ||||
| return res; | return res; | ||||
| regmatch_t pmatch; | regmatch_t pmatch; | ||||
| size_t offset = 0; | size_t offset = 0; | ||||
| #define APPEND(tclass) tokens_append(tokens, tclass, str + offset + pmatch.rm_so, pmatch.rm_eo - pmatch.rm_so) | |||||
| #define APPEND(treg) tokens_append( \ | |||||
| tokens, \ | |||||
| treg.tokenClass, \ | |||||
| str + offset + treg.pmatch.rm_so, \ | |||||
| treg.pmatch.rm_eo - treg.pmatch.rm_so \ | |||||
| ) | |||||
| #define LENGTH(treg) (treg.pmatch.rm_eo - treg.pmatch.rm_so) | |||||
| while (1) | while (1) | ||||
| { | { | ||||
| size_t i; | size_t i; | ||||
| //Reset .matched property for all tregs | |||||
| for (i = 0; i < LEXER_TOKEN_NONE; ++i) | |||||
| { | |||||
| tregs[i].matched = 0; | |||||
| } | |||||
| //See which tregs match | |||||
| for (i = 0; i < LEXER_TOKEN_NONE; ++i) | for (i = 0; i < LEXER_TOKEN_NONE; ++i) | ||||
| { | { | ||||
| struct token_reg treg = tregs[i]; | struct token_reg treg = tregs[i]; | ||||
| if (regmatch(treg.reg, str + offset, &pmatch)) | if (regmatch(treg.reg, str + offset, &pmatch)) | ||||
| { | { | ||||
| APPEND(treg.tokenClass); | |||||
| break; | |||||
| treg.matched = 1; | |||||
| treg.pmatch = pmatch; | |||||
| } | |||||
| } | |||||
| //Find longest match | |||||
| struct | |||||
| { | |||||
| size_t length; | |||||
| size_t index; | |||||
| } longest; | |||||
| longest.length = -1; | |||||
| longest.index = -1; | |||||
| for (i = 0; i < LEXER_TOKEN_NONE; ++i) | |||||
| { | |||||
| struct token_reg treg = tregs[i]; | |||||
| if (!treg.matched) | |||||
| continue; | |||||
| if (LENGTH(treg) >= longest.length) | |||||
| { | |||||
| longest.length = LENGTH(treg); | |||||
| longest.index = i; | |||||
| } | } | ||||
| } | } | ||||
| //Append longest match | |||||
| APPEND(tregs[longest.index]); | |||||
| offset += pmatch.rm_eo; | offset += pmatch.rm_eo; | ||||
| if (offset >= len) | if (offset >= len) | ||||
| break; | break; | ||||
| } | } | ||||
| #undef APPEND | |||||
| #undef LENGTH | |||||
| return tokens; | return tokens; | ||||
| } | } |