测试 Flex 中的当前启动状态

问题描述 投票:0回答:3

我有一个 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();
    }
}
parsing lex flex-lexer lexical-analysis
3个回答
2
投票

我认为接受的答案不正确。

当您调用 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);
}

1
投票

你很接近了。 列出

< >
之间的几个开始状态是有效的。 要获取当前状态,您可以调用
yy_top_state()

<STATE1,STATE2>{SAME_REGEX} {
    same_code();
    if(yy_top_state() == STATE2){
        one_extra_line();
    }
}

0
投票

您想要的符号是

yystart

通过

BEGIN
,您只需修改它,请参见下文:

#define BEGIN (yy_start) = 1 + 2 *

通过

yy_push_state(int new_state)
,您可以有效地
BEGIN(new_state)
,同时将当前的
yystart
保存到堆栈中。另一方面,
yy_push_state()
弹出堆栈顶部的状态并开始它。

© www.soinside.com 2019 - 2024. All rights reserved.