我有一个包含两个规则的flex文件,这些规则只在一行代码中有所不同:
<STATE1>{SAME_REGEX} {
same_code();
}
<STATE2>{SAME_REGEX} {
same_code();
one_extra_line();
}
有没有办法,为了简洁和易于维护(即使same_code()部分发生变化,它们将始终具有相同的部分),通过使用if语句测试当前状态来组合这两个部分?例如:
<STATE1,STATE2>{SAME_REGEX} {
same_code();
if(STATE2){
one_extra_line();
}
}
答案 0 :(得分:1)
你很亲密。在< >
之间列出几个开始状态是有效的。要获取当前状态,您可以致电yy_top_state()
<STATE1,STATE2>{SAME_REGEX} {
same_code();
if(yy_top_state() == STATE2){
one_extra_line();
}
}
答案 1 :(得分:1)
我不认为接受的答案是正确的。
当你调用yy_push_state(new_state)时,你将当前活动状态推入堆栈并使'new_state'成为当前活动状态。类似地,调用yy_pop_state()将删除当前位于状态堆栈顶部的状态并使其成为活动状态。 yy_top_state将返回先前保存到堆栈中的值,而不是当前活动状态,我认为这是OP正在寻找的状态。
请参阅flex信息页面的“第10节开始条件”。
这是一个用于说明问题的小型交互式flex程序
注意:以下输入切换到所有三种状态0,1,2:
Exmpale ##说明了弹性状态#
%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);
}