Parsing 在flex中测试当前启动状态

Parsing 在flex中测试当前启动状态,parsing,lex,flex-lexer,lexical-analysis,Parsing,Lex,Flex Lexer,Lexical Analysis,我有一个flex文件,其中有两条规则,它们只在一行代码中有所不同: <STATE1>{SAME_REGEX} { same_code(); } <STATE2>{SAME_REGEX} { same_code(); one_extra_line(); } {SAME_REGEX}{ 相同的_代码(); } {SAME_REGEX}{ 相同的_代码(); 一条额外的线(); } 为了简洁和易于维护(即使相同的_code()部分发生了更改,它们也

我有一个flex文件,其中有两条规则,它们只在一行代码中有所不同:

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

<STATE2>{SAME_REGEX} {
    same_code();
    one_extra_line();
}
{SAME_REGEX}{
相同的_代码();
}
{SAME_REGEX}{
相同的_代码();
一条额外的线();
}
为了简洁和易于维护(即使相同的_code()部分发生了更改,它们也会始终保持相同的部分),有没有办法通过使用if语句测试当前状态来将这两者结合起来?例如:

<STATE1,STATE2>{SAME_REGEX} {
    same_code();
    if(STATE2){
        one_extra_line();
    }
}
{SAME_REGEX}{
相同的_代码();
如果(状态2){
一条额外的线();
}
}

你很接近了。列出
之间的几个启动状态是有效的。要获取当前状态,可以调用
yy\u top\u state()

{SAME_REGEX}{
相同的_代码();
if(yy_top_state()==STATE2){
一条额外的线();
}
}

我认为公认的答案不正确

当您调用yy_push_state(新_状态)时,您将当前活动状态推送到堆栈上,并使“新_状态”成为当前活动状态。类似地,调用yy_pop_state()将删除当前位于状态堆栈顶部的状态,并使其成为活动状态。yy_top_state将返回先前保存到堆栈上的值,而不是当前活动状态,我相信这是OP所寻找的

请参阅flex信息页面的“第10节启动条件”

这里有一个小的交互式flex程序来说明这个问题

注意:以下输入通过所有三种状态0、1、2进行切换:

举例说明灵活状态#

%选项堆栈
%{
#包括
#定义TOP_STATE yy_TOP_STATE()
无效pop_状态(常量字符*);
无效推送状态(常量字符*,int);
%}
%x州1
%x州2
%%
{
#[^#\n]+{if(YY#u START==STATE1)
推送状态(yytext,状态2);
其他的
流行状态(yytext);
}
.{pop_state(yytext);}
\n{pop_state(“NEWLINE”);}
}
#{push_state(“#”,STATE1)}
.
%%
int
主(内部argv,字符**argc)
{ 
yylex();
返回0;
}
无效的
pop_状态(常量字符*txt)
{ 
printf(“活动状态:%d\n”,YY_开始);
printf(“\t匹配:%s\n”,txt);
printf(“\t顶置状态(堆栈顶部):%d…”,yy_顶置状态());
yy_pop_state();
printf(“活动状态:%d\n”,YY_开始);
}
无效的
推送状态(const char*txt,int new_state)
{
printf(“活动状态:%d\n”,YY_开始);
printf(“\t匹配:'%s'\n',txt);
printf(“\t推送状态:%d,切换到状态%d…”,YY_开始,新_状态);
yy_推_状态(新_状态);
printf(“堆栈顶部:%d,活动状态:%d\n”,yy_顶部_状态(),yy_开始);
}
<STATE1,STATE2>{SAME_REGEX} {
    same_code();
    if(yy_top_state() == STATE2){
        one_extra_line();
    }
}
%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);
}