anagram_1.0.0_49233f56/sources/anagram-grammars_debug.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
--  Copyright (c) 2010-2017 Maxim Reznik <reznikmm@gmail.com>
--
--  SPDX-License-Identifier: MIT
--  License-Filename: LICENSE
-------------------------------------------------------------

with Ada.Wide_Wide_Text_IO;
with Anagram.Grammars.LR;

package body Anagram.Grammars_Debug is

   -----------
   -- Print --
   -----------

   procedure Print (Self : Anagram.Grammars.Grammar) is
      use Ada.Wide_Wide_Text_IO;
      use Anagram.Grammars;

      procedure Print_Attr (Attr : Attribute_Index);
      procedure Print_Productions (First, Last : Production_Count);
      procedure Print_Declarations (First, Last : Attribute_Declaration_Count);
      function Is_List (X : Boolean) return Wide_Wide_String;

      procedure Print_Attr (Attr : Attribute_Index) is
      begin
         if Self.Attribute (Attr).Is_Left_Hand_Side then
            Put ("LHS.");
         else
            Put (Self.Part (Self.Attribute (Attr).Origin).Name.
                   To_Wide_Wide_String & ".");
         end if;

         Put_Line (Self.Declaration (Self.Attribute (Attr).Declaration).Name.
                     To_Wide_Wide_String);
      end Print_Attr;

      procedure Print_Declarations
        (First, Last : Attribute_Declaration_Count) is
      begin
         for D in First .. Last loop
            Put_Line
              ("  Attr: " & Self.Declaration (D).Name.To_Wide_Wide_String &
                 " inherited=" &
                 Boolean'Wide_Wide_Image (Self.Declaration (D).Is_Inherited));
         end loop;
      end Print_Declarations;

      procedure Print_Productions (First, Last : Production_Count) is
      begin
         for P in First .. Last loop
            Put_Line ("  Production: " &
                        Self.Production (P).Name.To_Wide_Wide_String &
                      " (" & Production_Index'Wide_Wide_Image (P) & ")");

            for R in Part_Count'(Self.Production (P).First) ..
              Self.Production (P).Last
            loop
               Put ("    " & Self.Part (R).Name.To_Wide_Wide_String);

               if Self.Part (R).Is_Terminal_Reference then
                  Put_Line (" refs " & Self.Terminal (Self.Part (R).Denote)
                              .Image.To_Wide_Wide_String);
               elsif Self.Part (R).Is_Non_Terminal_Reference then
                  Put_Line (" refs " & Self.Non_Terminal (Self.Part (R).Denote)
                              .Name.To_Wide_Wide_String);
               else
                  if Self.Part (R).Is_List_Reference then
                     Put_Line (" List:" &
                                 Self.Non_Terminal (Self.Part (R).Denote)
                                   .Name.To_Wide_Wide_String);
                  else
                     Put_Line (" Option:");

                     Print_Productions
                       (Self.Part (R).First, Self.Part (R).Last);

                     Put_Line (" End");
                  end if;
               end if;
            end loop;

            for R in Self.Production (P).First_Rule ..
              Self.Production (P).Last_Rule
            loop
               Put_Line ("Rule: ");
               Put ("  Result: ");
               Print_Attr (Self.Rule (R).Result);

               for A in Self.Rule (R).First_Argument ..
                 Self.Rule (R).Last_Argument
               loop
                  Put ("  Arg: ");
                  Print_Attr (A);
               end loop;
            end loop;
         end loop;
      end Print_Productions;

      function Is_List (X : Boolean) return Wide_Wide_String is
      begin
         if X then
            return " (List)";
         else
            return "";
         end if;
      end Is_List;
   begin
      Put_Line ("Terminals:");

      for J in 1 .. Self.Last_Terminal loop
         Put_Line (Terminal_Count'Wide_Wide_Image (J) & " " &
                     Self.Terminal (J).Image.To_Wide_Wide_String);

         Print_Declarations
           (Self.Terminal (J).First_Attribute,
            Self.Terminal (J).Last_Attribute);
      end loop;

      Put_Line ("Non Terminals:");

      for J in 1 .. Self.Last_Non_Terminal loop
         Put_Line (Non_Terminal_Count'Wide_Wide_Image (J) & " " &
                     Self.Non_Terminal (J).Name.To_Wide_Wide_String &
                     Is_List (Self.Non_Terminal (J).Is_List));

         Print_Declarations
           (Self.Non_Terminal (J).First_Attribute,
            Self.Non_Terminal (J).Last_Attribute);

         Print_Productions
           (Self.Non_Terminal (J).First, Self.Non_Terminal (J).Last);
      end loop;
   end Print;

   ---------------------
   -- Print_Conflicts --
   ---------------------

   procedure Print_Conflicts (Self  : Anagram.Grammars.Grammar;
                              Table : Anagram.Grammars.LR_Tables.Table)
   is
      use Ada.Wide_Wide_Text_IO;
      use Anagram.Grammars.LR_Tables;
      use type Anagram.Grammars.LR.State_Count;

      procedure Print_State (State : Anagram.Grammars.LR.State_Index);
      procedure Print_Reduce
        (Prefix : Wide_Wide_String;
         R      : in out Reduce_Iterator);
      procedure Print_Conflict
        (Prefix : Wide_Wide_String;
         T      : Anagram.Grammars.Terminal_Count);

      ------------------
      -- Print_Reduce --
      ------------------

      procedure Print_Reduce
        (Prefix : Wide_Wide_String;
         R      : in out Reduce_Iterator)
      is
         P  : Anagram.Grammars.Production_Index;
         NT : Anagram.Grammars.Non_Terminal_Index;
      begin
         while not Is_Empty (R) loop
            P := Production (R);
            NT := Self.Production (P).Parent;

            Put_Line
              (Prefix & "Non terminal "
               & Self.Non_Terminal (NT).Name.To_Wide_Wide_String
               & " production "
               & Self.Production (P).Name.To_Wide_Wide_String);

            Next (Table, R);
         end loop;
      end Print_Reduce;

      -----------------
      -- Print_State --
      -----------------

      procedure Print_State (State : Anagram.Grammars.LR.State_Index) is
      begin
         Put_Line
           ("State:" &
              Anagram.Grammars.LR.State_Index'Wide_Wide_Image (State));
      end Print_State;

      procedure Print_Conflict
        (Prefix : Wide_Wide_String;
         T      : Anagram.Grammars.Terminal_Count)
      is
         use type Anagram.Grammars.Terminal_Count;
      begin
         if T = 0 then
            Put_Line (Prefix & " conflict on token End_Of_File");
         else
            Put_Line
              (Prefix & " conflict on token '"
               & Self.Terminal (T).Image.To_Wide_Wide_String
               & "'");
         end if;
      end Print_Conflict;

      State_Printed : Boolean;

      S : Anagram.Grammars.LR.State_Count;
      R : Reduce_Iterator;
   begin
      for State in 1 .. Last_State (Table) loop
         State_Printed := False;

         for T in 0 .. Self.Last_Terminal loop
            S := Shift (Table, State, T);
            R := Reduce (Table, State, T);

            if S /= 0 then
               if not Is_Empty (R) then
                  if not State_Printed then
                     State_Printed := True;
                     Print_State (State);
                  end if;

                  Print_Conflict ("Shift/Reduce", T);

                  Put ("Shift to ");
                  Print_State (S);
                  Print_Reduce ("Shift/Reduce ", R);
               end if;
            elsif not Is_Empty (R) then
               declare
                  Save : Reduce_Iterator := R;
               begin
                  Next (Table, R);

                  if not Is_Empty (R) then
                     if not State_Printed then
                        State_Printed := True;
                        Print_State (State);
                     end if;

                     Print_Conflict ("Reduce/Reduce", T);

                     Print_Reduce ("Reduce/Reduce ", Save);
                  end if;
               end;
            end if;
         end loop;
      end loop;
   end Print_Conflicts;

end Anagram.Grammars_Debug;