0

I'm working on a project for a class in Formal Methods and Models and I'm having some issues with flex/lex.

We're using flex and C to write a simple parser to check usernames and passwords from console input. I've already got the various states worked out and checked, so it's basically done. I'm just trying to make it work better.

I have five states: the initial state which checks the username, and states that check the password requirements (length, special character, capital letter, number). Initially, the user enters a username to check. On success, they are asked for a password, which is checked for the requirements above. The problem is that the user is required to retype their password at each state.

I'd love to know if there's a way to have flex accept a password of the proper length and then have each following state pass it to the next, so that the user only has to enter it once. Similar questions gives me this result that includes talking about flex's YY_BUFFERS, but I'm not sure if that's in a similar direction.

Code is below:

%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();

}
Community
  • 1
  • 1

1 Answers1

1

You can use yyless(0) to cause flex to rescan a token. See the Flex manual for details.

An example would be

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

Although I think it's actually pretty rude to print out a password. What if someone is looking over the user's shoulder?

rici
  • 234,347
  • 28
  • 237
  • 341