-------------------------------------------------
--                                             --
--         Parser generated by Coco/R          --
--                                             --
-- (assuming FileIO library will be available) --
-------------------------------------------------

with  CRT;
with  CRA;
with  CRS;

package body CRP is

   identifier  : constant := 0;
   str_const   : constant := 1;


   function CHR (Item: Integer) return Character
   is
   begin
      return Character'Val (Item);
   end CHR;
   pragma Inline (CHR);

   function ORD (Item: Character) return Integer
   is
   begin
      return Character'Pos (Item);
   end ORD;
   pragma Inline (ORD);

   function Allocate_String (S : String) return FileIO.String_Ptr
   is
      P : FileIO.String_Ptr;
   begin
      P := new String'(S);
      return P;
   end Allocate_String;
   pragma Inline (Allocate_String);


   procedure Fix_String
     (name  : in out String;
      len   : in     CARDINAL)
   is
      Has_Double  : Boolean;
      Has_Spaces  : Boolean;
   begin
      if  len = 2  then
         Semantic_Error (129);
         return;
      end if;
      if  CRT.ignoreCase  then
         for  I  in 2..(len - 1)  loop
            name (I) := FileIO.Up_Case (name (I));
         end loop;
      end if;

      Has_Double := FALSE;
      Has_Spaces := FALSE;

      for  I  in 2..(len - 1)  loop
         if  name (I) = '"'  then
            Has_Double := TRUE;
         end if;
         if  name (I) <= ' '  then
            Has_Spaces := TRUE;
         end if;
      end loop;
      if  not Has_Double  then
         name (1)   := '"';
         name (len) := '"';
      end if;
      if  Has_Spaces  then
         Semantic_Error (124);
      end if;
   end Fix_String;

   procedure Match_Literal (sp: in     Integer)
   is
      sn       :  CRT.Symbol_Node;
      sn1      :  CRT.Symbol_Node;
      matchedSp: Integer;
   begin
      CRT.Get_Symbol_Node (sp, sn);
      CRA.Match_DFA (sn.Symbol_Name.all, sp, matchedSp);
      if  matchedSp /= CRT.No_Symbol  then
         CRT.Get_Symbol_Node (matchedSp, sn1);
         sn1.struct := CRT.TK_Class_Literal_Token;
         CRT.Put_Symbol_Node (matchedSp, sn1);
         sn.struct := CRT.TK_Literal_Token;
      else
         sn.struct := CRT.TK_Class_Token;
      end if;
      CRT.Put_Symbol_Node (sp, sn);
   end Match_Literal;

   procedure Set_Context (gp: in     Integer)
   is
      The_Graph_Index: Integer         := gp;
      The_Graph_Node : CRT.Graph_Node;
   begin
      while  The_Graph_Index > 0  loop
         CRT.Get_Graph_Node (The_Graph_Index, The_Graph_Node);
         if  (The_Graph_Node.Node_Type = CRT.NT_Single_Character) or else
             (The_Graph_Node.Node_Type = CRT.NT_Character_Class)  then
            The_Graph_Node.Index_2 := CRT.contextTrans;
            CRT.Put_Graph_Node (The_Graph_Index, The_Graph_Node);
         elsif  (The_Graph_Node.Node_Type = CRT.NT_Optional) or else
                (The_Graph_Node.Node_Type = CRT.NT_Iteration)  then
            Set_Context (The_Graph_Node.Index_1);
         elsif  The_Graph_Node.Node_Type = CRT.NT_Alternative  then
            Set_Context (The_Graph_Node.Index_1);
            Set_Context (The_Graph_Node.Index_2);
         end if;
         The_Graph_Index := The_Graph_Node.next;
      end loop;
   end Set_Context;

   procedure Set_Option (S: in out FileIO.String_Ptr)
   is
   begin
      for  I in S.all'Range  loop
         S (I) := FileIO.Up_Case (S (I));
         if  (S (I) >= 'A') and then
             (S (I) <= 'Z')  then
            CRT.ddt (S (I)) := TRUE;
         end if;
      end loop;
      FileIO.Free_String (S);
      S := null;
   end Set_Option;







   --
   -- Report semantic error errNo
   --
   procedure Semantic_Error (errNo: in     Integer)
   is
   begin
      if  errDist >= minErrDist  then
         CRS.Error (errNo, CRS.line, CRS.col, CRS.pos);
      end if;
      errDist := 0;
   end Semantic_Error;


   --
   -- Report syntax error errNo
   --
   procedure Syntax_Error (errNo: in     Integer)
   is
   begin
      if  errDist >= minErrDist  then
         CRS.Error (errNo, CRS.nextLine, CRS.nextCol, CRS.nextPos);
      end if;
      errDist := 0;
   end Syntax_Error;


   procedure Get
   is
      S: FileIO.String_Ptr;
   begin
      loop
         CRS.Get (sym);
         if  sym <= maxT  then
            errDist := errDist + 1;
         else
            case  sym  is
               when 42 =>
                  CRS.Get_Name (CRS.nextPos, CRS.nextLen, S);
                  Set_Option (S);
               when others =>
                  null;
            end case;
            CRS.nextPos  := CRS.pos;
            CRS.nextCol  := CRS.col;
            CRS.nextLine := CRS.line;
            CRS.nextLen  := CRS.len;
         end if;
         exit when sym <= maxT;
      end loop;
   end Get;


   function Is_In
     (s: in     SymbolSet;
      x: in     CARDINAL)
     return Boolean
   is
   begin
      return  Sets.Is_In ((x mod setsize), s (x / setsize));
   end Is_In;

   procedure Is_In
     (s     : in out SymbolSet;
      x     : in     CARDINAL;
      Result:    out Boolean)
   is
   begin
      Result := Sets.Is_In ((x mod setsize), s (x / setsize));
   end Is_In;


   procedure Expect (n: in     CARDINAL)
   is
   begin
      if  sym = n  then
         Get;
      else
         Syntax_Error (n);
      end if;
   end Expect;


   procedure Expect_Weak
     (n     : CARDINAL;
      follow: CARDINAL)
   is
      Is_In_Result : Boolean;
   begin
      if  sym = n  then
         Get;
      else
         Syntax_Error (n);
   --       while  not Is_In (symSet (follow), sym)  loop
   --          Get;
   --       end loop;
         loop
            Is_In (symSet (follow), sym, Is_In_Result);
            exit when not Is_In_Result;
            Get;
         end loop;
      end if;
   end Expect_Weak;


   function Weak_Separator
     (n     : CARDINAL;
      syFol : CARDINAL;
      repFol: CARDINAL)
     return Boolean
   is
      use type Sets.BitSet;

      s           : SymbolSet;
      I           : CARDINAL;
      Is_In_Result: Boolean;
   begin
      if  sym = n  then
         Get;
         return TRUE;
      else
         Is_In (symSet (repFol), sym, Is_In_Result);
         if  Is_In_Result  then
            return FALSE;
         else
            I := 0;
            while  (I <= (maxT / setsize))  loop
               s (I) := symSet (0) (I) + symSet (syFol) (I) + symSet (repFol) (I);
               I := I + 1;
            end loop;
            Syntax_Error (n);
            loop
               Is_In (s, sym, Is_In_Result);
               exit when not Is_In_Result;
               Get;
            end loop;

            Is_In (symSet (syFol), sym, Is_In_Result);
            return Is_In_Result;
         end if;
      end if;
   end Weak_Separator;


   --
   -- Retrieves Lex as name of current token (capitalized if IGNORE case )
   --
   procedure Lex_Name (Lex:    out FileIO.String_Ptr)
   is
   begin
      CRS.Get_Name (CRS.pos, CRS.len, Lex);
   end Lex_Name;


   --
   -- Retrieves Lex as exact spelling of current token
   --
   procedure Lex_String (Lex:    out FileIO.String_Ptr)
   is
   begin
      CRS.Get_String (CRS.pos, CRS.len, Lex);
   end Lex_String;


   --
   -- Retrieves Lex as exact spelling of lookahead token
   --
   procedure Look_Ahead_Name (Lex:    out FileIO.String_Ptr)
   is
   begin
      CRS.Get_Name (CRS.nextPos, CRS.nextLen, Lex);
   end Look_Ahead_Name;


   --
   -- Retrieves Lex as name of lookahead token (capitalized if IGNORE case )
   --
   procedure Look_Ahead_String (Lex:    out FileIO.String_Ptr)
   is
   begin
      CRS.Get_String (CRS.nextPos, CRS.nextLen, Lex);
   end Look_Ahead_String;


   --
   -- Returns TRUE if no errors have been recorded while parsing
   --
   function Successful return Boolean
   is
   begin
      return CRS.errors = 0;
   end Successful;


   procedure Token_Factor (gL: in out Integer; gR: in out Integer);
   procedure Token_Term (gL: in out Integer; gR: in out Integer);
   procedure Factor (gL: in out Integer; gR: in out Integer);
   procedure Term (gL: in out Integer; gR: in out Integer);
   procedure Symbol (name: in out CRT.Name_Ptr; kind: in out Integer);
   procedure Single_Character (n: in out CARDINAL);
   procedure Symbol_Set (the_set: in out CRT.CRT_Set);
   procedure Set (the_set: in out CRT.CRT_Set);
   procedure Token_Expression (gL: in out Integer; gR: in out Integer);
   procedure Name_Declaration;
   procedure Token_Declaration (typ: Integer);
   procedure Set_Declaration;
   procedure Expression (gL: in out Integer; gR: in out Integer);
   procedure Semantic_Text (The_Sem_Action_Pos: in out CRT.Position);
   procedure Attributes (Attr_Pos: in out CRT.Position);
   procedure Declaration (startedDFA: in out Boolean);
   procedure Ident (name: in out CRT.Name_Ptr);
   procedure CR;

   procedure Token_Factor (gL: in out Integer; gR: in out Integer)
   is
      kind  : Integer;
      c     : Integer;
      the_set   : CRT.CRT_Set;
      name  : CRT.Name_Ptr;
   begin -- Token_Factor
      gL := 0;
      gR := 0;
      if  (sym = 1) or else (sym = 2)  then
         Symbol (name, kind);
         if  kind = identifier  then
            c := CRT.Get_Class_By_Name (name.all);
            if  c < 0  then
               Semantic_Error (115);
               Sets.Clear (the_set);
               c := CRT.New_Character_Class (name, the_set);
            end if;
            gL := CRT.New_Graph_Node (CRT.NT_Character_Class, c, 0);
            gR := gL;
         else
            CRT.String_To_Graph (name.all, gL, gR);
         end if;
      elsif  (sym = 25)  then
         Get;
         Token_Expression (gL, gR);
         Expect (26);
      elsif  (sym = 29)  then
         Get;
         Token_Expression (gL, gR);
         Expect (30);
         CRT.Make_Option (gL, gR);
      elsif  (sym = 31)  then
         Get;
         Token_Expression (gL, gR);
         Expect (32);
         CRT.Make_Iteration (gL, gR);
      else
         Syntax_Error (42);
      end if;
   end Token_Factor;

   procedure Token_Term (gL: in out Integer; gR: in out Integer)
   is
      gL2: Integer;
      gR2: Integer;
   begin -- Token_Term
      Token_Factor (gL, gR);
      while  (sym = 1) or else (sym = 2) or else (sym = 25) or else (sym = 29) or else (sym = 31)  loop
         Token_Factor (gL2, gR2);
         CRT.Concatenate_Sequential (gL, gR, gL2, gR2);
      end loop;
      if  (sym = 34)  then
         Get;
         Expect (25);
         Token_Expression (gL2, gR2);
         Set_Context (gL2);
         CRT.Concatenate_Sequential (gL, gR, gL2, gR2);
         Expect (26);
      end if;
   end Token_Term;

   procedure Factor (gL: in out Integer; gR: in out Integer)
   is
      sp      : Integer;
      kind    : Integer;
      name    : CRT.Name_Ptr;
      gn      : CRT.Graph_Node;
      sn      : CRT.Symbol_Node;
      the_set : CRT.CRT_Set;
      undef   : Boolean;
      weak    : Boolean;
      pos     : CRT.Position;
   begin -- Factor
      gL := 0;
      gR := 0;
      weak := FALSE;
      case  sym  is
         when 1 | 2 | 28 =>
            if  (sym = 28)  then
               Get;
               weak := TRUE;
            end if;
            Symbol (name, kind);
            sp    := CRT.Find_Symbol (name.all);
            undef := sp = CRT.No_Symbol;
            if  undef  then
               if  kind = identifier  then
                  sp := CRT.New_Sym (CRT.NT_Nonterminal_Symbol, name, 0);
               elsif  CRT.genScanner  then
                  sp := CRT.New_Sym (CRT.NT_Terminal_Symbol, name, CRS.line);
                  Match_Literal (sp);
               else
                  Semantic_Error (106);
                  sp := 0;
               end if;
            end if;
            CRT.Get_Symbol_Node (sp, sn);
            if  (sn.Node_Type /= CRT.NT_Terminal_Symbol) and then
                (sn.Node_Type /= CRT.NT_Nonterminal_Symbol)  then
               Semantic_Error (104);
            end if;
            if  weak  then
               if  sn.Node_Type = CRT.NT_Terminal_Symbol  then
                  sn.Node_Type := CRT.NT_Weak_Terminal_Symbol;
               else
                  Semantic_Error (123);
               end if;
            end if;
            gL := CRT.New_Graph_Node (sn.Node_Type, sp, CRS.line);
            gR := gL;
            if  (sym = 35) or else (sym = 37)  then
               Attributes (pos);
               CRT.Get_Graph_Node (gL, gn);
               gn.Source_Pos := pos;
               CRT.Put_Graph_Node (gL, gn);
               CRT.Get_Symbol_Node (sp, sn);
               if  sn.Node_Type /= CRT.NT_Nonterminal_Symbol  then
                  Semantic_Error (103);
               end if;
               if  undef  then
                 sn.Attr_Pos := pos;
                 CRT.Put_Symbol_Node (sp, sn);
               elsif  sn.Attr_Pos.Start < 0  then
                  Semantic_Error (105);
               end if;
            elsif  Is_In (symSet (1), sym)  then
               CRT.Get_Symbol_Node (sp, sn);
               if  sn.Attr_Pos.Start >= 0  then
                  Semantic_Error (105);
               end if;
            else
               Syntax_Error (43);
            end if;
         when 25 =>
            Get;
            Expression (gL, gR);
            Expect (26);
         when 29 =>
            Get;
            Expression (gL, gR);
            Expect (30);
            CRT.Make_Option (gL, gR);
         when 31 =>
            Get;
            Expression (gL, gR);
            Expect (32);
            CRT.Make_Iteration (gL, gR);
         when 39 =>
            Semantic_Text (pos);
            gL := CRT.New_Graph_Node (CRT.NT_Semantic_Action, 0, 0);
            gR := gL;
            CRT.Get_Graph_Node (gL, gn);
            gn.Source_Pos := pos;
            CRT.Put_Graph_Node (gL, gn);
         when 23 =>
            Get;
            Sets.Fill (the_set);
            Sets.Excl (the_set, CRT.EOF_Symbol);
            gL := CRT.New_Graph_Node (CRT.NT_ANY_Symbol, CRT.New_Set (the_set), 0);
            gR := gL;
         when 33 =>
            Get;
            gL := CRT.New_Graph_Node (CRT.NT_SYNC_Symbol, 0, 0);
            gR := gL;
         when others =>
            Syntax_Error (44);

      end case;
   end Factor;

   procedure Term (gL: in out Integer; gR: in out Integer)
   is
      gL2         : Integer;
      gR2         : Integer;
   begin -- Term
      gL := 0;
      gR := 0;
      
      if  Is_In (symSet (2), sym)  then
         Factor (gL, gR);
         while  Is_In (symSet (2), sym)  loop
            Factor (gL2, gR2);
            CRT.Concatenate_Sequential (gL, gR, gL2, gR2);
         end loop;
      elsif  (sym = 8) or else (sym = 26) or else (sym = 27) or else (sym = 30) or else (sym = 32)  then
         gL := CRT.New_Graph_Node (CRT.NT_Empty_Alternative, 0, 0);
         gR := gL;
      else
         Syntax_Error (45);
      end if;
   end Term;

   procedure Symbol (name: in out CRT.Name_Ptr; kind: in out Integer)
   is
   begin -- Symbol
      if  (sym = 1)  then
         Ident (name);
         kind := identifier;
      elsif  (sym = 2)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, name);
         kind := str_const;
         Fix_String (name.all, CRS.len);
      else
         Syntax_Error (46);
      end if;
   end Symbol;

   procedure Single_Character (n: in out CARDINAL)
   is
      S: FileIO.String_Ptr;
   begin -- Single_Character
      Expect (24);
      Expect (25);
      if  (sym = 4)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, S);
         n := 0;
         for  I in 1..CRS.len  loop
            n := 10 * n + ORD (S (I)) - ORD ('0');
         end loop;
         if  n > 255  then
            Semantic_Error (118);
            n := n MOD 256;
         end if;
         if  CRT.ignoreCase  then
            n := ORD (FileIO.Up_Case (CHR (n)));
         end if;
      elsif  (sym = 2)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, S);
         if  CRS.len /= 3  then
            Semantic_Error (118);
         end if;
         if  CRT.ignoreCase  then
            S (2) := FileIO.Up_Case (S (2));
         end if;
         n := ORD (S (2));
      else
         Syntax_Error (47);
      end if;
      Expect (26);
   end Single_Character;

   procedure Symbol_Set (the_set: in out CRT.CRT_Set)
   is
      I     : CARDINAL;
      n1    : CARDINAL;
      n2    : CARDINAL;
      c     : Integer;
      name  : CRT.Name_Ptr;
      S     : FileIO.String_Ptr;
   begin -- Symbol_Set
      Sets.Clear (the_set);
      if  (sym = 1)  then
         Ident (name);
         c := CRT.Get_Class_By_Name (name.all);
         if  c < 0  then
            Semantic_Error (115);
         else
            CRT.Get_Character_Class (c, the_set);
         end if;
      elsif  (sym = 2)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, S);
         I := 2;
         while  S (I) /= S (1)  loop
            if  CRT.ignoreCase  then
               S (I) := FileIO.Up_Case (S (I));
            end if;
            Sets.Incl (the_set, ORD (S (I)));
            I := I + 1;
         end loop;
      elsif  (sym = 24)  then
         Single_Character (n1);
         Sets.Incl (the_set, n1);
         if  (sym = 22)  then
            Get;
            Single_Character (n2);
            for  I in n1 .. n2  loop
               Sets.Incl (the_set, I);
            end loop;
         end if;
      elsif  (sym = 23)  then
         Get;
         for  I in 0 .. 255  loop
            Sets.Incl (the_set, I);
         end loop;
      else
         Syntax_Error (48);
      end if;
   end Symbol_Set;

   procedure Set (the_set: in out CRT.CRT_Set)
   is
      set2: CRT.CRT_Set;
   begin -- Set
      Symbol_Set (the_set);
      while  (sym = 20) or else (sym = 21)  loop
         if  (sym = 20)  then
            Get;
            Symbol_Set (set2);
            Sets.Unite (the_set, set2);
         else
            Get;
            Symbol_Set (set2);
            Sets.Differ (the_set, set2);
         end if;
      end loop;
   end Set;

   procedure Token_Expression (gL: in out Integer; gR: in out Integer)
   is
      gL2   : Integer;
      gR2   : Integer;
      first : Boolean;
   begin -- Token_Expression
      Token_Term (gL, gR);
      first := TRUE;
      while  Weak_Separator (27, 3, 4)  loop
         Token_Term (gL2, gR2);
         if  first  then
            CRT.Make_First_Alternative (gL, gR);
            first := FALSE;
         end if;
         CRT.Concatenate_Alternative (gL, gR, gL2, gR2);
      end loop;
   end Token_Expression;

   procedure Name_Declaration
   is
      name  : CRT.Name_Ptr;
      str   : CRT.Name_Ptr;
   begin -- Name_Declaration
      Ident (name);
      Expect (7);
      if  (sym = 1)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, str);
      elsif  (sym = 2)  then
         Get;
         CRS.Get_Name (CRS.pos, CRS.len, str);
         Fix_String   (str.all, CRS.len);
      else
         Syntax_Error (49);
      end if;
      CRT.New_Name (name, str);
      Expect (8);
   end Name_Declaration;

   procedure Token_Declaration (typ: Integer)
   is
      kind  : Integer;
      name  : CRT.Name_Ptr;
      pos   : CRT.Position;
      sp    : Integer;
      gL    : Integer;
      gR    : Integer;
      sn    : CRT.Symbol_Node;
   begin -- Token_Declaration
      Symbol (name, kind);
      if  CRT.Find_Symbol (name.all) /= CRT.No_Symbol  then
         Semantic_Error (107);
      else
         sp := CRT.New_Sym (typ, name, CRS.line);
         CRT.Get_Symbol_Node (sp, sn);
         sn.struct := CRT.TK_Class_Token;
         CRT.Put_Symbol_Node (sp, sn);
      end if;
      while  not ( Is_In (symSet (5), sym))  loop
         Syntax_Error (50);
         Get;
      end loop;
      if  (sym = 7)  then
         Get;
         Token_Expression (gL, gR);
         if  kind /= identifier  then
            Semantic_Error (113);
         end if;
         CRT.Complete_Graph (gR);
         CRA.Convert_To_States (gL, sp);
         Expect (8);
      elsif  Is_In (symSet (6), sym)  then
         if  kind = identifier  then
            CRT.genScanner := FALSE;
         else
            Match_Literal (sp);
         end if;
      else
         Syntax_Error (51);
      end if;
      if  (sym = 39)  then
         Semantic_Text (pos);
         if  typ = CRT.NT_Terminal_Symbol  then
            Semantic_Error (114);
         end if;
         CRT.Get_Symbol_Node (sp, sn);
         sn.Sem_Action_Pos := pos;
         CRT.Put_Symbol_Node (sp, sn);
      end if;
   end Token_Declaration;

   procedure Set_Declaration
   is
      c     : Integer;
      oneSet: CRT.CRT_Set;
      name  : CRT.Name_Ptr;
   begin -- Set_Declaration
      Ident (name);
      c := CRT.Get_Class_By_Name (name.all);
      if  c >= 0  then
         Semantic_Error (107);
      end if;
      Expect (7);
      Set (oneSet);
      if  Sets.Empty (oneSet)  then
         Semantic_Error (101);
      end if;
      c := CRT.New_Character_Class (name, oneSet);
      Expect (8);
   end Set_Declaration;

   procedure Expression (gL: in out Integer; gR: in out Integer)
   is
      gL2   : Integer;
      gR2   : Integer;
      first : Boolean;
   begin -- Expression
      Term (gL, gR);
      first := TRUE;
      while  Weak_Separator (27, 1, 7)  loop
         Term (gL2, gR2);
         if  first  then
           CRT.Make_First_Alternative (gL, gR);
           first := FALSE;
         end if;
         CRT.Concatenate_Alternative (gL, gR, gL2, gR2);
      end loop;
   end Expression;

   procedure Semantic_Text (The_Sem_Action_Pos: in out CRT.Position)
   is
   begin -- Semantic_Text
      Expect (39);
      The_Sem_Action_Pos.Start  := CRS.pos + 2;
      The_Sem_Action_Pos.Column := CRS.col + 2;
      while  Is_In (symSet (8), sym)  loop
         if  Is_In (symSet (9), sym)  then
            Get;
         elsif  (sym = 3)  then
            Get;
            Semantic_Error (102);
         else
            Get;
            Semantic_Error (109);
         end if;
      end loop;
      Expect (40);
      if  (CRS.pos - The_Sem_Action_Pos.Start) > FileIO.INT (CRT.maxSemLen)  then
         Semantic_Error (128);
      end if;
      The_Sem_Action_Pos.Length := FileIO.ORDL (CRS.pos - The_Sem_Action_Pos.Start);
   end Semantic_Text;

   procedure Attributes (Attr_Pos: in out CRT.Position)
   is
   begin -- Attributes
      if  (sym = 35)  then
         Get;
         Attr_Pos.Start  := CRS.pos + 1;
         Attr_Pos.Column := CRS.col + 1;
         while  Is_In (symSet (10), sym)  loop
            if  Is_In (symSet (11), sym)  then
               Get;
            else
               Get;
               Semantic_Error (102);
            end if;
         end loop;
         Expect (36);
         Attr_Pos.Length := FileIO.INTL (CRS.pos - Attr_Pos.Start);
      elsif  (sym = 37)  then
         Get;
         Attr_Pos.Start  := CRS.pos + 2;
         Attr_Pos.Column := CRS.col + 2;
         while  Is_In (symSet (12), sym)  loop
            if  Is_In (symSet (13), sym)  then
               Get;
            else
               Get;
               Semantic_Error (102);
            end if;
         end loop;
         Expect (38);
         Attr_Pos.Length := FileIO.INTL (CRS.pos - Attr_Pos.Start);
      else
         Syntax_Error (52);
      end if;
   end Attributes;

   procedure Declaration (startedDFA: in out Boolean)
   is
      gL1            : Integer;
      gR1            : Integer;
      gL2            : Integer;
      gR2            : Integer;
      nested         : Boolean;
   begin -- Declaration
      case  sym  is
         when 10 =>
            Get;
            while  (sym = 1)  loop
               Set_Declaration;
            end loop;
         when 11 =>
            Get;
            while  (sym = 1) or else (sym = 2)  loop
               Token_Declaration (CRT.NT_Terminal_Symbol);
            end loop;
         when 12 =>
            Get;
            while  (sym = 1)  loop
               Name_Declaration;
            end loop;
         when 13 =>
            Get;
            while  (sym = 1) or else (sym = 2)  loop
               Token_Declaration (CRT.NT_Pragma_Symbol);
            end loop;
         when 14 =>
            Get;
            Expect (15);
            Token_Expression (gL1, gR1);
            Expect (16);
            Token_Expression (gL2, gR2);
            if  (sym = 17)  then
               Get;
               nested := TRUE;
            elsif  Is_In (symSet (14), sym)  then
               nested := FALSE;
            else
               Syntax_Error (53);
            end if;
            CRA.Define_New_Comment (gL1, gL2, nested);
         when 18 =>
            Get;
            if  (sym = 19)  then
               Get;
               if  startedDFA  then
                  Semantic_Error (130);
               end if;
               CRT.ignoreCase := TRUE;
            elsif  (sym = 1) or else (sym = 2) or else (sym = 23) or else (sym = 24)  then
               Set (CRT.ignored);
               if  Sets.Is_In (CRT.ignored, 0)  then
                  Semantic_Error (119);
               end if;
            else
               Syntax_Error (54);
            end if;
         when others =>
            Syntax_Error (55);

      end case;
      startedDFA := TRUE;
   end Declaration;

   procedure Ident (name: in out CRT.Name_Ptr)
   is
   begin -- Ident
      Expect (1);
      CRS.Get_Name (CRS.pos, CRS.len, name);
   end Ident;

   procedure CR
   is
      startedDFA  : Boolean;
      Ok          : Boolean;
      undef       : Boolean;
      hasAttrs    : Boolean;
      unknownSy   : Integer;
      eofSy       : Integer;
      gR          : Integer;
      gramLine    : Integer;
      sp          : Integer;
      name        : CRT.Name_Ptr;
      gramName    : CRT.Name_Ptr;
      sn          : CRT.Symbol_Node;
   begin -- CR
      Expect (5);
      gramLine       := CRS.line;
      eofSy          := CRT.New_Sym (CRT.NT_Terminal_Symbol, Allocate_String ("EOF"), 0);
      CRT.genScanner := TRUE;
      CRT.ignoreCase := FALSE;
      Sets.Clear (CRT.ignored);
      startedDFA     := FALSE;
      Ident (gramName);
      CRT.semDeclPos.Start  := CRS.nextPos;
      while  Is_In (symSet (15), sym)  loop
         Get;
      end loop;
      CRT.semDeclPos.Length := FileIO.INTL (CRS.nextPos - CRT.semDeclPos.Start);
      CRT.semDeclPos.Column := 0;
      while  Is_In (symSet (16), sym)  loop
         Declaration (startedDFA);
      end loop;
      while  not ( (sym = 0) or else (sym = 6))  loop
         Syntax_Error (56);
         Get;
      end loop;
      Expect (6);
      Ok := Successful;
      if  Ok and then CRT.genScanner  then
         CRA.Convert_NDFA_into_DFA (Ok);
      end if;
      if  not Ok  then
         Semantic_Error (127);
      end if;
      CRT.nNodes := 0;
      while  (sym = 1)  loop
         Ident (name);
         sp := CRT.Find_Symbol (name.all);
         undef := sp = CRT.No_Symbol;
         if  undef  then
            sp := CRT.New_Sym (CRT.NT_Nonterminal_Symbol, name, CRS.line);
            CRT.Get_Symbol_Node (sp, sn);
         else
            CRT.Get_Symbol_Node (sp, sn);
            if  sn.Node_Type = CRT.NT_Nonterminal_Symbol  then
               if  sn.struct > 0  then
                  Semantic_Error (107);
               end if;
            else
               Semantic_Error (108);
            end if;
            sn.Source_Line := CRS.line;
         end if;
         hasAttrs := sn.Attr_Pos.Start >= 0;
         if  (sym = 35) or else (sym = 37)  then
            Attributes (sn.Attr_Pos);
            if  not undef and then not hasAttrs  then
               Semantic_Error (105);
            end if;
            CRT.Put_Symbol_Node (sp, sn);
         elsif  (sym = 7) or else (sym = 39)  then
            if  not undef and then hasAttrs  then
               Semantic_Error (105);
            end if;
         else
            Syntax_Error (57);
         end if;
         if  (sym = 39)  then
            Semantic_Text (sn.Sem_Action_Pos);
         end if;
         Expect_Weak (7, 17);
         Expression (sn.struct, gR);
         CRT.Complete_Graph  (gR);
         CRT.Put_Symbol_Node (sp, sn);
         Expect_Weak (8, 18);
      end loop;
      Expect (9);
      Ident (name);
      sp := CRT.Find_Symbol (gramName.all);
      if  sp = CRT.No_Symbol  then
         Semantic_Error (111);
      else
         CRT.Get_Symbol_Node (sp, sn);
         if  sn.Attr_Pos.Start >= 0  then
            Semantic_Error (112);
         end if;
         CRT.root := CRT.New_Graph_Node (CRT.NT_Nonterminal_Symbol, sp, gramLine);
      end if;
      if  name.all /= gramName.all  then
         Semantic_Error (117);
      end if;
      Expect (8);
      unknownSy := CRT.New_Sym (CRT.NT_Terminal_Symbol, Allocate_String ("not"), 0);
   end CR;




   procedure Parse
   is
   begin
      CRS.Reset;
      Get;
      CR;

   end Parse;


begin -- CRP
   errDist := minErrDist;

   symSet ( 0)(0) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 6 => TRUE, 7 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 0)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet ( 0)(2) := Sets.BITSET'(7 => TRUE, others => FALSE);
   symSet ( 1)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 8 => TRUE, others => FALSE);
   symSet ( 1)(1) := Sets.BITSET'(7 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet ( 1)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 7 => TRUE, others => FALSE);
   symSet ( 2)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, others => FALSE);
   symSet ( 2)(1) := Sets.BITSET'(7 => TRUE, 9 => TRUE, 12 => TRUE, 13 => TRUE, 15 => TRUE, others => FALSE);
   symSet ( 2)(2) := Sets.BITSET'(1 => TRUE, 7 => TRUE, others => FALSE);
   symSet ( 3)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, others => FALSE);
   symSet ( 3)(1) := Sets.BITSET'(9 => TRUE, 13 => TRUE, 15 => TRUE, others => FALSE);
   symSet ( 3)(2) := Sets.BITSET'(others => FALSE);
   symSet ( 4)(0) := Sets.BITSET'(6 => TRUE, 8 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 4)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 10 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 4)(2) := Sets.BITSET'(0 => TRUE, others => FALSE);
   symSet ( 5)(0) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 6 => TRUE, 7 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 5)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet ( 5)(2) := Sets.BITSET'(7 => TRUE, others => FALSE);
   symSet ( 6)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 6 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 6)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet ( 6)(2) := Sets.BITSET'(7 => TRUE, others => FALSE);
   symSet ( 7)(0) := Sets.BITSET'(8 => TRUE, others => FALSE);
   symSet ( 7)(1) := Sets.BITSET'(10 => TRUE, 14 => TRUE, others => FALSE);
   symSet ( 7)(2) := Sets.BITSET'(0 => TRUE, others => FALSE);
   symSet ( 8)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet ( 8)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet ( 8)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 9 => TRUE, others => FALSE);
   symSet ( 9)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet ( 9)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet ( 9)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 9 => TRUE, others => FALSE);
   symSet (10)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet (10)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet (10)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, others => FALSE);
   symSet (11)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet (11)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet (11)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, others => FALSE);
   symSet (12)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet (12)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet (12)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, others => FALSE);
   symSet (13)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet (13)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE);
   symSet (13)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, others => FALSE);
   symSet (14)(0) := Sets.BITSET'(6 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet (14)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet (14)(2) := Sets.BITSET'(others => FALSE);
   symSet (15)(0) := Sets.BITSET'(1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 15 => TRUE, others => FALSE);
   symSet (15)(1) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, 15 => TRUE, others => FALSE);
   symSet (15)(2) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 3 => TRUE, 4 => TRUE, 5 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 9 => TRUE, others => FALSE);
   symSet (16)(0) := Sets.BITSET'(10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet (16)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet (16)(2) := Sets.BITSET'(others => FALSE);
   symSet (17)(0) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 6 => TRUE, 7 => TRUE, 8 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet (17)(1) := Sets.BITSET'(2 => TRUE, 7 => TRUE, 9 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 15 => TRUE, others => FALSE);
   symSet (17)(2) := Sets.BITSET'(1 => TRUE, 7 => TRUE, others => FALSE);
   symSet (18)(0) := Sets.BITSET'(0 => TRUE, 1 => TRUE, 2 => TRUE, 6 => TRUE, 7 => TRUE, 9 => TRUE, 10 => TRUE, 11 => TRUE, 12 => TRUE, 13 => TRUE, 14 => TRUE, others => FALSE);
   symSet (18)(1) := Sets.BITSET'(2 => TRUE, others => FALSE);
   symSet (18)(2) := Sets.BITSET'(7 => TRUE, others => FALSE);

end CRP;





