0

私は次の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          _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;  }
                ;               

%%

3つのシフト削減の競合を与えています.どうすればそれらを削除できますか????

4

1 に答える 1

1

shift-reduceの競合は、文法が説明する「小さな言語」に固有のものです。入力トークンのストリームを検討してください

_DTP_LONG _DTP_LONG _DTP_LONG EOS

それぞれ_DTP_LONGをとして減らすことができますNumber。しかし、

Number Number Number

DateShortExpr1の数字の後に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

パーサーが行うことは、ルール11()で減らすのではなく、ルール12をシフトして適用することDateShortExpr : Numberです。これは、パーサーがシングルNumberDateShortExpr;として解釈することは決してないことを意味します。常にシフトします。

また、デフォルトの動作に依存することの難しさは、文法を変更すると変更される可能性があることです。

于 2013-02-11T14:40:35.227 に答える