在flex状态之间传递匹配

时间:2013-04-29 18:34:36

标签: c lex flex-lexer

我正在为正式方法和模型中的一个类开发一个项目,我遇到了一些flex / lex的问题。

我们使用flex和C编写一个简单的解析器来检查控制台输入的用户名和密码。我已经得到了各种各样的状态并进行了检查,所以它基本完成了。我只是想让它更好地工作。

我有五种状态:检查用户名的初始状态,并说明检查密码要求(长度,特殊字符,大写字母,数字)。最初,用户输入用户名进行检查。成功时,会要求他们输入密码,并检查上述要求。问题是用户需要在每个州重新键入密码。

我很想知道是否有办法让flex接受适当长度的密码,然后将每个后续状态传递给下一个,这样用户只需输入一次。类似的问题让我this result包括谈论flex的YY_BUFFERS,但是我不确定它是否在类似的方向。

代码如下:

%s  PW_START
%s  PW_SPECIAL
%s  PW_CAPS
%s  PW_INT
%s  PW_PRINT


%%
<INITIAL>^[a-z]{1}[A-Z]{1}[a-z]{1,6}    {

    printf("Accepted username: %s\n", yytext);
    printf("Namelength: %d\n", yyleng);
    printf("Enter a password: ");
    BEGIN PW_START;}

<PW_START>^[a-z]{1}([a-zA-Z0-9\[^#@]){5,9}  {

    printf("Password is proper length: %s\n", yytext);
    BEGIN PW_SPECIAL;}

<PW_SPECIAL>^[a-z]{1}[a-zA-Z0-9]{0,8}[\[^#@][a-zA-Z0-9\[^#@]{0,8}   {

    printf("Password contains >= 1 special character.\n");
    printf("Accepted password: %s\n", yytext);
    BEGIN PW_CAPS;}

<PW_CAPS>^[a-z]{1}[a-z\[^#@0-9]{0,8}[A-Z][a-zA-Z0-9\[^#@]{0,8}  {

    printf("Password contains >= 1 capital letter.\n");
    BEGIN PW_INT;}

<PW_INT>^[a-z]{1}[a-zA-Z\[^#@]{0,8}[0-9][a-zA-Z0-9\[^#@]{0,8}   {

    printf("Password contains >= 1 integer.\n");
    BEGIN PW_PRINT;}

<PW_PRINT>.*    {

    printf("Accepted password: %s\n", yytext);}

%%

int main(int argc, char* argv[]){
    printf("Enter a username: ");
    yylex();

}

1 个答案:

答案 0 :(得分:1)

您可以使用yyless(0)使flex重新扫描令牌。有关详细信息,请参阅Flex manual

一个例子是

<PW_START>^[a-z]{1}([a-zA-Z0-9\[^#@]){5,9}  {
      printf("Password is proper length: %s\n", yytext);
      BEGIN(PW_SPECIAL);
      yyless(0);
    }

虽然我认为打印密码真的很粗鲁。如果有人正在看着用户的肩膀怎么办?