File : par-util.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                             P A R . U T I L                              --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1992-2013, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
  17 -- for  more details.  You should have  received  a copy of the GNU General --
  18 -- Public License  distributed with GNAT; see file COPYING3.  If not, go to --
  19 -- http://www.gnu.org/licenses for a complete copy of the license.          --
  20 --                                                                          --
  21 -- GNAT was originally developed  by the GNAT team at  New York University. --
  22 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  23 --                                                                          --
  24 ------------------------------------------------------------------------------
  25 
  26 with Csets;    use Csets;
  27 with Namet.Sp; use Namet.Sp;
  28 with Stylesw;  use Stylesw;
  29 with Uintp;    use Uintp;
  30 with Warnsw;   use Warnsw;
  31 
  32 with GNAT.Spelling_Checker; use GNAT.Spelling_Checker;
  33 
  34 separate (Par)
  35 package body Util is
  36 
  37    ---------------------
  38    -- Bad_Spelling_Of --
  39    ---------------------
  40 
  41    function Bad_Spelling_Of (T : Token_Type) return Boolean is
  42       Tname : constant String := Token_Type'Image (T);
  43       --  Characters of token name
  44 
  45       S : String (1 .. Tname'Last - 4);
  46       --  Characters of token name folded to lower case, omitting TOK_ at start
  47 
  48       M1 : String (1 .. 42) := "incorrect spelling of keyword ************";
  49       M2 : String (1 .. 44) := "illegal abbreviation of keyword ************";
  50       --  Buffers used to construct error message
  51 
  52       P1 : constant := 30;
  53       P2 : constant := 32;
  54       --  Starting subscripts in M1, M2 for keyword name
  55 
  56       SL : constant Natural := S'Length;
  57       --  Length of expected token name excluding TOK_ at start
  58 
  59    begin
  60       if Token /= Tok_Identifier then
  61          return False;
  62       end if;
  63 
  64       for J in S'Range loop
  65          S (J) := Fold_Lower (Tname (J + 4));
  66       end loop;
  67 
  68       Get_Name_String (Token_Name);
  69 
  70       --  A special check for case of PROGRAM used for PROCEDURE
  71 
  72       if T = Tok_Procedure
  73         and then Name_Len = 7
  74         and then Name_Buffer (1 .. 7) = "program"
  75       then
  76          Error_Msg_SC -- CODEFIX
  77            ("PROCEDURE expected");
  78          Token := T;
  79          return True;
  80 
  81       --  A special check for an illegal abbreviation
  82 
  83       elsif Name_Len < S'Length
  84         and then Name_Len >= 4
  85         and then Name_Buffer (1 .. Name_Len) = S (1 .. Name_Len)
  86       then
  87          for J in 1 .. S'Last loop
  88             M2 (P2 + J - 1) := Fold_Upper (S (J));
  89          end loop;
  90 
  91          Error_Msg_SC (M2 (1 .. P2 - 1 + S'Last));
  92          Token := T;
  93          return True;
  94       end if;
  95 
  96       --  Now we go into the full circuit to check for a misspelling
  97 
  98       --  Never consider something a misspelling if either the actual or
  99       --  expected string is less than 3 characters (before this check we
 100       --  used to consider i to be a misspelled if in some cases).
 101 
 102       if SL < 3 or else Name_Len < 3 then
 103          return False;
 104 
 105       --  Special case: prefix matches, i.e. the leading characters of the
 106       --  token that we have exactly match the required keyword. If there
 107       --  are at least two characters left over, assume that we have a case
 108       --  of two keywords joined together which should not be joined.
 109 
 110       elsif Name_Len > SL + 1
 111         and then S = Name_Buffer (1 .. SL)
 112       then
 113          Scan_Ptr := Token_Ptr + S'Length;
 114          Error_Msg_S ("|missing space");
 115          Token := T;
 116          return True;
 117       end if;
 118 
 119       if Is_Bad_Spelling_Of (Name_Buffer (1 .. Name_Len), S) then
 120          for J in 1 .. S'Last loop
 121             M1 (P1 + J - 1) := Fold_Upper (S (J));
 122          end loop;
 123 
 124          Error_Msg_SC -- CODFIX
 125            (M1 (1 .. P1 - 1 + S'Last));
 126          Token := T;
 127          return True;
 128 
 129       else
 130          return False;
 131       end if;
 132    end Bad_Spelling_Of;
 133 
 134    ----------------------
 135    -- Check_95_Keyword --
 136    ----------------------
 137 
 138    --  On entry, the caller has checked that current token is an identifier
 139    --  whose name matches the name of the 95 keyword New_Tok.
 140 
 141    procedure Check_95_Keyword (Token_95, Next : Token_Type) is
 142       Scan_State : Saved_Scan_State;
 143 
 144    begin
 145       Save_Scan_State (Scan_State); -- at identifier/keyword
 146       Scan; -- past identifier/keyword
 147 
 148       if Token = Next then
 149          Restore_Scan_State (Scan_State); -- to identifier
 150          Error_Msg_Name_1 := Token_Name;
 151          Error_Msg_SC ("(Ada 83) keyword* cannot be used!");
 152          Token := Token_95;
 153       else
 154          Restore_Scan_State (Scan_State); -- to identifier
 155       end if;
 156    end Check_95_Keyword;
 157 
 158    ----------------------
 159    -- Check_Bad_Layout --
 160    ----------------------
 161 
 162    procedure Check_Bad_Layout is
 163    begin
 164       if RM_Column_Check and then Token_Is_At_Start_Of_Line
 165         and then Start_Column <= Scope.Table (Scope.Last).Ecol
 166       then
 167          Error_Msg_BC -- CODEFIX
 168            ("(style) incorrect layout");
 169       end if;
 170    end Check_Bad_Layout;
 171 
 172    --------------------------
 173    -- Check_Future_Keyword --
 174    --------------------------
 175 
 176    procedure Check_Future_Keyword is
 177    begin
 178       --  Ada 2005 (AI-284): Compiling in Ada 95 mode we warn that INTERFACE,
 179       --  OVERRIDING, and SYNCHRONIZED are new reserved words.
 180 
 181       if Ada_Version = Ada_95
 182         and then Warn_On_Ada_2005_Compatibility
 183       then
 184          if Nam_In (Token_Name, Name_Overriding, Name_Synchronized)
 185            or else (Token_Name = Name_Interface
 186                      and then Prev_Token /= Tok_Pragma)
 187          then
 188             Error_Msg_N ("& is a reserved word in Ada 2005?y?", Token_Node);
 189          end if;
 190       end if;
 191 
 192       --  Similarly, warn about Ada 2012 reserved words
 193 
 194       if Ada_Version in Ada_95 .. Ada_2005
 195         and then Warn_On_Ada_2012_Compatibility
 196       then
 197          if Token_Name = Name_Some then
 198             Error_Msg_N ("& is a reserved word in Ada 2012?y?", Token_Node);
 199          end if;
 200       end if;
 201 
 202       --  Note: we deliberately do not emit these warnings when operating in
 203       --  Ada 83 mode because in that case we assume the user is building
 204       --  legacy code anyway and is not interested in updating Ada versions.
 205 
 206    end Check_Future_Keyword;
 207 
 208    --------------------------
 209    -- Check_Misspelling_Of --
 210    --------------------------
 211 
 212    procedure Check_Misspelling_Of (T : Token_Type) is
 213    begin
 214       if Bad_Spelling_Of (T) then
 215          null;
 216       end if;
 217    end Check_Misspelling_Of;
 218 
 219    -----------------------------
 220    -- Check_Simple_Expression --
 221    -----------------------------
 222 
 223    procedure Check_Simple_Expression (E : Node_Id) is
 224    begin
 225       if Expr_Form = EF_Non_Simple then
 226          Error_Msg_N ("this expression must be parenthesized", E);
 227       end if;
 228    end Check_Simple_Expression;
 229 
 230    ---------------------------------------
 231    -- Check_Simple_Expression_In_Ada_83 --
 232    ---------------------------------------
 233 
 234    procedure Check_Simple_Expression_In_Ada_83 (E : Node_Id) is
 235    begin
 236       if Expr_Form = EF_Non_Simple then
 237          if Ada_Version = Ada_83 then
 238             Error_Msg_N ("(Ada 83) this expression must be parenthesized!", E);
 239          end if;
 240       end if;
 241    end Check_Simple_Expression_In_Ada_83;
 242 
 243    ------------------------
 244    -- Check_Subtype_Mark --
 245    ------------------------
 246 
 247    function Check_Subtype_Mark (Mark : Node_Id) return Node_Id is
 248    begin
 249       if Nkind (Mark) = N_Identifier
 250         or else Nkind (Mark) = N_Selected_Component
 251         or else (Nkind (Mark) = N_Attribute_Reference
 252                   and then Is_Type_Attribute_Name (Attribute_Name (Mark)))
 253         or else Mark = Error
 254       then
 255          return Mark;
 256       else
 257          Error_Msg ("subtype mark expected", Sloc (Mark));
 258          return Error;
 259       end if;
 260    end Check_Subtype_Mark;
 261 
 262    -------------------
 263    -- Comma_Present --
 264    -------------------
 265 
 266    function Comma_Present return Boolean is
 267       Scan_State  : Saved_Scan_State;
 268       Paren_Count : Nat;
 269 
 270    begin
 271       --  First check, if a comma is present, then a comma is present
 272 
 273       if Token = Tok_Comma then
 274          T_Comma;
 275          return True;
 276 
 277       --  If we have a right paren, then that is taken as ending the list
 278       --  i.e. no comma is present.
 279 
 280       elsif Token = Tok_Right_Paren then
 281          return False;
 282 
 283       --  If pragmas, then get rid of them and make a recursive call
 284       --  to process what follows these pragmas.
 285 
 286       elsif Token = Tok_Pragma then
 287          P_Pragmas_Misplaced;
 288          return Comma_Present;
 289 
 290       --  At this stage we have an error, and the goal is to decide on whether
 291       --  or not we should diagnose an error and report a (non-existent)
 292       --  comma as being present, or simply to report no comma is present
 293 
 294       --  If we are a semicolon, then the question is whether we have a missing
 295       --  right paren, or whether the semicolon should have been a comma. To
 296       --  guess the right answer, we scan ahead keeping track of the paren
 297       --  level, looking for a clue that helps us make the right decision.
 298 
 299       --  This approach is highly accurate in the single error case, and does
 300       --  not make bad mistakes in the multiple error case (indeed we can't
 301       --  really make a very bad decision at this point in any case).
 302 
 303       elsif Token = Tok_Semicolon then
 304          Save_Scan_State (Scan_State);
 305          Scan; -- past semicolon
 306 
 307          --  Check for being followed by identifier => which almost certainly
 308          --  means we are still in a parameter list and the comma should have
 309          --  been a semicolon (such a sequence could not follow a semicolon)
 310 
 311          if Token = Tok_Identifier then
 312             Scan;
 313 
 314             if Token = Tok_Arrow then
 315                goto Assume_Comma;
 316             end if;
 317          end if;
 318 
 319          --  If that test didn't work, loop ahead looking for a comma or
 320          --  semicolon at the same parenthesis level. Always remember that
 321          --  we can't go badly wrong in an error situation like this.
 322 
 323          Paren_Count := 0;
 324 
 325          --  Here is the look ahead loop, Paren_Count tells us whether the
 326          --  token we are looking at is at the same paren level as the
 327          --  suspicious semicolon that we are trying to figure out.
 328 
 329          loop
 330 
 331             --  If we hit another semicolon or an end of file, and we have
 332             --  not seen a right paren or another comma on the way, then
 333             --  probably the semicolon did end the list. Indeed that is
 334             --  certainly the only single error correction possible here.
 335 
 336             if Token = Tok_Semicolon or else Token = Tok_EOF then
 337                Restore_Scan_State (Scan_State);
 338                return False;
 339 
 340             --  A comma at the same paren level as the semicolon is a strong
 341             --  indicator that the semicolon should have been a comma, indeed
 342             --  again this is the only possible single error correction.
 343 
 344             elsif Token = Tok_Comma then
 345                exit when Paren_Count = 0;
 346 
 347             --  A left paren just bumps the paren count
 348 
 349             elsif Token = Tok_Left_Paren then
 350                Paren_Count := Paren_Count + 1;
 351 
 352             --  A right paren that is at the same paren level as the semicolon
 353             --  also means that the only possible single error correction is
 354             --  to assume that the semicolon should have been a comma. If we
 355             --  are not at the same paren level, then adjust the paren level.
 356 
 357             elsif Token = Tok_Right_Paren then
 358                exit when Paren_Count = 0;
 359                Paren_Count := Paren_Count - 1;
 360             end if;
 361 
 362             --  Keep going, we haven't made a decision yet
 363 
 364             Scan;
 365          end loop;
 366 
 367          --  If we fall through the loop, it means that we found a terminating
 368          --  right paren or another comma. In either case it is reasonable to
 369          --  assume that the semicolon was really intended to be a comma. Also
 370          --  come here for the identifier arrow case.
 371 
 372          <<Assume_Comma>>
 373             Restore_Scan_State (Scan_State);
 374             Error_Msg_SC -- CODEFIX
 375               ("|"";"" should be "",""");
 376             Scan; -- past the semicolon
 377             return True;
 378 
 379       --  If we are not at semicolon or a right paren, then we base the
 380       --  decision on whether or not the next token can be part of an
 381       --  expression. If not, then decide that no comma is present (the
 382       --  caller will eventually generate a missing right parent message)
 383 
 384       elsif Token in Token_Class_Eterm then
 385          return False;
 386 
 387       --  Otherwise we assume a comma is present, even if none is present,
 388       --  since the next token must be part of an expression, so if we were
 389       --  at the end of the list, then there is more than one error present.
 390 
 391       else
 392          T_Comma; -- to give error
 393          return True;
 394       end if;
 395    end Comma_Present;
 396 
 397    -----------------------
 398    -- Discard_Junk_List --
 399    -----------------------
 400 
 401    procedure Discard_Junk_List (L : List_Id) is
 402       pragma Warnings (Off, L);
 403    begin
 404       null;
 405    end Discard_Junk_List;
 406 
 407    -----------------------
 408    -- Discard_Junk_Node --
 409    -----------------------
 410 
 411    procedure Discard_Junk_Node (N : Node_Id) is
 412       pragma Warnings (Off, N);
 413    begin
 414       null;
 415    end Discard_Junk_Node;
 416 
 417    ------------
 418    -- Ignore --
 419    ------------
 420 
 421    procedure Ignore (T : Token_Type) is
 422    begin
 423       while Token = T loop
 424          if T = Tok_Comma then
 425             Error_Msg_SC -- CODEFIX
 426               ("|extra "","" ignored");
 427 
 428          elsif T = Tok_Left_Paren then
 429             Error_Msg_SC -- CODEFIX
 430               ("|extra ""("" ignored");
 431 
 432          --  Note: the following error used to be labeled as a non-serious
 433          --  error like the other similar messages here (with a | at the start
 434          --  of the message). But this caused some annoying cascaded errors
 435          --  that were confusing, as shown by this example:
 436 
 437          --          A : array (1 .. 9) of Integer :=
 438          --            ((1 .. 2) => 0,
 439          --             1  2   3
 440          --       >>> positional aggregate cannot have one component
 441          --       >>> named association cannot follow positional association
 442          --       >>> extra ")" ignored
 443 
 444          --  So we decided to label it as serious after all
 445 
 446          elsif T = Tok_Right_Paren then
 447             Error_Msg_SC -- CODEFIX
 448               ("extra "")"" ignored");
 449 
 450          elsif T = Tok_Semicolon then
 451             Error_Msg_SC -- CODEFIX
 452               ("|extra "";"" ignored");
 453 
 454          elsif T = Tok_Colon then
 455             Error_Msg_SC -- CODEFIX
 456               ("|extra "":"" ignored");
 457 
 458          else
 459             declare
 460                Tname : constant String := Token_Type'Image (Token);
 461             begin
 462                Error_Msg_SC ("|extra " & Tname (5 .. Tname'Last) & "ignored");
 463             end;
 464          end if;
 465 
 466          Scan; -- Scan past ignored token
 467       end loop;
 468    end Ignore;
 469 
 470    ----------------------------
 471    -- Is_Reserved_Identifier --
 472    ----------------------------
 473 
 474    function Is_Reserved_Identifier (C : Id_Check := None) return Boolean is
 475    begin
 476       if not Is_Reserved_Keyword (Token) then
 477          return False;
 478 
 479       else
 480          declare
 481             Ident_Casing : constant Casing_Type :=
 482                              Identifier_Casing (Current_Source_File);
 483             Key_Casing   : constant Casing_Type :=
 484                              Keyword_Casing (Current_Source_File);
 485 
 486          begin
 487             --  If the casing of identifiers and keywords is different in
 488             --  this source file, and the casing of this token matches the
 489             --  keyword casing, then we return False, since it is pretty
 490             --  clearly intended to be a keyword.
 491 
 492             if Ident_Casing = Unknown
 493               or else Key_Casing = Unknown
 494               or else Ident_Casing = Key_Casing
 495               or else Determine_Token_Casing /= Key_Casing
 496             then
 497                return True;
 498 
 499             --  Here we have a keyword written clearly with keyword casing.
 500             --  In default mode, we would not be willing to consider this as
 501             --  a reserved identifier, but if C is set, we may still accept it
 502 
 503             elsif C /= None then
 504                declare
 505                   Scan_State  : Saved_Scan_State;
 506                   OK_Next_Tok : Boolean;
 507 
 508                begin
 509                   Save_Scan_State (Scan_State);
 510                   Scan;
 511 
 512                   if Token_Is_At_Start_Of_Line then
 513                      return False;
 514                   end if;
 515 
 516                   case C is
 517                      when None =>
 518                         raise Program_Error;
 519 
 520                      when C_Comma_Right_Paren =>
 521                         OK_Next_Tok :=
 522                           Token = Tok_Comma or else Token = Tok_Right_Paren;
 523 
 524                      when C_Comma_Colon =>
 525                         OK_Next_Tok :=
 526                           Token = Tok_Comma or else Token = Tok_Colon;
 527 
 528                      when C_Do =>
 529                         OK_Next_Tok :=
 530                           Token = Tok_Do;
 531 
 532                      when C_Dot =>
 533                         OK_Next_Tok :=
 534                           Token = Tok_Dot;
 535 
 536                      when C_Greater_Greater =>
 537                         OK_Next_Tok :=
 538                           Token = Tok_Greater_Greater;
 539 
 540                      when C_In =>
 541                         OK_Next_Tok :=
 542                           Token = Tok_In;
 543 
 544                      when C_Is =>
 545                         OK_Next_Tok :=
 546                           Token = Tok_Is;
 547 
 548                      when C_Left_Paren_Semicolon =>
 549                         OK_Next_Tok :=
 550                           Token = Tok_Left_Paren or else Token = Tok_Semicolon;
 551 
 552                      when C_Use =>
 553                         OK_Next_Tok :=
 554                           Token = Tok_Use;
 555 
 556                      when C_Vertical_Bar_Arrow =>
 557                         OK_Next_Tok :=
 558                           Token = Tok_Vertical_Bar or else Token = Tok_Arrow;
 559                   end case;
 560 
 561                   Restore_Scan_State (Scan_State);
 562 
 563                   if OK_Next_Tok then
 564                      return True;
 565                   end if;
 566                end;
 567             end if;
 568          end;
 569       end if;
 570 
 571       --  If we fall through it is not a reserved identifier
 572 
 573       return False;
 574    end Is_Reserved_Identifier;
 575 
 576    ----------------------
 577    -- Merge_Identifier --
 578    ----------------------
 579 
 580    procedure Merge_Identifier (Prev : Node_Id; Nxt : Token_Type) is
 581    begin
 582       if Token /= Tok_Identifier then
 583          return;
 584       end if;
 585 
 586       declare
 587          S : Saved_Scan_State;
 588          T : Token_Type;
 589 
 590       begin
 591          Save_Scan_State (S);
 592          Scan;
 593          T := Token;
 594          Restore_Scan_State (S);
 595 
 596          if T /= Nxt then
 597             return;
 598          end if;
 599       end;
 600 
 601       --  Check exactly one space between identifiers
 602 
 603       if Source (Token_Ptr - 1) /= ' '
 604         or else Int (Token_Ptr) /=
 605                   Int (Prev_Token_Ptr) + Length_Of_Name (Chars (Prev)) + 1
 606       then
 607          return;
 608       end if;
 609 
 610       --  Do the merge
 611 
 612       Get_Name_String (Chars (Token_Node));
 613 
 614       declare
 615          Buf : constant String (1 .. Name_Len) :=
 616                  Name_Buffer (1 .. Name_Len);
 617 
 618       begin
 619          Get_Name_String (Chars (Prev));
 620          Add_Char_To_Name_Buffer ('_');
 621          Add_Str_To_Name_Buffer (Buf);
 622          Set_Chars (Prev, Name_Find);
 623       end;
 624 
 625       Error_Msg_Node_1 := Prev;
 626       Error_Msg_SC ("unexpected identifier, possibly & was meant here");
 627       Scan;
 628    end Merge_Identifier;
 629 
 630    -------------------
 631    -- Next_Token_Is --
 632    -------------------
 633 
 634    function Next_Token_Is (Tok : Token_Type) return Boolean is
 635       Scan_State : Saved_Scan_State;
 636       Result     : Boolean;
 637    begin
 638       Save_Scan_State (Scan_State);
 639       Scan;
 640       Result := (Token = Tok);
 641       Restore_Scan_State (Scan_State);
 642       return Result;
 643    end Next_Token_Is;
 644 
 645    -------------------
 646    -- No_Constraint --
 647    -------------------
 648 
 649    procedure No_Constraint is
 650    begin
 651       --  If we have a token that could start a constraint on the same line
 652       --  then cnsider this an illegal constraint. It seems unlikely it could
 653       --  be anything else if it is on the same line.
 654 
 655       if Token in Token_Class_Consk then
 656          Error_Msg_SC ("constraint not allowed here");
 657          Discard_Junk_Node (P_Constraint_Opt);
 658       end if;
 659    end No_Constraint;
 660 
 661    ---------------------
 662    -- Pop_Scope_Stack --
 663    ---------------------
 664 
 665    procedure Pop_Scope_Stack is
 666    begin
 667       pragma Assert (Scope.Last > 0);
 668       Scope.Decrement_Last;
 669 
 670       if Debug_Flag_P then
 671          Error_Msg_Uint_1 := UI_From_Int (Scope.Last);
 672          Error_Msg_SC ("decrement scope stack ptr, new value = ^!");
 673       end if;
 674    end Pop_Scope_Stack;
 675 
 676    ----------------------
 677    -- Push_Scope_Stack --
 678    ----------------------
 679 
 680    procedure Push_Scope_Stack is
 681    begin
 682       Scope.Increment_Last;
 683 
 684       if Style_Check_Max_Nesting_Level
 685         and then Scope.Last = Style_Max_Nesting_Level + 1
 686       then
 687          Error_Msg
 688            ("(style) maximum nesting level exceeded",
 689             First_Non_Blank_Location);
 690       end if;
 691 
 692       Scope.Table (Scope.Last).Junk := False;
 693       Scope.Table (Scope.Last).Node := Empty;
 694 
 695       if Debug_Flag_P then
 696          Error_Msg_Uint_1 := UI_From_Int (Scope.Last);
 697          Error_Msg_SC ("increment scope stack ptr, new value = ^!");
 698       end if;
 699    end Push_Scope_Stack;
 700 
 701    ----------------------
 702    -- Separate_Present --
 703    ----------------------
 704 
 705    function Separate_Present return Boolean is
 706       Scan_State : Saved_Scan_State;
 707 
 708    begin
 709       if Token = Tok_Separate then
 710          return True;
 711 
 712       elsif Token /= Tok_Identifier then
 713          return False;
 714 
 715       else
 716          Save_Scan_State (Scan_State);
 717          Scan; -- past identifier
 718 
 719          if Token = Tok_Semicolon then
 720             Restore_Scan_State (Scan_State);
 721             return Bad_Spelling_Of (Tok_Separate);
 722 
 723          else
 724             Restore_Scan_State (Scan_State);
 725             return False;
 726          end if;
 727       end if;
 728    end Separate_Present;
 729 
 730    --------------------------
 731    -- Signal_Bad_Attribute --
 732    --------------------------
 733 
 734    procedure Signal_Bad_Attribute is
 735    begin
 736       Bad_Attribute (Token_Node, Token_Name, Warn => False);
 737    end Signal_Bad_Attribute;
 738 
 739    -----------------------------
 740    -- Token_Is_At_End_Of_Line --
 741    -----------------------------
 742 
 743    function Token_Is_At_End_Of_Line return Boolean is
 744       S : Source_Ptr;
 745 
 746    begin
 747       --  Skip past blanks and horizontal tabs
 748 
 749       S := Scan_Ptr;
 750       while Source (S) = ' ' or else Source (S) = ASCII.HT loop
 751          S := S + 1;
 752       end loop;
 753 
 754       --  We are at end of line if at a control character (CR/LF/VT/FF/EOF)
 755       --  or if we are at the start of an end of line comment sequence.
 756 
 757       return Source (S) < ' '
 758         or else (Source (S) = '-' and then Source (S + 1) = '-');
 759    end Token_Is_At_End_Of_Line;
 760 
 761    -------------------------------
 762    -- Token_Is_At_Start_Of_Line --
 763    -------------------------------
 764 
 765    function Token_Is_At_Start_Of_Line return Boolean is
 766    begin
 767       return (Token_Ptr = First_Non_Blank_Location or else Token = Tok_EOF);
 768    end Token_Is_At_Start_Of_Line;
 769 
 770    -----------------------------------
 771    -- Warn_If_Standard_Redefinition --
 772    -----------------------------------
 773 
 774    procedure Warn_If_Standard_Redefinition (N : Node_Id) is
 775    begin
 776       if Warn_On_Standard_Redefinition then
 777          declare
 778             C : constant Entity_Id := Current_Entity (N);
 779          begin
 780             if Present (C) and then Sloc (C) = Standard_Location then
 781                Error_Msg_N ("redefinition of entity& in Standard?K?", N);
 782             end if;
 783          end;
 784       end if;
 785    end Warn_If_Standard_Redefinition;
 786 
 787 end Util;