我有一个 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();
}
}
我认为接受的答案不正确。
当您调用 yy_push_state(new_state) 时,您将当前活动状态推入堆栈并使“new_state”成为当前活动状态。类似地,调用 yy_pop_state() 将删除当前位于状态堆栈顶部的状态并使其成为活动状态。 yy_top_state 将返回之前保存到堆栈中的值,而不是当前活动状态,我相信这正是 OP 正在寻找的状态。
请参阅 Flex 信息页面的“第 10 节启动条件”。
这是一个小型交互式弹性程序来说明这个问题
注意: 以下输入在所有三种状态 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);
}
你很接近了。 列出
< >
之间的几个开始状态是有效的。 要获取当前状态,您可以调用 yy_top_state()
<STATE1,STATE2>{SAME_REGEX} {
same_code();
if(yy_top_state() == STATE2){
one_extra_line();
}
}
您想要的符号是
yystart
。
通过
BEGIN
,您只需修改它,请参见下文:
#define BEGIN (yy_start) = 1 + 2 *
通过
yy_push_state(int new_state)
,您可以有效地BEGIN(new_state)
,同时将当前的yystart
保存到堆栈中。另一方面,yy_push_state()
弹出堆栈顶部的状态并开始它。