如何在lex中匹配可选标记

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

我的文件带有如下字符串。

PORT = en, PIN = P3; 
PORT = dummy[9], PIN = P41;
PORT = dummy[8], PIN = P42;
PORT = dummy[7], PIN = P43;
PORT = dummy[6], PIN = P44;
PORT = dummy[5], PIN = P45;
PORT = dummy[4], PIN = P46;
PORT = dummy[3], PIN = P47;
PORT = dummy[2], PIN = P48;
PORT = dummy[1], PIN = P49;
PORT = dummy[0], PIN = P50;
PORT = out1, PIN = P6; 

我正在尝试使用PORT如下提取PINlex

lex grammer。

%%
"="                    { return EQUALS; }
","                    { return COMMA; }
";"                    { return SEMICOLON; }
PORT                   { return PORT; }
PIN                    { return PIN; }
[\[0-9\]]* {yylval.str =strdup(yytext);return BUS_PORT;}
[a-zA-Z_][a-zA-Z0-9_]* {yylval.str =strdup(yytext);return ALPHANUMERIC;}
"//".* | [\t]          {; }
"/*"[.\n]*"*/"         {; }
\n                     {; }
.                      {; }
%%

以及相应的yacc文件。

%token EQUALS
%token COMMA
%token SEMICOLON
%token PIN
%token PORT
%token <str> ALPHANUMERIC
%token <str> BUS_PORT
%type <str> port_name
%type <str> pin_name

%%

physical_command : sub_command
                 | physical_command sub_command
                 ;
sub_command      : port_command
                 ;

port_command     : PORT EQUALS port_name COMMA PIN EQUALS pin_name SEMICOLON
                 {
                   pm->addPortAndPin(std::string($3),std::string($7));
                 }
                 ;

port_name        : ALPHANUMERIC
                 | ALPHANUMERIC BUS_PORT
                 {
                   $$ = $1;
                 }
                 ;
pin_name         : ALPHANUMERIC
                 {
                   $$ = $1;
                 }
                 ;
%%

如果看到port名称,则可以是数组类型{dummy[10]dummy[9] .. etc}或普通类型。为了解析它,我写了如下规则。

port_name        : ALPHANUMERIC //for normal type
                 | ALPHANUMERIC BUS_PORT  //for array type
                 {
                   $$ = $1;
                 }

语法是

[\[0-9\]]* {yylval.str =strdup(yytext);return BUS_PORT;}
[a-zA-Z_][a-zA-Z0-9_]* {yylval.str =strdup(yytext);return ALPHANUMERIC;}

我的问题:

我无法使用上述规则解析数组类型,我的输出如下所示。请为我提供一些规则,以便我可以解析常规和数组类型。

Port = en       Pin = P3
Port = dummy    Pin = P41 //should have been dummy[9]
Port = dummy    Pin = P42 //should have been dummy[8]
Port = dummy    Pin = P43
Port = dummy    Pin = P44
Port = dummy    Pin = P45
Port = dummy    Pin = P46
Port = dummy    Pin = P47
Port = dummy    Pin = P48
Port = dummy    Pin = P49
Port = dummy    Pin = P50
Port = out1     Pin = P6
c yacc lex
1个回答
0
投票

数组元素访问操作,其中每个开头'['应该具有相应的结尾']'在解析级别进行处理。

在lex规范中,替换

[\[0-9\]]* {yylval.str =strdup(yytext);return BUS_PORT;}

作者

  [0-9]+   {}
   "["     { return *yytext;} 
   "]"     { return *yytext;}

在解析器规范中,替换

  port_name  : ALPHANUMERIC
             | ALPHANUMERIC BUS_PORT { $$ = $1;}

作者

  port_name  : ALPHANUMERIC
             | ALPHANUMERIC '[' BUS_PORT ']' { $$ = $1;}

另一个解决方案是,将BUS_PORT令牌规则更改为

  \[[0-9]+\] {yylval.str =strdup(yytext);return BUS_PORT;}

[它识别[后跟一个或一个数字,然后是],仅适用于固定数量的尺寸

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