hppa: Fix LO_SUM DLTIND14R address support in PRINT_OPERAND_ADDRESS
[official-gcc.git] / gcc / ada / par-tchk.adb
blobf5b6267f31e7637ba84462912c9f2b94184822c3
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- P A R . T C H K --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1992-2024, 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 ------------------------------------------------------------------------------
26 -- Token scan routines
28 -- Error recovery: none of the T_xxx or TF_xxx routines raise Error_Resync
30 separate (Par)
31 package body Tchk is
33 type Position is (SC, BC, AP);
34 -- Specify position of error message (see Error_Msg_SC/BC/AP)
36 -----------------------
37 -- Local Subprograms --
38 -----------------------
40 procedure Check_Token (T : Token_Type; P : Position);
41 pragma Inline (Check_Token);
42 -- Called by T_xx routines to check for reserved keyword token. P is the
43 -- position of the error message if the token is missing (see Wrong_Token)
45 procedure Wrong_Token (T : Token_Type; P : Position);
46 -- Called when scanning a reserved keyword when the keyword is not present.
47 -- T is the token type for the keyword, and P indicates the position to be
48 -- used to place a message relative to the current token if the keyword is
49 -- not located nearby.
51 -----------------
52 -- Check_Token --
53 -----------------
55 procedure Check_Token (T : Token_Type; P : Position) is
56 begin
57 if Token = T then
58 Scan;
59 return;
60 else
61 Wrong_Token (T, P);
62 end if;
63 end Check_Token;
65 -------------
66 -- T_Abort --
67 -------------
69 procedure T_Abort is
70 begin
71 Check_Token (Tok_Abort, SC);
72 end T_Abort;
74 -------------
75 -- T_Arrow --
76 -------------
78 procedure T_Arrow is
79 begin
80 if Token = Tok_Arrow then
81 Scan;
83 -- A little recovery helper, accept then in place of =>
85 elsif Token = Tok_Then then
86 Error_Msg_BC -- CODEFIX
87 ("|THEN should be ""='>""");
88 Scan; -- past THEN used in place of =>
90 elsif Token = Tok_Colon_Equal then
91 Error_Msg_SC -- CODEFIX
92 ("|"":="" should be ""='>""");
93 Scan; -- past := used in place of =>
95 else
96 Error_Msg_AP -- CODEFIX
97 ("missing ""='>""");
98 end if;
99 end T_Arrow;
101 ----------
102 -- T_At --
103 ----------
105 procedure T_At is
106 begin
107 Check_Token (Tok_At, SC);
108 end T_At;
110 ------------
111 -- T_Body --
112 ------------
114 procedure T_Body is
115 begin
116 Check_Token (Tok_Body, BC);
117 end T_Body;
119 -----------
120 -- T_Box --
121 -----------
123 procedure T_Box is
124 begin
125 if Token = Tok_Box then
126 Scan;
127 else
128 Error_Msg_AP -- CODEFIX
129 ("missing ""'<'>""");
130 end if;
131 end T_Box;
133 -------------
134 -- T_Colon --
135 -------------
137 procedure T_Colon is
138 begin
139 if Token = Tok_Colon then
140 Scan;
141 else
142 Error_Msg_AP -- CODEFIX
143 ("missing "":""");
144 end if;
145 end T_Colon;
147 -------------------
148 -- T_Colon_Equal --
149 -------------------
151 procedure T_Colon_Equal is
152 begin
153 if Token = Tok_Colon_Equal then
154 Scan;
156 elsif Token = Tok_Equal then
157 Error_Msg_SC -- CODEFIX
158 ("|""="" should be "":=""");
159 Scan;
161 elsif Token = Tok_Colon then
162 Error_Msg_SC -- CODEFIX
163 ("|"":"" should be "":=""");
164 Scan;
166 elsif Token = Tok_Is then
167 Error_Msg_SC -- CODEFIX
168 ("|IS should be "":=""");
169 Scan;
171 else
172 Error_Msg_AP -- CODEFIX
173 ("missing "":=""");
174 end if;
175 end T_Colon_Equal;
177 -------------
178 -- T_Comma --
179 -------------
181 procedure T_Comma is
182 begin
183 if Token = Tok_Comma then
184 Scan;
186 else
187 if Token = Tok_Pragma then
188 P_Pragmas_Misplaced;
189 end if;
191 if Token = Tok_Comma then
192 Scan;
193 else
194 Error_Msg_AP -- CODEFIX
195 ("missing "",""");
196 end if;
197 end if;
199 if Token = Tok_Pragma then
200 P_Pragmas_Misplaced;
201 end if;
202 end T_Comma;
204 ---------------
205 -- T_Dot_Dot --
206 ---------------
208 procedure T_Dot_Dot is
209 begin
210 if Token = Tok_Dot_Dot then
211 Scan;
212 else
213 Error_Msg_AP -- CODEFIX
214 ("missing ""..""");
215 end if;
216 end T_Dot_Dot;
218 -----------
219 -- T_For --
220 -----------
222 procedure T_For is
223 begin
224 Check_Token (Tok_For, AP);
225 end T_For;
227 -----------------------
228 -- T_Greater_Greater --
229 -----------------------
231 procedure T_Greater_Greater is
232 begin
233 if Token = Tok_Greater_Greater then
234 Scan;
235 else
236 Error_Msg_AP -- CODEFIX
237 ("missing ""'>'>""");
238 end if;
239 end T_Greater_Greater;
241 ------------------
242 -- T_Identifier --
243 ------------------
245 procedure T_Identifier is
246 begin
247 if Token = Tok_Identifier then
248 Scan;
249 elsif Token in Token_Class_Literal then
250 Error_Msg_SC ("identifier expected");
251 Scan;
252 else
253 Error_Msg_AP ("identifier expected");
254 end if;
255 end T_Identifier;
257 ----------
258 -- T_In --
259 ----------
261 procedure T_In is
262 begin
263 Check_Token (Tok_In, AP);
264 end T_In;
266 ----------
267 -- T_Is --
268 ----------
270 procedure T_Is is
271 begin
272 Ignore (Tok_Semicolon);
274 -- If we have IS scan past it
276 if Token = Tok_Is then
277 Scan;
279 -- And ignore any following semicolons
281 Ignore (Tok_Semicolon);
283 -- Allow OF, => or = to substitute for IS with complaint
285 elsif Token = Tok_Arrow then
286 Error_Msg_SC -- CODEFIX
287 ("|""=>"" should be IS");
288 Scan; -- past =>
290 elsif Token = Tok_Of then
291 Error_Msg_SC -- CODEFIX
292 ("|OF should be IS");
293 Scan; -- past OF
295 elsif Token = Tok_Equal then
296 Error_Msg_SC -- CODEFIX
297 ("|""="" should be IS");
298 Scan; -- past =
300 else
301 Wrong_Token (Tok_Is, AP);
302 end if;
304 -- Ignore extra IS keywords
306 while Token = Tok_Is loop
307 Error_Msg_SC -- CODEFIX
308 ("|extra IS ignored");
309 Scan;
310 end loop;
311 end T_Is;
313 ------------------
314 -- T_Left_Paren --
315 ------------------
317 procedure T_Left_Paren is
318 begin
319 if Token = Tok_Left_Paren then
320 Scan;
321 else
322 Error_Msg_AP -- CODEFIX
323 ("missing ""(""");
324 end if;
325 end T_Left_Paren;
327 ------------
328 -- T_Loop --
329 ------------
331 procedure T_Loop is
332 begin
333 if Token = Tok_Do then
334 Error_Msg_SC -- CODEFIX
335 ("LOOP expected");
336 Scan;
337 else
338 Check_Token (Tok_Loop, AP);
339 end if;
340 end T_Loop;
342 -----------
343 -- T_Mod --
344 -----------
346 procedure T_Mod is
347 begin
348 Check_Token (Tok_Mod, AP);
349 end T_Mod;
351 -----------
352 -- T_New --
353 -----------
355 procedure T_New is
356 begin
357 Check_Token (Tok_New, AP);
358 end T_New;
360 ----------
361 -- T_Of --
362 ----------
364 procedure T_Of is
365 begin
366 Check_Token (Tok_Of, AP);
367 end T_Of;
369 ----------
370 -- T_Or --
371 ----------
373 procedure T_Or is
374 begin
375 Check_Token (Tok_Or, AP);
376 end T_Or;
378 ---------------
379 -- T_Private --
380 ---------------
382 procedure T_Private is
383 begin
384 Check_Token (Tok_Private, SC);
385 end T_Private;
387 -------------
388 -- T_Range --
389 -------------
391 procedure T_Range is
392 begin
393 Check_Token (Tok_Range, AP);
394 end T_Range;
396 --------------
397 -- T_Record --
398 --------------
400 procedure T_Record is
401 begin
402 Check_Token (Tok_Record, AP);
403 end T_Record;
405 ---------------------------
406 -- T_Right_Curly_Bracket --
407 ---------------------------
409 procedure T_Right_Curly_Bracket is
410 begin
411 if Token = Tok_Right_Curly_Bracket then
412 Scan;
413 else
414 Error_Msg_AP
415 ("|missing ""'}'""");
416 end if;
417 end T_Right_Curly_Bracket;
419 ---------------------
420 -- T_Right_Bracket --
421 ---------------------
423 procedure T_Right_Bracket is
424 begin
425 if Token = Tok_Right_Bracket then
426 Scan;
427 else
428 Error_Msg_AP -- CODEFIX
429 ("|missing ""']'""");
430 end if;
431 end T_Right_Bracket;
433 -------------------
434 -- T_Right_Paren --
435 -------------------
437 procedure T_Right_Paren is
438 begin
439 if Token = Tok_Right_Paren then
440 Scan;
441 else
442 Error_Msg_AP -- CODEFIX
443 ("|missing "")""");
444 end if;
445 end T_Right_Paren;
447 -----------------
448 -- T_Semicolon --
449 -----------------
451 procedure T_Semicolon is
452 begin
453 if Token = Tok_Semicolon then
454 Scan;
456 if Token = Tok_Semicolon then
457 Error_Msg_SC -- CODEFIX
458 ("|extra "";"" ignored");
459 Scan;
460 end if;
462 return;
464 elsif Token = Tok_Colon then
465 Error_Msg_SC -- CODEFIX
466 ("|"":"" should be "";""");
467 Scan;
468 return;
470 elsif Token = Tok_Comma then
471 Error_Msg_SC -- CODEFIX
472 ("|"","" should be "";""");
473 Scan;
474 return;
476 elsif Token = Tok_Dot then
477 Error_Msg_SC -- CODEFIX
478 ("|""."" should be "";""");
479 Scan;
480 return;
482 -- An interesting little case. If the previous token is a semicolon,
483 -- then there is no way that we can legitimately need another semicolon.
484 -- This could only arise in an situation where an error has already been
485 -- signalled. By simply ignoring the request for a semicolon in this
486 -- case, we avoid some spurious missing semicolon messages.
488 elsif Prev_Token = Tok_Semicolon then
489 return;
491 -- If the current token is | then this is a reasonable place to suggest
492 -- the possibility of a "C" confusion.
494 elsif Token = Tok_Vertical_Bar then
495 Error_Msg_SC -- CODEFIX
496 ("unexpected occurrence of ""'|"", did you mean OR'?");
497 Resync_Past_Semicolon;
498 return;
500 -- Deal with pragma. If pragma is not at start of line, it is considered
501 -- misplaced otherwise we treat it as a normal missing semicolon case.
503 elsif Token = Tok_Pragma and then not Token_Is_At_Start_Of_Line then
504 P_Pragmas_Misplaced;
506 if Token = Tok_Semicolon then
507 Scan;
508 return;
509 end if;
510 end if;
512 -- If none of those tests return, we really have a missing semicolon
514 Error_Msg_AP -- CODEFIX
515 ("|missing "";""");
516 return;
517 end T_Semicolon;
519 ------------
520 -- T_Then --
521 ------------
523 procedure T_Then is
524 begin
525 Check_Token (Tok_Then, AP);
526 end T_Then;
528 ------------
529 -- T_Type --
530 ------------
532 procedure T_Type is
533 begin
534 Check_Token (Tok_Type, BC);
535 end T_Type;
537 -----------
538 -- T_Use --
539 -----------
541 procedure T_Use is
542 begin
543 Check_Token (Tok_Use, SC);
544 end T_Use;
546 ------------
547 -- T_When --
548 ------------
550 procedure T_When is
551 begin
552 Check_Token (Tok_When, SC);
553 end T_When;
555 ------------
556 -- T_With --
557 ------------
559 procedure T_With is
560 begin
561 Check_Token (Tok_With, BC);
562 end T_With;
564 --------------
565 -- TF_Arrow --
566 --------------
568 procedure TF_Arrow is
569 Scan_State : Saved_Scan_State;
571 begin
572 if Token = Tok_Arrow then
573 Scan; -- skip arrow and we are done
575 elsif Token = Tok_Colon_Equal then
576 T_Arrow; -- Let T_Arrow give the message
578 else
579 T_Arrow; -- give missing arrow message
580 Save_Scan_State (Scan_State); -- at start of junk tokens
582 loop
583 if Prev_Token_Ptr < Current_Line_Start
584 or else Token in Tok_Semicolon | Tok_EOF
585 then
586 Restore_Scan_State (Scan_State); -- to where we were
587 return;
588 end if;
590 Scan; -- continue search
592 if Token = Tok_Arrow then
593 Scan; -- past arrow
594 return;
595 end if;
596 end loop;
597 end if;
598 end TF_Arrow;
600 -----------
601 -- TF_Is --
602 -----------
604 procedure TF_Is is
605 Scan_State : Saved_Scan_State;
607 begin
608 if Token = Tok_Is then
609 T_Is; -- past IS and we are done
611 -- Allow OF or => or = in place of IS (with error message)
613 elsif Token in Tok_Of | Tok_Arrow | Tok_Equal then
614 T_Is; -- give missing IS message and skip bad token
616 else
617 T_Is; -- give missing IS message
618 Save_Scan_State (Scan_State); -- at start of junk tokens
620 loop
621 if Prev_Token_Ptr < Current_Line_Start
622 or else Token in Tok_Semicolon | Tok_EOF
623 then
624 Restore_Scan_State (Scan_State); -- to where we were
625 return;
626 end if;
628 Scan; -- continue search
630 if Token in Tok_Is | Tok_Of | Tok_Arrow then
631 Scan; -- past IS or OF or =>
632 return;
633 end if;
634 end loop;
635 end if;
636 end TF_Is;
638 -------------
639 -- TF_Loop --
640 -------------
642 procedure TF_Loop is
643 Scan_State : Saved_Scan_State;
645 begin
646 if Token = Tok_Loop then
647 Scan; -- past LOOP and we are done
649 -- Allow DO or THEN in place of LOOP
651 elsif Token in Tok_Then | Tok_Do then
652 T_Loop; -- give missing LOOP message
654 else
655 T_Loop; -- give missing LOOP message
656 Save_Scan_State (Scan_State); -- at start of junk tokens
658 loop
659 if Prev_Token_Ptr < Current_Line_Start
660 or else Token in Tok_Semicolon | Tok_EOF
661 then
662 Restore_Scan_State (Scan_State); -- to where we were
663 return;
664 end if;
666 Scan; -- continue search
668 if Token in Tok_Loop | Tok_Then then
669 Scan; -- past loop or then (message already generated)
670 return;
671 end if;
672 end loop;
673 end if;
674 end TF_Loop;
676 --------------
677 -- TF_Return--
678 --------------
680 procedure TF_Return is
681 Scan_State : Saved_Scan_State;
683 begin
684 if Token = Tok_Return then
685 Scan; -- skip RETURN and we are done
687 else
688 Error_Msg_SC -- CODEFIX
689 ("missing RETURN");
690 Save_Scan_State (Scan_State); -- at start of junk tokens
692 loop
693 if Prev_Token_Ptr < Current_Line_Start
694 or else Token in Tok_Semicolon | Tok_EOF
695 then
696 Restore_Scan_State (Scan_State); -- to where we were
697 return;
698 end if;
700 Scan; -- continue search
702 if Token = Tok_Return then
703 Scan; -- past RETURN
704 return;
705 end if;
706 end loop;
707 end if;
708 end TF_Return;
710 ------------------
711 -- TF_Semicolon --
712 ------------------
714 procedure TF_Semicolon is
715 Scan_State : Saved_Scan_State;
717 begin
718 if Token = Tok_Semicolon then
719 T_Semicolon;
720 return;
722 -- An interesting little test here. If the previous token is a
723 -- semicolon, then there is no way that we can legitimately need
724 -- another semicolon. This could only arise in an error situation
725 -- where an error has already been signalled. By simply ignoring
726 -- the request for a semicolon in this case, we avoid some spurious
727 -- missing semicolon messages.
729 elsif Prev_Token = Tok_Semicolon then
730 return;
732 else
733 -- Deal with pragma. If pragma is not at start of line, it is
734 -- considered misplaced otherwise we treat it as a normal
735 -- missing semicolon case.
737 if Token = Tok_Pragma
738 and then not Token_Is_At_Start_Of_Line
739 then
740 P_Pragmas_Misplaced;
742 if Token = Tok_Semicolon then
743 T_Semicolon;
744 return;
745 end if;
746 end if;
748 -- Here we definitely have a missing semicolon, so give message
750 T_Semicolon;
752 -- Scan out junk on rest of line. Scan stops on END keyword, since
753 -- that seems to help avoid cascaded errors.
755 Save_Scan_State (Scan_State); -- at start of junk tokens
757 loop
758 if Prev_Token_Ptr < Current_Line_Start
759 or else Token in Tok_EOF | Tok_End
760 then
761 Restore_Scan_State (Scan_State); -- to where we were
762 return;
763 end if;
765 Scan; -- continue search
767 if Token = Tok_Semicolon then
768 T_Semicolon;
769 return;
771 elsif Token in Token_Class_After_SM then
772 return;
773 end if;
774 end loop;
775 end if;
776 end TF_Semicolon;
778 -------------
779 -- TF_Then --
780 -------------
782 procedure TF_Then is
783 Scan_State : Saved_Scan_State;
785 begin
786 if Token = Tok_Then then
787 Scan; -- past THEN and we are done
789 else
790 T_Then; -- give missing THEN message
791 Save_Scan_State (Scan_State); -- at start of junk tokens
793 loop
794 if Prev_Token_Ptr < Current_Line_Start
795 or else Token in Tok_Semicolon | Tok_EOF
796 then
797 Restore_Scan_State (Scan_State); -- to where we were
798 return;
799 end if;
801 Scan; -- continue search
803 if Token = Tok_Then then
804 Scan; -- past THEN
805 return;
806 end if;
807 end loop;
808 end if;
809 end TF_Then;
811 ------------
812 -- TF_Use --
813 ------------
815 procedure TF_Use is
816 Scan_State : Saved_Scan_State;
818 begin
819 if Token = Tok_Use then
820 Scan; -- past USE and we are done
822 else
823 T_Use; -- give USE expected message
824 Save_Scan_State (Scan_State); -- at start of junk tokens
826 loop
827 if Prev_Token_Ptr < Current_Line_Start
828 or else Token in Tok_Semicolon | Tok_EOF
829 then
830 Restore_Scan_State (Scan_State); -- to where we were
831 return;
832 end if;
834 Scan; -- continue search
836 if Token = Tok_Use then
837 Scan; -- past use
838 return;
839 end if;
840 end loop;
841 end if;
842 end TF_Use;
844 ------------------
845 -- U_Left_Paren --
846 ------------------
848 procedure U_Left_Paren is
849 begin
850 if Token = Tok_Left_Paren then
851 Scan;
852 else
853 Error_Msg_AP -- CODEFIX
854 ("missing ""(""!");
855 end if;
856 end U_Left_Paren;
858 -------------------
859 -- U_Right_Paren --
860 -------------------
862 procedure U_Right_Paren is
863 begin
864 if Token = Tok_Right_Paren then
865 Scan;
866 else
867 Error_Msg_AP -- CODEFIX
868 ("|missing "")""!");
869 end if;
870 end U_Right_Paren;
872 -----------------
873 -- Wrong_Token --
874 -----------------
876 procedure Wrong_Token (T : Token_Type; P : Position) is
877 Missing : constant String := "missing ";
878 Image : constant String := Token_Type'Image (T);
879 Tok_Name : constant String := Image (5 .. Image'Length);
880 M : constant String := Missing & Tok_Name;
882 begin
883 if Token = Tok_Semicolon then
884 Scan;
886 if Token = T then
887 Error_Msg_SP -- CODEFIX
888 ("|extra "";"" ignored");
889 Scan;
890 else
891 Error_Msg_SP (M);
892 end if;
894 elsif Token = Tok_Comma then
895 Scan;
897 if Token = T then
898 Error_Msg_SP -- CODEFIX
899 ("|extra "","" ignored");
900 Scan;
902 else
903 Error_Msg_SP (M);
904 end if;
906 else
907 case P is
908 when SC => Error_Msg_SC (M);
909 when BC => Error_Msg_BC (M);
910 when AP => Error_Msg_AP (M);
911 end case;
912 end if;
913 end Wrong_Token;
915 end Tchk;