0

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

我们正在使用 flex 和 C 编写一个简单的解析器来检查来自控制台输入的用户名和密码。我已经把各种状态都搞定了,检查好了,基本就搞定了。我只是想让它更好地工作。

我有五个状态:检查用户名的初始状态和检查密码要求的状态(长度、特殊字符、大写字母、数字)。最初,用户输入用户名进行检查。成功后,系统会要求他们输入密码,并根据上述要求进行检查。问题是用户需要在每个状态下重新输入密码。

我很想知道是否有办法让 flex 接受适当长度的密码,然后让每个后续状态将其传递给下一个状态,这样用户只需输入一次。类似的问题给了我这个结果,包括谈论 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();

}
4

1 回答 1

1

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

一个例子是

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

虽然我认为打印密码实际上很粗鲁。如果有人从用户的肩膀上看怎么办?

于 2013-05-02T05:43:11.173 回答