Reduce/reduce 与两种日期时间格式的规则冲突

Reduce/reduce conflict with a rule for two datetime formats

我的数据包含日期时间值。日期时间值可以用军事日期时间表示:

day hour minute timezone

示例:081837Z

或者,日期时间值可以用月份日期时间表示:

month day hour minute timezone

示例:08081837Z

野牛报告:1 reduce/reduce conflict

月、日、小时和分钟的值都是 2 位数字,所以我的词法分析器只是为每个值向解析器发送一个 2 位数字的标记:

{TWODGT} { yylval.sval = malloc(yyleng + 1); strcpy(yylval.sval, yytext); return(TWODIGITS); }

为什么我会遇到 reduce/reduce 冲突?我需要做什么来解决这个问题?下面是我的词法分析器,然后是我的解析器。

这是“.l”文件:

%{
#include "helloworld.tab.h"
%}


TWODGT [0-9]{2,2}
TZONE  Z

%%
{TWODGT}        { yylval.sval = malloc(yyleng + 1); strcpy(yylval.sval, yytext); return(TWODIGITS); }
{TZONE}         { yylval.sval = malloc(yyleng + 1); strcpy(yylval.sval, yytext); return(TZONE); }
\n              { return(EOL); }
%%
int yywrap(){ return 1;}

这是“.y”文件:

%{
#include <stdio.h>
int yylex(void);
extern FILE *yyin;
void yyerror(const char* msg);
%}

%union
{
  char *sval;
}
%token <sval> TWODIGITS TZONE 
%token EOL

%type <sval> time tzone mildt mondt month day hour minute 

%start test

%%
test: time EOL  { printf("%s\n> ", ); }
 ;
 
time: mildt                 { $$ = "Military DateTime"; }
 | mondt                    { $$ = "Month DateTime"; }
;

mildt: day hour minute tzone        
;

mondt: month day hour minute tzone  
;

month: TWODIGITS                      
;

day: TWODIGITS                      
;

hour: TWODIGITS                     
;

minute: TWODIGITS                   
;

tzone: TZONE                        
;

%%

int main(int argc, char *argv[])
{
    yyin = fopen(argv[1], "r");
    yyparse();
    fclose(yyin);
    
    return 0;
}

void yyerror(const char *msg)
{
  fprintf(stderr, "error: %s\n", msg);
}

你遇到的基本问题是前瞻性——当解析器看到第一个 TWODIGITS 标记时,它不知道是否应该将它缩减为 day 以获得 mildtmonth 表示 mondt -- 直到第 4 个标记才能知道。

您可以通过删除所有相同的单一规则(month/day/hour/minute)来避免这种情况:

mildt: TWODIGITS TWODIGITS TWODIGITS TZONE
mondt: TWODIGITS TWODIGITS TWODIGITS TWODIGITS TZONE

这样一来,什么都不需要减少,直到你到达最后的TZONE并且知道有多少位。