1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- S C A N S -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1992-2019, 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. -- 17-- -- 18-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 21-- -- 22-- You should have received a copy of the GNU General Public License and -- 23-- a copy of the GCC Runtime Library Exception along with this program; -- 24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 25-- <http://www.gnu.org/licenses/>. -- 26-- -- 27-- GNAT was originally developed by the GNAT team at New York University. -- 28-- Extensive contributions were provided by Ada Core Technologies Inc. -- 29-- -- 30------------------------------------------------------------------------------ 31 32with Namet; use Namet; 33with Types; use Types; 34with Uintp; use Uintp; 35with Urealp; use Urealp; 36 37package Scans is 38 39-- The scanner maintains a current state in the global variables defined 40-- in this package. The call to the Scan routine advances this state to 41-- the next token. The state is initialized by the call to one of the 42-- initialization routines in Sinput. 43 44 -- The following type is used to identify token types returned by Scan. 45 -- The class column in this table indicates the token classes which 46 -- apply to the token, as defined by subsequent subtype declarations. 47 48 type Token_Type is ( 49 50 -- Token name Token type Class(es) 51 52 Tok_Integer_Literal, -- numeric lit Literal, Lit_Or_Name 53 54 Tok_Real_Literal, -- numeric lit Literal, Lit_Or_Name 55 56 Tok_String_Literal, -- string lit Literal. Lit_Or_Name 57 58 Tok_Char_Literal, -- char lit Name, Literal. Lit_Or_Name 59 60 Tok_Operator_Symbol, -- op symbol Name, Literal, Lit_Or_Name, Desig 61 62 Tok_Identifier, -- identifier Name, Lit_Or_Name, Desig 63 64 Tok_At_Sign, -- @ AI12-0125-3 : target name 65 66 Tok_Double_Asterisk, -- ** 67 68 Tok_Ampersand, -- & Binary_Addop 69 Tok_Minus, -- - Binary_Addop, Unary_Addop 70 Tok_Plus, -- + Binary_Addop, Unary_Addop 71 72 Tok_Asterisk, -- * Mulop 73 Tok_Mod, -- MOD Mulop 74 Tok_Rem, -- REM Mulop 75 Tok_Slash, -- / Mulop 76 77 Tok_New, -- NEW 78 79 Tok_Abs, -- ABS 80 Tok_Others, -- OTHERS 81 Tok_Null, -- NULL 82 83 -- Note: Tok_Raise is in no categories now, it used to be Cterm, Eterm, 84 -- After_SM, but now that Ada 2012 has added raise expressions, the 85 -- raise token can appear anywhere. Note in particular that Tok_Raise 86 -- being in Eterm stopped the parser from recognizing "return raise 87 -- exception-name". This degrades error recovery slightly, and perhaps 88 -- we could do better, but not worth the effort. 89 90 -- Ada2020 introduces square brackets as delimiters for array and 91 -- container aggregates. 92 93 Tok_Raise, -- RAISE 94 95 Tok_Dot, -- . Namext 96 Tok_Apostrophe, -- ' Namext 97 98 Tok_Left_Bracket, -- [ Namest 99 Tok_Left_Paren, -- ( Namext, Consk 100 101 Tok_Delta, -- DELTA Atkwd, Sterm, Consk 102 Tok_Digits, -- DIGITS Atkwd, Sterm, Consk 103 Tok_Range, -- RANGE Atkwd, Sterm, Consk 104 105 Tok_Right_Paren, -- ) Sterm 106 Tok_Right_Bracket, -- ] Sterm 107 Tok_Comma, -- , Sterm 108 109 Tok_And, -- AND Logop, Sterm 110 Tok_Or, -- OR Logop, Sterm 111 Tok_Xor, -- XOR Logop, Sterm 112 113 Tok_Less, -- < Relop, Sterm 114 Tok_Equal, -- = Relop, Sterm 115 Tok_Greater, -- > Relop, Sterm 116 Tok_Not_Equal, -- /= Relop, Sterm 117 Tok_Greater_Equal, -- >= Relop, Sterm 118 Tok_Less_Equal, -- <= Relop, Sterm 119 120 Tok_In, -- IN Relop, Sterm 121 Tok_Not, -- NOT Relop, Sterm 122 123 Tok_Box, -- <> Relop, Eterm, Sterm 124 Tok_Colon_Equal, -- := Eterm, Sterm 125 Tok_Colon, -- : Eterm, Sterm 126 Tok_Greater_Greater, -- >> Eterm, Sterm 127 128 Tok_Abstract, -- ABSTRACT Eterm, Sterm 129 Tok_Access, -- ACCESS Eterm, Sterm 130 Tok_Aliased, -- ALIASED Eterm, Sterm 131 Tok_All, -- ALL Eterm, Sterm 132 Tok_Array, -- ARRAY Eterm, Sterm 133 Tok_At, -- AT Eterm, Sterm 134 Tok_Body, -- BODY Eterm, Sterm 135 Tok_Constant, -- CONSTANT Eterm, Sterm 136 Tok_Do, -- DO Eterm, Sterm 137 Tok_Is, -- IS Eterm, Sterm 138 Tok_Interface, -- INTERFACE Eterm, Sterm 139 Tok_Limited, -- LIMITED Eterm, Sterm 140 Tok_Of, -- OF Eterm, Sterm 141 Tok_Out, -- OUT Eterm, Sterm 142 Tok_Record, -- RECORD Eterm, Sterm 143 Tok_Renames, -- RENAMES Eterm, Sterm 144 Tok_Reverse, -- REVERSE Eterm, Sterm 145 Tok_Some, -- SOME Eterm, Sterm 146 Tok_Tagged, -- TAGGED Eterm, Sterm 147 Tok_Then, -- THEN Eterm, Sterm 148 149 Tok_Less_Less, -- << Eterm, Sterm, After_SM 150 151 Tok_Abort, -- ABORT Eterm, Sterm, After_SM 152 Tok_Accept, -- ACCEPT Eterm, Sterm, After_SM 153 Tok_Case, -- CASE Eterm, Sterm, After_SM 154 Tok_Delay, -- DELAY Eterm, Sterm, After_SM 155 Tok_Else, -- ELSE Eterm, Sterm, After_SM 156 Tok_Elsif, -- ELSIF Eterm, Sterm, After_SM 157 Tok_End, -- END Eterm, Sterm, After_SM 158 Tok_Exception, -- EXCEPTION Eterm, Sterm, After_SM 159 Tok_Exit, -- EXIT Eterm, Sterm, After_SM 160 Tok_Goto, -- GOTO Eterm, Sterm, After_SM 161 Tok_If, -- IF Eterm, Sterm, After_SM 162 Tok_Pragma, -- PRAGMA Eterm, Sterm, After_SM 163 Tok_Requeue, -- REQUEUE Eterm, Sterm, After_SM 164 Tok_Return, -- RETURN Eterm, Sterm, After_SM 165 Tok_Select, -- SELECT Eterm, Sterm, After_SM 166 Tok_Terminate, -- TERMINATE Eterm, Sterm, After_SM 167 Tok_Until, -- UNTIL Eterm, Sterm, After_SM 168 Tok_When, -- WHEN Eterm, Sterm, After_SM 169 170 Tok_Begin, -- BEGIN Eterm, Sterm, After_SM, Labeled_Stmt 171 Tok_Declare, -- DECLARE Eterm, Sterm, After_SM, Labeled_Stmt 172 Tok_For, -- FOR Eterm, Sterm, After_SM, Labeled_Stmt 173 Tok_Loop, -- LOOP Eterm, Sterm, After_SM, Labeled_Stmt 174 Tok_While, -- WHILE Eterm, Sterm, After_SM, Labeled_Stmt 175 176 Tok_Entry, -- ENTRY Eterm, Sterm, Declk, Deckn, After_SM 177 Tok_Protected, -- PROTECTED Eterm, Sterm, Declk, Deckn, After_SM 178 Tok_Task, -- TASK Eterm, Sterm, Declk, Deckn, After_SM 179 Tok_Type, -- TYPE Eterm, Sterm, Declk, Deckn, After_SM 180 Tok_Subtype, -- SUBTYPE Eterm, Sterm, Declk, Deckn, After_SM 181 Tok_Overriding, -- OVERRIDING Eterm, Sterm, Declk, Declk, After_SM 182 Tok_Synchronized, -- SYNCHRONIZED Eterm, Sterm, Declk, Deckn, After_SM 183 Tok_Use, -- USE Eterm, Sterm, Declk, Deckn, After_SM 184 185 Tok_Function, -- FUNCTION Eterm, Sterm, Cunit, Declk, After_SM 186 Tok_Generic, -- GENERIC Eterm, Sterm, Cunit, Declk, After_SM 187 Tok_Package, -- PACKAGE Eterm, Sterm, Cunit, Declk, After_SM 188 Tok_Procedure, -- PROCEDURE Eterm, Sterm, Cunit, Declk, After_SM 189 190 Tok_Private, -- PRIVATE Eterm, Sterm, Cunit, After_SM 191 Tok_With, -- WITH Eterm, Sterm, Cunit, After_SM 192 Tok_Separate, -- SEPARATE Eterm, Sterm, Cunit, After_SM 193 194 Tok_EOF, -- End of file Eterm, Sterm, Cterm, After_SM 195 196 Tok_Semicolon, -- ; Eterm, Sterm, Cterm 197 198 Tok_Arrow, -- => Sterm, Cterm, Chtok 199 200 Tok_Vertical_Bar, -- | Cterm, Sterm, Chtok 201 202 Tok_Dot_Dot, -- .. Sterm, Chtok 203 204 Tok_Project, 205 Tok_Extends, 206 Tok_External, 207 Tok_External_As_List, 208 -- These four entries represent keywords for the project file language 209 -- and can be returned only in the case of scanning project files. 210 211 Tok_Comment, 212 -- This entry is used when scanning project files (where it represents 213 -- an entire comment), and in preprocessing with the -C switch set 214 -- (where it represents just the "--" of a comment). For the project 215 -- file case, the text of the comment is stored in Comment_Id. 216 217 Tok_End_Of_Line, 218 -- Represents an end of line. Not used during normal compilation scans 219 -- where end of line is ignored. Active for preprocessor scanning and 220 -- also when scanning project files (where it is needed because of ???) 221 222 Tok_Special, 223 -- AI12-0125-03 : target name as abbreviation for LHS 224 225 -- Otherwise used only in preprocessor scanning (to represent one of 226 -- the characters '#', '$', '?', '@', '`', '\', '^', '~', or '_'. The 227 -- character value itself is stored in Scans.Special_Character. 228 229 Tok_SPARK_Hide, 230 -- HIDE directive in SPARK 231 232 No_Token); 233 -- No_Token is used for initializing Token values to indicate that 234 -- no value has been set yet. 235 236 function Keyword_Name (Token : Token_Type) return Name_Id; 237 -- Given a token that is a reserved word, return the corresponding Name_Id 238 -- in lower case. E.g. Keyword_Name (Tok_Begin) = Name_Find ("begin"). 239 -- It is an error to pass any other kind of token. 240 241 -- Note: in the RM, operator symbol is a special case of string literal. 242 -- We distinguish at the lexical level in this compiler, since there are 243 -- many syntactic situations in which only an operator symbol is allowed. 244 245 -- The following subtype declarations group the token types into classes. 246 -- These are used for class tests in the parser. 247 248 subtype Token_Class_Numeric_Literal is 249 Token_Type range Tok_Integer_Literal .. Tok_Real_Literal; 250 -- Numeric literal 251 252 subtype Token_Class_Literal is 253 Token_Type range Tok_Integer_Literal .. Tok_Operator_Symbol; 254 -- Literal 255 256 subtype Token_Class_Lit_Or_Name is 257 Token_Type range Tok_Integer_Literal .. Tok_Identifier; 258 259 subtype Token_Class_Binary_Addop is 260 Token_Type range Tok_Ampersand .. Tok_Plus; 261 -- Binary adding operator (& + -) 262 263 subtype Token_Class_Unary_Addop is 264 Token_Type range Tok_Minus .. Tok_Plus; 265 -- Unary adding operator (+ -) 266 267 subtype Token_Class_Mulop is 268 Token_Type range Tok_Asterisk .. Tok_Slash; 269 -- Multiplying operator 270 271 subtype Token_Class_Logop is 272 Token_Type range Tok_And .. Tok_Xor; 273 -- Logical operator (and, or, xor) 274 275 subtype Token_Class_Relop is 276 Token_Type range Tok_Less .. Tok_Box; 277 -- Relational operator (= /= < <= > >= not, in plus <> to catch misuse 278 -- of Pascal style not equal operator). 279 280 subtype Token_Class_Name is 281 Token_Type range Tok_Char_Literal .. Tok_At_Sign; 282 -- First token of name (4.1), 283 -- (identifier, char literal, operator symbol) 284 -- Includes '@' after Ada2012 corrigendum. 285 286 subtype Token_Class_Desig is 287 Token_Type range Tok_Operator_Symbol .. Tok_At_Sign; 288 -- Token which can be a Designator (identifier, operator symbol) 289 290 subtype Token_Class_Namext is 291 Token_Type range Tok_Dot .. Tok_Left_Paren; 292 -- Name extension tokens. These are tokens which can appear immediately 293 -- after a name to extend it recursively (period, quote, left paren) 294 295 subtype Token_Class_Consk is 296 Token_Type range Tok_Left_Paren .. Tok_Range; 297 -- Keywords which can start constraint 298 -- (left paren, delta, digits, range) 299 300 subtype Token_Class_Eterm is 301 Token_Type range Tok_Colon_Equal .. Tok_Semicolon; 302 -- Expression terminators. These tokens can never appear within a simple 303 -- expression. This is used for error recovery purposes (if we encounter 304 -- an error in an expression, we simply scan to the next Eterm token). 305 306 subtype Token_Class_Sterm is 307 Token_Type range Tok_Delta .. Tok_Dot_Dot; 308 -- Simple_Expression terminators. A Simple_Expression must be followed 309 -- by a token in this class, or an error message is issued complaining 310 -- about a missing binary operator. 311 312 subtype Token_Class_Atkwd is 313 Token_Type range Tok_Delta .. Tok_Range; 314 -- Attribute keywords. This class includes keywords which can be used 315 -- as an Attribute_Designator, namely DELTA, DIGITS and RANGE 316 317 subtype Token_Class_Cterm is 318 Token_Type range Tok_EOF .. Tok_Vertical_Bar; 319 -- Choice terminators. These tokens terminate a choice. This is used for 320 -- error recovery purposes (if we encounter an error in a Choice, we 321 -- simply scan to the next Cterm token). 322 323 subtype Token_Class_Chtok is 324 Token_Type range Tok_Arrow .. Tok_Dot_Dot; 325 -- Choice tokens. These tokens signal a choice when used in an Aggregate 326 327 subtype Token_Class_Cunit is 328 Token_Type range Tok_Function .. Tok_Separate; 329 -- Tokens which can begin a compilation unit 330 331 subtype Token_Class_Declk is 332 Token_Type range Tok_Entry .. Tok_Procedure; 333 -- Keywords which start a declaration 334 335 subtype Token_Class_Deckn is 336 Token_Type range Tok_Entry .. Tok_Use; 337 -- Keywords which start a declaration but can't start a compilation unit 338 339 subtype Token_Class_After_SM is 340 Token_Type range Tok_Less_Less .. Tok_EOF; 341 -- Tokens which always, or almost always, appear after a semicolon. Used 342 -- in the Resync_Past_Semicolon routine to avoid gobbling up stuff when 343 -- a semicolon is missing. Of significance only for error recovery. 344 345 subtype Token_Class_Labeled_Stmt is 346 Token_Type range Tok_Begin .. Tok_While; 347 -- Tokens which start labeled statements 348 349 type Token_Flag_Array is array (Token_Type) of Boolean; 350 Is_Reserved_Keyword : constant Token_Flag_Array := 351 Token_Flag_Array' 352 (Tok_Mod .. Tok_Rem => True, 353 Tok_New .. Tok_Null => True, 354 Tok_Delta .. Tok_Range => True, 355 Tok_And .. Tok_Xor => True, 356 Tok_In .. Tok_Not => True, 357 Tok_Abstract .. Tok_Then => True, 358 Tok_Abort .. Tok_Separate => True, 359 others => False); 360 -- Flag array used to test for reserved word 361 362 procedure Initialize_Ada_Keywords; 363 -- Set up Token_Type values in Names table entries for Ada reserved 364 -- words. This ignores Ada_Version; Ada_Version is taken into account in 365 -- Snames.Is_Keyword_Name. 366 367 -------------------------- 368 -- Scan State Variables -- 369 -------------------------- 370 371 -- Note: these variables can only be referenced during the parsing of a 372 -- file. Reference to any of them from Sem or the expander is wrong. 373 374 -- These variables are initialized as required by Scn.Initialize_Scanner, 375 -- and should not be referenced before such a call. However, there are 376 -- situations in which these variables are saved and restored, and this 377 -- may happen before the first Initialize_Scanner call, resulting in the 378 -- assignment of invalid values. To avoid this, and allow building with 379 -- the -gnatVa switch, we initialize some variables to known valid values. 380 381 Scan_Ptr : Source_Ptr := No_Location; -- init for -gnatVa 382 -- Current scan pointer location. After a call to Scan, this points 383 -- just past the end of the token just scanned. 384 385 Token : Token_Type := No_Token; -- init for -gnatVa 386 -- Type of current token 387 388 Token_Ptr : Source_Ptr := No_Location; -- init for -gnatVa 389 -- Pointer to first character of current token 390 391 Current_Line_Start : Source_Ptr := No_Location; -- init for -gnatVa 392 -- Pointer to first character of line containing current token 393 394 Start_Column : Column_Number := No_Column_Number; -- init for -gnatVa 395 -- Starting column number (zero origin) of the first non-blank character 396 -- on the line containing the current token. This is used for error 397 -- recovery circuits which depend on looking at the column line up. 398 399 Type_Token_Location : Source_Ptr := No_Location; -- init for -gnatVa 400 -- Within a type declaration, gives the location of the TYPE keyword that 401 -- opened the type declaration. Used in checking the end column of a record 402 -- declaration, which can line up either with the TYPE keyword, or with the 403 -- start of the line containing the RECORD keyword. 404 405 Checksum : Word := 0; -- init for -gnatVa 406 -- Used to accumulate a CRC representing the tokens in the source 407 -- file being compiled. This CRC includes only program tokens, and 408 -- excludes comments. 409 410 Limited_Checksum : Word := 0; 411 -- Used to accumulate a CRC representing significant tokens in the 412 -- limited view of a package, i.e. visible type names and related 413 -- tagged indicators. 414 415 First_Non_Blank_Location : Source_Ptr := No_Location; -- init for -gnatVa 416 -- Location of first non-blank character on the line containing the 417 -- current token (i.e. the location of the character whose column number 418 -- is stored in Start_Column). 419 420 Token_Node : Node_Id := Empty; 421 -- Node table Id for the current token. This is set only if the current 422 -- token is one for which the scanner constructs a node (i.e. it is an 423 -- identifier, operator symbol, or literal). For other token types, 424 -- Token_Node is undefined. 425 426 Token_Name : Name_Id := No_Name; 427 -- For identifiers, this is set to the Name_Id of the identifier scanned. 428 -- For all other tokens, Token_Name is set to Error_Name. Note that it 429 -- would be possible for the caller to extract this information from 430 -- Token_Node. We set Token_Name separately for two reasons. First it 431 -- allows a quicker test for a specific identifier. Second, it allows 432 -- a version of the parser to be built that does not build tree nodes, 433 -- usable as a syntax checker. 434 435 Prev_Token : Token_Type := No_Token; 436 -- Type of previous token 437 438 Prev_Token_Ptr : Source_Ptr; 439 -- Pointer to first character of previous token 440 441 Version_To_Be_Found : Boolean; 442 -- This flag is True if the scanner is still looking for an RCS version 443 -- number in a comment. Normally it is initialized to False so that this 444 -- circuit is not activated. If the -dv switch is set, then this flag is 445 -- initialized to True, and then reset when the version number is found. 446 -- We do things this way to minimize the impact on comment scanning. 447 448 Character_Code : Char_Code; 449 -- Valid only when Token is Tok_Char_Literal. Contains the value of the 450 -- scanned literal. 451 452 Real_Literal_Value : Ureal; 453 -- Valid only when Token is Tok_Real_Literal, contains the value of the 454 -- scanned literal. 455 456 Int_Literal_Value : Uint; 457 -- Valid only when Token = Tok_Integer_Literal, contains the value of the 458 -- scanned literal. 459 460 Based_Literal_Uses_Colon : Boolean; 461 -- Valid only when Token = Tok_Integer_Literal or Tok_Real_Literal. Set 462 -- True only for the case of a based literal using ':' instead of '#'. 463 464 String_Literal_Id : String_Id; 465 -- Valid only when Token = Tok_String_Literal or Tok_Operator_Symbol. 466 -- Contains the Id for currently scanned string value. 467 468 Wide_Character_Found : Boolean := False; 469 -- Valid only when Token = Tok_String_Literal. Set True if wide character 470 -- found (i.e. a character that does not fit in Character, but fits in 471 -- Wide_Wide_Character). 472 473 Wide_Wide_Character_Found : Boolean := False; 474 -- Valid only when Token = Tok_String_Literal. Set True if wide wide 475 -- character found (i.e. a character that does not fit in Character or 476 -- Wide_Character). 477 478 Special_Character : Character; 479 -- AI12-0125-03 : '@' as target name is handled elsewhere. 480 -- Valid only when Token = Tok_Special. Returns one of the characters 481 -- '#', '$', '?', '`', '\', '^', '~', or '_'. 482 -- 483 -- Why only this set? What about wide characters??? 484 485 Comment_Id : Name_Id := No_Name; 486 -- Valid only when Token = Tok_Comment. Store the string that follows 487 -- the "--" of a comment when scanning project files. 488 -- 489 -- Is it really right for this to be a Name rather than a String, what 490 -- about the case of Wide_Wide_Characters??? 491 492 Inside_Depends : Boolean := False; 493 -- True while parsing the argument of a Depends or Refined_Depends pragma 494 -- or aspect. Used to allow/require nonstandard style rules for =>+ with 495 -- -gnatyt. 496 497 Inside_If_Expression : Nat := 0; 498 -- This is a counter that is set non-zero while scanning out an if 499 -- expression (incremented on entry, decremented on exit). It is used to 500 -- disconnect format checks that normally apply to keywords THEN, ELSE etc. 501 502 Inside_Pragma : Boolean := False; 503 -- True within a pragma. Used to avoid complaining about reserved words 504 -- within pragmas (see Scan_Reserved_Identifier). 505 506 -------------------------------------------------------- 507 -- Procedures for Saving and Restoring the Scan State -- 508 -------------------------------------------------------- 509 510 -- The following procedures can be used to save and restore the entire 511 -- scan state. They are used in cases where it is necessary to backup 512 -- the scan during the parse. 513 514 type Saved_Scan_State is private; 515 -- Used for saving and restoring the scan state 516 517 procedure Save_Scan_State (Saved_State : out Saved_Scan_State); 518 pragma Inline (Save_Scan_State); 519 -- Saves the current scan state for possible later restoration. Note that 520 -- there is no harm in saving the state and then never restoring it. 521 522 procedure Restore_Scan_State (Saved_State : Saved_Scan_State); 523 pragma Inline (Restore_Scan_State); 524 -- Restores a scan state saved by a call to Save_Scan_State. 525 -- The saved scan state must refer to the current source file. 526 527private 528 type Saved_Scan_State is record 529 Save_Scan_Ptr : Source_Ptr; 530 Save_Token : Token_Type; 531 Save_Token_Ptr : Source_Ptr; 532 Save_Current_Line_Start : Source_Ptr; 533 Save_Start_Column : Column_Number; 534 Save_Checksum : Word; 535 Save_First_Non_Blank_Location : Source_Ptr; 536 Save_Token_Node : Node_Id; 537 Save_Token_Name : Name_Id; 538 Save_Prev_Token : Token_Type; 539 Save_Prev_Token_Ptr : Source_Ptr; 540 end record; 541 542end Scans; 543