Datetime 使用YACC shift的日期时间分析器减少冲突
我有下面的YACC解析器Datetime 使用YACC shift的日期时间分析器减少冲突,datetime,yacc,shift-reduce-conflict,Datetime,Yacc,Shift Reduce Conflict,我有下面的YACC解析器 %start Start %token _DTP_LONG // Any number; Max upto 4 Digits. %token _DTP_SDF // 17 Digit number indicating SDF format of Date Time %token _DTP_EOS // end of input %token
%start Start
%token _DTP_LONG // Any number; Max upto 4 Digits.
%token _DTP_SDF // 17 Digit number indicating SDF format of Date Time
%token _DTP_EOS // end of input
%token _DTP_MONTH //Month names e.g Jan,Feb
%token _DTP_AM //Is A.M
%token _DTP_PM //Is P.M
%%
Start : DateTimeShortExpr
| DateTimeLongExpr
| SDFDateTimeExpr EOS
| DateShortExpr EOS
| DateLongExpr EOS
| MonthExpr EOS
;
DateTimeShortExpr : DateShortExpr TimeExpr EOS {;}
| DateShortExpr AMPMTimeExpr EOS {;}
;
DateTimeLongExpr : DateLongExpr TimeExpr EOS {;}
| DateLongExpr AMPMTimeExpr EOS {;}
;
DateShortExpr : Number { rc = vDateTime.SetDate ((Word) $1, 0, 0);
}
| Number Number { rc = vDateTime.SetDate ((Word) $1, (Word) $2, 0); }
| Number Number Number { rc = vDateTime.SetDate ((Word) $1, (Word) $2, (Word) $3); }
;
DateLongExpr : Number AbsMonth { // case : number greater than 31, consider as year
if ($1 > 31) {
rc = vDateTime.SetDateFunc (1, (Word) $2, (Word) $1);
}
// Number is considered as days
else {
rc = vDateTime.SetDateFunc ((Word) $1, (Word) $2, 0);
}
}
| Number AbsMonth Number {rc = vDateTime.SetDateFunc((Word) $1, (Word) $2, (Word) $3);}
;
TimeExpr : Number { rc = vDateTime.SetTime ((Word) $1, 0, 0);}
| Number Number { rc = vDateTime.SetTime ((Word) $1, (Word) $2, 0); }
| Number Number Number { rc = vDateTime.SetTime ((Word) $1, (Word) $2, (Word) $3); }
;
AMPMTimeExpr : TimeExpr _DTP_AM { rc = vDateTime.SetTo24hr(TP_AM) ; }
| TimeExpr _DTP_PM { rc = vDateTime.SetTo24hr(TP_PM) ; }
| _DTP_AM TimeExpr { rc = vDateTime.SetTo24hr(TP_AM) ; }
| _DTP_PM TimeExpr { rc = vDateTime.SetTo24hr(TP_PM) ; }
;
SDFDateTimeExpr : SDFNumber { rc = vDateTime.SetSDF ($1);}
;
MonthExpr : AbsMonth { rc = vDateTime.SetNrmMth ($1);}
| AbsMonth Number { rc = vDateTime.Set ($1,$2);}
;
Number : _DTP_LONG { $$ = $1; }
;
SDFNumber : _DTP_SDF { $$ = $1; }
;
EOS : _DTP_EOS { $$ = $1; }
;
AbsMonth : _DTP_MONTH { $$ = $1; }
;
%%
它给出了三个移位-减少冲突。我如何删除它们???移位-减少冲突是语法描述的“小语言”所固有的。考虑输入令牌流< /P>
_DTP_LONG _DTP_LONG _DTP_LONG EOS
每个\u DTP\u LONG
可以减少为一个数字
。但是应该
Number Number Number
是否减少为1号DateShortExpr
后接2号TimeExpr
或2号DateShortExpr
后接1号TimeShortExpr
?这种模糊性是内在的
如果可能的话,可以通过添加其他符号来重新设计您的语言,以区分日期和时间——例如,冒号表示时间的各个部分,斜杠表示日期的各个部分
更新
我不认为您可以在这里使用yacc/bison的特性,因为标记是无法区分的
当yacc/bison遇到一个问题时,您必须依赖它的默认行为,也就是说,改变而不是减少。在输出中考虑这个例子:
+------------------------- STATE 9 -------------------------+
+ CONFLICTS:
? sft/red (shift & new state 12, rule 11) on _DTP_LONG
+ RULES:
DateShortExpr : Number^ (rule 11)
DateShortExpr : Number^Number
DateShortExpr : Number^Number Number
DateLongExpr : Number^AbsMonth
DateLongExpr : Number^AbsMonth Number
+ ACTIONS AND GOTOS:
_DTP_LONG : shift & new state 12
_DTP_MONTH : shift & new state 13
: reduce by rule 11
Number : goto state 26
AbsMonth : goto state 27
解析器将要做的是移位并应用规则12,而不是按规则11减少(DateShortExpr:Number
)。这意味着解析器永远不会将单个数字
解释为DateShortExpr
;它总是会改变的
依赖默认行为的一个困难是,当您修改语法时,默认行为可能会发生变化。您能指出在哪里会发生这种情况吗?另外,请花一些时间格式化您的代码。@leppie:这是lrt文件,我不想让用户放置指定的分隔符……我知道它是内置的,但我们可以通过应用某种优先级来抑制它们吗