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();
}
}
Pregunta
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();
}
}
Solución
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();
}
}
Otros consejos
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);
}