lex模式匹配ipv4点分十进制表示法

时间:2012-12-05 21:08:56

标签: c++ c token lex flex-lexer

我在下面给出了一个模式,用于匹配点分十进制表示法中的ipv4地址。

IPV4ADDRESS (([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))

我用

%x S_rule S_dst_ip

<S_rule>(dst-ip){SPACE}   {

           BEGIN(S_dst_ip);

        }


<S_dst_ip>\{{IPV4ADDRESS}\}  {

       /*code to process the sring here.*/
     }

匹配表单

的输入
dst-ip {10.13.12.138}

现在我要匹配

dst-ip { 10.13.12.138 } in addition to dst-ip {10.13.12.138}

我修改上面定义的IPV4ADDRESS如下

IPV4ADDRESS [ \t]*(([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))[ \t]*

然而,此修改似乎与

不匹配
  dst-ip { 10.13.12.138 } OR dst-ip {10.13.12.138}

有人可以在我的代码中指出错误吗?

1 个答案:

答案 0 :(得分:1)

因为它“适合我”,所以我不能告诉你代码有什么问题,因为你没有显示SSCCE(Short, Self-Contained, Correct Example)。这是一个:

/*IPV4ADDRESS     (([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))*/
IPV4ADDRESS [ \t]*(([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))[ \t]*
SPACE [ \t]

%x S_rule S_dst_ip

%%

%{
    BEGIN S_rule;
%}

<S_rule>(dst-ip){SPACE}   {
           BEGIN(S_dst_ip);
        }

<S_dst_ip>\{{IPV4ADDRESS}\}  {
       printf("\n\nMATCH [%s]\n\n", yytext);
       BEGIN S_rule;
     }

. { ECHO; }

%%

int main(void)
{
    while (yylex() != 0)
        ;
    return(0);
}

int yywrap(void)
{
    return 1;
}

根据您问题中的文字使用测试数据文件:

dst-ip {10.13.12.138}
dst-ip { 10.13.12.138 } 
dst-ip {10.13.12.138}
dst-ip { 10.13.12.138 } OR dst-ip {10.13.12.138}

上面的程序产生(一些空行被省略):

MATCH [{10.13.12.138}]

MATCH [{ 10.13.12.138 }]

MATCH [{10.13.12.138}]

MATCH [{ 10.13.12.138 }]

 OR 

MATCH [{10.13.12.138}]

如果我不得不猜测出现了什么问题,我会怀疑你在识别S_rule之后错过了切换回状态S_dst_ip(可能还有开头的%{ BEGIN S_rule; %}短语)。

我顺便提一下,这将接受{999.999.999.999}作为IPv4地址。但是,通过更严格控制的表达来修复它是可行的,并且与您的主要问题没有密切关系。