Question

I have a flex file with two rules that differ only in one line of code:

<STATE1>{SAME_REGEX} {
    same_code();
}

<STATE2>{SAME_REGEX} {
    same_code();
    one_extra_line();
}

Is there any way, for brevity and ease of maintenance (even if the same_code() part changes, they will always have that part the same), to combine these two, by testing current state with an if statement? for instance:

<STATE1,STATE2>{SAME_REGEX} {
    same_code();
    if(STATE2){
        one_extra_line();
    }
}
Was it helpful?

Solution

You're close. Listing several start states between < > is valid. To get the current state, you can call yy_top_state()

<STATE1,STATE2>{SAME_REGEX} {
    same_code();
    if(yy_top_state() == STATE2){
        one_extra_line();
    }
}

OTHER TIPS

I don't think the accepted answer is correct.

When you call yy_push_state(new_state) you're pushing the currently active state onto the stack and making 'new_state' the currently active state. Similarly, calling yy_pop_state() will remove the state currently at the top of the state stack and make it the active state. yy_top_state will return the value that was previously saved onto the stack not the currently active state which I believe is what the OP is looking for.

See 'Section 10 Start Conditions' of flex's info page.

Here's a small interactive flex program to illustrate the issue

Note: The following input switches through all three states 0,1,2:

Exmpale ## illustrating flex states #

%option stack

%{
#include<stdio.h>
#define TOP_STATE yy_top_state()

void pop_state(const char *);
void push_state(const char *, int);
%}


%x STATE1
%x STATE2

%%

<STATE1,STATE2>{
#[^#\n]+ { if(YY_START == STATE1)
             push_state(yytext, STATE2);
           else
             pop_state(yytext);
         }
.        { pop_state(yytext);  }
\n       { pop_state("NEWLINE"); }
}

#        { push_state("#", STATE1); }
.

%%

int
main(int argv, char ** argc)
{ 
  yylex();
  return 0;
}

void
pop_state(const char * txt)
{ 
  printf("active state: %d\n", YY_START);
  printf("\tmatched: %s\n ", txt);
  printf("\tpopping state (stack top): %d ... ", yy_top_state());
  yy_pop_state();
  printf("active state: %d\n", YY_START);
}

void
push_state(const char * txt, int new_state)
{
  printf("active state: %d\n", YY_START);
  printf("\tmatched: '%s'\n ", txt);
  printf("\tpushing state: %d, switching to state %d ... ", YY_START, new_state);
  yy_push_state(new_state);
  printf("stack top: %d, active state: %d\n", yy_top_state(), YY_START);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top