测试flex中的当前启动状态

时间:2014-03-31 17:24:41

标签: parsing lex flex-lexer lexical-analysis

我有一个包含两个规则的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();
    }
}

2 个答案:

答案 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);
}