Flex-lexer:以后的规则比先前的规则具有优先权

时间:2019-02-10 09:53:24

标签: bison flex-lexer

我正在尝试从c / c ++源文件中提取信息。 我正在尝试提取宏的内容。

例如:

  • 应从MYMACRO(random content) random content中提取。
  • 应从MYMACRO (random content) random content中提取。

问题: 野牛不会将MYMACRO识别为令牌。

此代码只是第一步,仅将宏本身作为输入

Lex文件:parser.l

%{
 #include <iostream>
 #include "parser.tab.h"
 using namespace std;
 extern int yylex(); 
%}

%option noyywrap

%%

"MYMACRO" {
  return EXTRACT_CONTENT_START;
}

[(] {
  return BRACE_OPEN;
}

[)] {
  return BRACE_CLOSE; 
}

.* { 
    yylval.sval = strdup(yytext);
    return ANY_TEXT;
}


%%

野牛文件:parser.y:

%{

  #include <iostream>
  #include <string.h>
  using namespace std;

  extern int yylex();
  extern int yyparse();
  extern int yy_scan_string(char const *);

  void yyerror(const char *s);

%}

%union {
  int ival;
  char * sval;
  char cval;
}

%error-verbose


%token EXTRACT_CONTENT_START
%token <cval> BRACE_OPEN
%token <cval> BRACE_CLOSE
%token <sval> ANY_TEXT

%%

program:
    EXTRACT_CONTENT_START 
    BRACE_OPEN
    ANY_TEXT
    BRACE_CLOSE 
    ;

%%

int main(int ,char**){
  yy_scan_string("MYMACRO(random content)");
  yyparse();
}

void yyerror(const char *s) {
  cout << endl << s << endl;
  exit(-1);
}
  • 预期: random content
  • 实际: unexpected ANY_TEXT, expecting EXTRACT_CONTENT_START (因此@Flex:不是发送第一个出现的规则,而是实际使用最后一个规则)

我也尝试过使用状态并将flex文件中的最后一个规则更改为

<STATE_CONTENT> .* { 
    yylval.sval = strdup(yytext);
    return ANY_TEXT;
} 

但是,这将在containint unrecognized rule行上导致%%错误。

1 个答案:

答案 0 :(得分:0)

为什么优先选择最后一条规则的原因:

lex使用最长的匹配时间 。 。*比其他任何字符都适合更多字符。因此,ANY_TEXT始终是选择。

要解决此问题,请按以下步骤更改它:

parser.l

删除 componentDidMount() { this.database.once("value", function(snapshot) { snapshot.forEach(function(data) { this.setState({users: data.val()}) }.bind(this)} }.bind(this)); } -规则并添加此规则:

.*

此规则的最长匹配项仅为一个字符。因此,与其他规则相比,它的优先级最低。

parser.y

添加新令牌:

. { 
    yylval.cval = *yytext;
    return ANY_CHAR;
}

要对整个字符串执行操作,请添加:

%token <cval> ANY_CHAR

@State问题:来自rici的答案:

  

无论模式前面是否带有状态,都不能在模式之前加上空格。换句话说,从技术上讲更准确的是,模式不能包含未引用的空格,而前缀是模式的一部分