re2c - regex compiler

рдкрд╛рддреНрд░реЛрдВ рдХреА рдзрд╛рд░рд╛ рд╕реЗ рдХреБрдЫ рдЯреЛрдХрди рдирд┐рдХрд╛рд▓рдиреЗ рдХрд╛ рдХрд╛рдо рдмрд╣реБрдд рдЖрдо рд╣реИред рдЕрдХреНрд╕рд░ рдЗрд╕реЗ рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдПрдирд╛рд▓рд╛рдЗрдЬрд╝рд░ рдХреА рдорджрдж рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХрдИ рдХреЛрдб рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдкрд░ рдмрдирд╛рдП рдЧрдП рд╣реИрдВ, рдЬреЛ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рддрд░реНрдХ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдпрд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреЛрдб рдореЗрдВ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рднрд╛рд╖рд╛ рдХрд╛ рд╕рдВрдХрд▓рди рд╣реИред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдлреНрд▓реЗрдХреНрд╕ рдПрдХ рдРрд╕рд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рд╣реИред рд╡рд░реНрд╖реЛрдВ рд╕реЗ рдкреБрд░рд╛рдирд╛ рд▓реЗрдХрд┐рди рд╕рд┐рджреНрдз рд╣реИред

рдореИрдВрдиреЗ рдлреНрд▓реЗрдХреНрд╕ рдХрд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛, рдЗрд╕рдореЗрдВ рдЕрдЪреНрдЫреЗ рдФрд░ рдмреБрд░реЗ рджреЛрдиреЛрдВ рдкрдХреНрд╖ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдмрдбрд╝реЗ рдФрд░ рдореБрдЭреЗ рд╢рд┐рдХрд╛рдпрдд рдХрд░рдиреЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИред

рд▓реЗрдХрд┐рди рдХрд▓ рдореИрдВ рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЖрдпрд╛ рдерд╛ - re2c ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рдЪреАрдЬ рдкрд░ рдЖрдк рдХреБрдЫ рдорд┐рдирдЯреЛрдВ рдореЗрдВ рдЕрдкрдиреЗ рдШреБрдЯрдиреЗ рдкрд░ рд▓реЗрдХреНрд╕рд┐рдХрд▓ рдПрдирд╛рд▓рд┐рд╕рд┐рд╕ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред


рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕реЗ рдХреБрдЫ рдХрдорд╛рдВрдб, рдкреВрд░реНрдгрд╛рдВрдХ рдФрд░ рднрд┐рдиреНрдирд╛рддреНрдордХ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХрд╛ рдЪрдпрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдк рдлреНрд▓реЗрдХреНрд╕ рдХреЛ рдЙрдЬрд╛рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

#include <stdio.h> #include <stdlib.h> enum { CMD, INT, FLOAT, SPACE, END }; int scan(char** p, char** lex) { char* marker; if (lex) *lex = *p; /*!re2c re2c:define:YYCTYPE = "unsigned char"; re2c:define:YYCURSOR = *p; re2c:define:YYMARKER = marker; re2c:yyfill:enable = 0; re2c:yych:conversion = 1; re2c:indent:top = 1; "GET"|"PUT"|"EXIT" { return CMD; } [0-9]+ { return INT; } [0-9]+ '.' [0-9]* { return FLOAT; } [ \t]+ { return SPACE; } [^] { return END; } */ } int main(int argc, char* argv[]) { char *p, *last; int token; if (argc < 2) return 1; p = argv[1]; while ((token = scan(&p, &last)) != END) { int sz = p - last; switch (token) { case CMD: printf("Command: '%.*s'\n", sz, last); break; case INT: printf("Number: '%.*s'\n", sz, last); break; case FLOAT: printf("Float: '%.*s'\n", sz, last); break; } } return 0; } 

рдФрд░ рд╡рд╣ рд╕рдм рд╣реИ!

рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рд╕рднреА рдЬрд╛рджреВ "рд╕реНрдХреИрди * (") рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ "/ *! Re2c" рдФрд░ "* /" рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдмреАрдЪ рд╣реЛрддрд╛ рд╣реИред

рддреЛ, re2c рдПрдХ рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд╕рдВрдХрд▓рдХ рд╣реИ рдЬреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЯреЗрдХреНрд╕реНрдЯ рдореЗрдВ рд╕реАрдзреЗ рдХреЛрдб рдПрдореНрдмреЗрдб рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ рд╣рдо re2c рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдкрдирд╛ рд╕реНрд░реЛрдд рдЪрд▓рд╛рддреЗ рд╣реИрдВ:

  re2c.exe -is test.re2c >test.c 

рддрдм рд╣рдореЗрдВ рдпрд╣ рдорд┐рд▓рддрд╛ рд╣реИ:

 /* Generated by re2c 0.13.5 on Tue Apr 19 21:08:57 2011 */ #include <stdio.h> #include <stdlib.h> enum { CMD, INT, FLOAT, SPACE, END }; int scan(char** p, char** lex) { char* marker; if (lex) *lex = *p; { unsigned char yych; yych = (unsigned char)**p; if (yych <= '9') { if (yych <= 0x1F) { if (yych == '\t') goto yy8; goto yy10; } else { if (yych <= ' ') goto yy8; if (yych <= '/') goto yy10; goto yy6; } } else { if (yych <= 'F') { if (yych == 'E') goto yy5; goto yy10; } else { if (yych <= 'G') goto yy2; if (yych == 'P') goto yy4; goto yy10; } } yy2: yych = (unsigned char)*(marker = ++*p); if (yych == 'E') goto yy24; yy3: { return END; } yy4: yych = (unsigned char)*(marker = ++*p); if (yych == 'U') goto yy23; goto yy3; yy5: yych = (unsigned char)*(marker = ++*p); if (yych == 'X') goto yy18; goto yy3; yy6: ++*p; if ((yych = (unsigned char)**p) == '.') goto yy13; if (yych <= '/') goto yy7; if (yych <= '9') goto yy16; yy7: { return INT; } yy8: ++*p; yych = (unsigned char)**p; goto yy12; yy9: { return SPACE; } yy10: yych = (unsigned char)*++*p; goto yy3; yy11: ++*p; yych = (unsigned char)**p; yy12: if (yych == '\t') goto yy11; if (yych == ' ') goto yy11; goto yy9; yy13: ++*p; yych = (unsigned char)**p; if (yych <= '/') goto yy15; if (yych <= '9') goto yy13; yy15: { return FLOAT; } yy16: ++*p; yych = (unsigned char)**p; if (yych == '.') goto yy13; if (yych <= '/') goto yy7; if (yych <= '9') goto yy16; goto yy7; yy18: yych = (unsigned char)*++*p; if (yych == 'I') goto yy20; yy19: *p = marker; goto yy3; yy20: yych = (unsigned char)*++*p; if (yych != 'T') goto yy19; yy21: ++*p; { return CMD; } yy23: yych = (unsigned char)*++*p; if (yych == 'T') goto yy21; goto yy19; yy24: ++*p; if ((yych = (unsigned char)**p) == 'T') goto yy21; goto yy19; } } int main(int argc, char* argv[]) { char *p, *last; int token; if (argc < 2) return 1; p = argv[1]; while ((token = scan(&p, &last)) != END) { int sz = p - last; switch (token) { case CMD: printf("Command: '%.*s'\n", sz, last); break; case INT: printf("Number: '%.*s'\n", sz, last); break; case FLOAT: printf("Float: '%.*s'\n", sz, last); break; } } return 0; } 

рдбрд░рд╛рд╡рдирд╛? рд╣рд╛рдВ, рдХреЛрдб рдореИрдиреНрдпреБрдЕрд▓ рд╕рдВрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рд╣рдо рд╕рдВрдХрд▓рди рдХрд░рддреЗ рд╣реИрдВ:

  re2c.exe -is test.re2c >test.c && cl test.c 

рд╣рдо рд▓реЙрдиреНрдЪ рдХрд░рддреЗ рд╣реИрдВ:

  test "GET 123.0 12344 PUT 10." 

рдкрд░рд┐рдгрд╛рдо:

  Command: 'GET' Float: '123.0' Number: '12344' Command: 'PUT' Float: '10.' 

рдЬреИрд╕рд╛ рдХрд┐ рд╡реЗ рдХрд╣рддреЗ рд╣реИрдВ, рддреЗрдЬ, рд╕рд╕реНрддрд╛ рдФрд░ рд╣рдВрд╕рдореБрдЦред рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдорд╛рд╕реНрдЯрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП re2c рдЖрдкрдХреЛ рдкреНрд░рд▓реЗрдЦрди рдХреЗ рдПрдХ рдФрд░ рдХреЗрд╡рд▓ рдкреГрд╖реНрда рдХреЛ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рд╡реИрд╕реЗ, re2c рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рд░рд▓рддрд╛ рдХрд╛ рдорддрд▓рдм рдпрд╣ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЖрдк рдЗрд╕ рдкрд░ рдЬрдЯрд┐рд▓ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡рд┐рддрд░рдг рдореЗрдВ C рдФрд░ Rexx рдЯреЛрдХрди рдХреЗ рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВред

рдпрджрд┐ рдЖрдк re2c рдЭрдВрдбреЗ рдХреЗ рд╕рд╛рде рдЦреЗрд▓рддреЗ рд╣реИрдВ , рддреЛ рдЖрдк "if / else" рдХреЗ рдмрдЬрд╛рдп "рд╕реНрд╡рд┐рдЪ / рдХреЗрд╕" рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЪреБрдирд╛рд╡ рдХреЛ рд╕рдордЭрдиреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдЖрдкрдХрд╛ рдХрдВрдкрд╛рдЗрд▓рд░ рдХрд┐рд╕ рдХреЛрдб рдХреЛ рдмреЗрд╣рддрд░ рдмрдирд╛рддрд╛ рд╣реИред

рдЬреИрд╕рд╛ рдХрд┐ рдореИрдВ рдЗрд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, re2c рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд╡рд┐рд╢реНрд▓реЗрд╖рдХ рдмрд╣реБрдд рддреЗрдЬ, рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдмрд╣реБрдд рддреЗрдЬ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕реЗ рдЙрд╕реА flex'a, ANTLR'a рдпрд╛ Spirit'a рдХреЗ рдЦрд┐рд▓рд╛рдл рдорд╛рдкрдирд╛ рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧрд╛ред

рд╡рд┐рд╖рдп рдкрд░ рд▓рдЧрднрдЧ рдкреЛрд╕реНрдЯ:

Source: https://habr.com/ru/post/In117843/


All Articles