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
以获得 mildt
或 month
表示 mondt
-- 直到第 4 个标记才能知道。
您可以通过删除所有相同的单一规则(month/day/hour/minute)来避免这种情况:
mildt: TWODIGITS TWODIGITS TWODIGITS TZONE
mondt: TWODIGITS TWODIGITS TWODIGITS TWODIGITS TZONE
这样一来,什么都不需要减少,直到你到达最后的TZONE
并且知道有多少位。
我的数据包含日期时间值。日期时间值可以用军事日期时间表示:
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
以获得 mildt
或 month
表示 mondt
-- 直到第 4 个标记才能知道。
您可以通过删除所有相同的单一规则(month/day/hour/minute)来避免这种情况:
mildt: TWODIGITS TWODIGITS TWODIGITS TZONE
mondt: TWODIGITS TWODIGITS TWODIGITS TWODIGITS TZONE
这样一来,什么都不需要减少,直到你到达最后的TZONE
并且知道有多少位。