Flex的词法分析器:对现有规则后的规则获得优先权

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

我试图从一个C / C ++的资源文件的信息。我试图提取宏的内容。

E.g:

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

问题:北美野牛不会承认MYMACRO作为标记。

这个代码是仅在第一步骤中,我们期望仅宏本身作为输入

莱克斯 - 文件: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;
} 

但是,这将导致对含qazxsw POI行的qazxsw POI错误。

bison flex-lexer
1个回答
0
投票

究其原因,为什么最后一个规则可以采取优先:

法采用最长匹配。和*适合多个字符,比什么都重要。因此ANY_TEXT总是采取的选择。

为了解决它改变这样的:

parser.l:

除去unrecognized rule规则,并添加这一项:

%%

这条规则的最长匹配的是只有一个字符。因此,这将是对最低优先级相对于其他规则。

parser.y:

添加一个新的令牌:

.*

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

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

@state问题:从RICI答案:

你不能把空白的模式之前,无论它是否是由一个国家之前。说,这在技术上是更准确的另一种方式是,图案不能包含空格不带引号,并且前缀为模式的一部分

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