Flex-lexer:后面的规则优先于前面的规则

Flex-lexer: later rule get priority over prior rule

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

例如:

问题: Bison 不会将 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);
}

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

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

但这会导致包含 %%.

行出现 unrecognized rule 错误

为什么优先考虑最后一条规则:

lex 使用最长匹配。并且 .* 比其他任何东西都适合更多的字符。因此 ANY_TEXT 总是被采纳的选择。

要解决它,请像这样更改它:

parser.l:

删除 .*-规则并添加此规则:

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

这条规则的最长匹配只有一个个字符。因此,与其他规则相比,它的优先级最低。

parser.y:

添加新令牌:

%token <cval> ANY_CHAR

要作用于整个字符串,添加:

  anyText:
      anyText ANY_CHAR { cout << ; }    
      |
  ;

@状态问题: rici的回答:

You cannot put whitespace before the pattern, whether or not it is preceded by a state. Another way of saying that, which is technically more accurate, is that patterns cannot contain unquoted whitespace, and the prefix is part of the pattern