1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
#include "ip_parser.h"
/** Ragel machine **/
%%{
machine ip_parser;
action is_ipv4 {
ip_type = ip_type_ipv4;
}
action is_ipv6 {
ip_type = ip_type_ipv6;
}
action is_ipv6_reference {
ip_type = ip_type_ipv6_reference;
}
DIGIT = "0".."9";
HEXDIG = DIGIT | "A"i | "B"i | "C"i | "D"i | "E"i | "F"i;
dec_octet = DIGIT | ( 0x31..0x39 DIGIT ) | ( "1" DIGIT{2} ) |
( "2" 0x30..0x34 DIGIT ) | ( "25" 0x30..0x35 );
IPv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet;
h16 = HEXDIG{1,4};
ls32 = ( h16 ":" h16 ) | IPv4address;
IPv6address = ( ( h16 ":" ){6} ls32 ) |
( "::" ( h16 ":" ){5} ls32 ) |
( h16? "::" ( h16 ":" ){4} ls32 ) |
( ( ( h16 ":" )? h16 )? "::" ( h16 ":" ){3} ls32 ) |
( ( ( h16 ":" ){,2} h16 )? "::" ( h16 ":" ){2} ls32 ) |
( ( ( h16 ":" ){,3} h16 )? "::" h16 ":" ls32 ) |
( ( ( h16 ":" ){,4} h16 )? "::" ls32 ) |
( ( ( h16 ":" ){,5} h16 )? "::" h16 ) |
( ( ( h16 ":" ){,6} h16 )? "::" );
IPv6reference = "[" IPv6address "]";
main := IPv4address @is_ipv4 |
IPv6address @is_ipv6 |
IPv6reference @is_ipv6_reference;
}%%
/** Data **/
%% write data;
/** exec **/
enum enum_ip_type ip_parser_execute(const char *str, size_t len)
{
int cs = 0;
const char *p, *pe;
enum enum_ip_type ip_type = ip_type_error;
p = str;
pe = str+len;
%% write init;
%% write exec;
if(len != p-str)
return ip_type_error;
else
return ip_type;
}
|