home *** CD-ROM | disk | FTP | other *** search
/ Programmer's ROM - The Computer Language Library / programmersrom.iso / ada / metric / halstead.tst < prev    next >
Encoding:
Text File  |  1988-05-03  |  29.9 KB  |  752 lines

  1. ::::::::::::::
  2. scanners.bdy
  3. ::::::::::::::
  4. package body scanners is    --| Scan tokens from strings
  5.  
  6. ----------------------------------------------------------------------------
  7. -- Local function specs:
  8.  
  9. function is_Space(C: Character) return boolean;
  10. --| Return True iff C is a space or tab.
  11.  
  12. ----------------------------------------------------------------------------
  13.  
  14. procedure start_Scanner(    --| Initialize a scanner
  15.     Scanner: in out Scanner_Type;    --| Scanner to be initialized
  16.     S: in string;            --| String to be scanned
  17.     Last: in natural            --| Last scannable character in S.
  18.     )
  19. is
  20.  
  21. begin
  22.     Scanner.Index := S'First;
  23.     Scanner.Max_Index := Last;
  24.     Scanner.First := 1;
  25.     Scanner.Last := 0;
  26.     Scanner.Length := 0;
  27.  
  28. end start_Scanner;
  29.  
  30. ----------------------------------------------------------------------------
  31.  
  32. function is_Empty(    --| Return False if Scanner can scan more characters
  33.     Scanner: in Scanner_Type
  34.     ) return boolean is
  35.  
  36. begin
  37.     return Scanner.Index > Scanner.Max_Index;
  38.  
  39. end is_Empty;
  40.  
  41. ----------------------------------------------------------------------------
  42.  
  43. function is_Alpha(    --| Check for alphabetic character
  44.     Scanner: in scanner_Type;
  45.     S: in string
  46.     ) return boolean is
  47.  
  48. begin
  49.     return Scanner.Index <= scanner.Max_Index and then 
  50.        (S(Scanner.Index) in 'a'..'z' or else
  51.        S(Scanner.Index) in 'A'..'Z');
  52.  
  53. end is_Alpha;
  54.  
  55. ----------------------------------------------------------------------------
  56.  
  57. function is_Digit(    --| Check for start of  unsigned number
  58.     Scanner: in scanner_Type;
  59.     S: in string
  60.     ) return boolean is
  61.  
  62. begin
  63.     return Scanner.Index <= scanner.Max_Index and then 
  64.            S(Scanner.Index) in '0'..'9';
  65.  
  66. end is_Digit;
  67.  
  68. ----------------------------------------------------------------------------
  69.  
  70. function is_Sign(    --| Check for '+' or '-'
  71.     Scanner: in scanner_Type;
  72.     S: in string
  73.     ) return boolean is
  74.  
  75. begin
  76.     return Scanner.Index <= scanner.Max_Index and then 
  77.        (S(Scanner.Index) = '+' or else S(Scanner.Index) = '-');
  78.  
  79. end is_Sign;
  80.  
  81. ----------------------------------------------------------------------------
  82.  
  83. function is_Digit_or_Sign(    --| Check for start of optionally signed number
  84.     Scanner: in scanner_Type;
  85.     S: in string
  86.     ) return boolean is
  87.  
  88. begin
  89.     return Scanner.Index <= scanner.Max_Index and then 
  90.        (S(Scanner.Index) in '0'..'9'
  91.        or else S(Scanner.Index) = '+' or else S(Scanner.Index) = '-');
  92.  
  93. end is_Digit_or_Sign;
  94.  
  95.  
  96. ----------------------------------------------------------------------------
  97.  
  98. procedure skip_Blanks(    --| Skip leading blanks in S
  99.     Scanner: in out Scanner_Type;    --| Scanner to be updated
  100.     S: in string            --| String being scanned
  101.     ) is
  102.  
  103. begin
  104.     Scanner.First := Scanner.Index;
  105.     Scanner.Length := 0;
  106.     if Scanner.Index <= Scanner.Max_Index then
  107.       while is_Space(S(Scanner.Index)) loop
  108.     Scanner.Index := Scanner.Index + 1;
  109.     exit when Scanner.Index > Scanner.Max_Index;
  110.       end loop;
  111.       Scanner.Length := Scanner.Index - Scanner.First;
  112.     end if;
  113.  
  114. end skip_Blanks;
  115.  
  116. ----------------------------------------------------------------------------
  117.  
  118. procedure trim_blanks(
  119.     Scanner: in out Scanner_Type;
  120.     S: in string
  121.     ) is
  122. begin
  123.     while Scanner.First < Scanner.Last and then is_Space(S(Scanner.First)) loop
  124.     Scanner.First := Scanner.First + 1;
  125.     end loop;
  126.     while Scanner.Last >= Scanner.First and then is_Space(S(Scanner.Last)) loop
  127.     Scanner.Last := Scanner.Last - 1;
  128.     end loop;
  129.     Scanner.Length := Scanner.Last - Scanner.First + 1;
  130.  
  131. end trim_Blanks;
  132.  
  133. ----------------------------------------------------------------------------
  134.  
  135. procedure scan_Until(    --| Scan until C is found
  136.     Scanner: in out Scanner_Type;
  137.     S: in string;
  138.     C: in character
  139.     )
  140. is
  141.     Index: natural := Scanner.Index;
  142.  
  143. begin
  144.     Scanner.Length := 0;
  145.     if Index <= Scanner.Max_Index then
  146.       while S(Index) /= C loop
  147.     Index := Index + 1;
  148.     if Index > Scanner.Max_Index then    -- Didn't find C
  149.       return;
  150.     end if;
  151.       end loop;
  152.       Scanner.First := Scanner.Index;    -- First character scanned
  153.       Scanner.Length := Index - Scanner.First;
  154.       Scanner.Last := Index - 1;
  155.       Scanner.Index := Index;
  156.     end if;
  157.  
  158. end scan_Until;
  159.  
  160. ----------------------------------------------------------------------------
  161.  
  162. procedure scan_Word(    --| Scan past a sequence of non-blank characters
  163.     Scanner: in out Scanner_Type;
  164.     S: in string
  165.     ) is
  166.  
  167. begin
  168.     Scanner.First := Scanner.Index;
  169.     Scanner.Last := Scanner.First - 1;
  170.     Scanner.Length := 0;
  171.     if Scanner.Index <= Scanner.Max_Index then
  172.       while not is_Space(S(Scanner.Index)) loop
  173.     Scanner.Index := Scanner.Index + 1;
  174.     exit when Scanner.Index > Scanner.Max_Index;
  175.       end loop;
  176.       Scanner.Length := Scanner.Index - Scanner.First;
  177.       Scanner.Last := Scanner.Index - 1;
  178.     end if;
  179.  
  180. end scan_Word;
  181.  
  182. ----------------------------------------------------------------------------
  183.  
  184. procedure scan_Number(
  185.     Scanner: in out scanner_Type;
  186.     S: in string
  187.     ) is
  188.  
  189. begin
  190.     Scanner.First := Scanner.Index;
  191.     if Scanner.Index <= Scanner.Max_Index then
  192.       if S(Scanner.Index) = '-' or else S(Scanner.Index) = '+' then
  193.     Scanner.Index := Scanner.Index + 1;
  194.       end if;
  195.       while Scanner.Index <= Scanner.Max_Index
  196.         and then S(Scanner.Index) in '0'..'9'
  197.       loop
  198.     Scanner.Index := Scanner.Index + 1;
  199.       end loop;
  200.     end if;
  201.     Scanner.Length := Scanner.Index - Scanner.First;
  202.     Scanner.Last := Scanner.Index - 1;
  203.  
  204. end scan_Number;
  205.  
  206. ----------------------------------------------------------------------------
  207.  
  208. procedure scan_Delimited(    --| Scan string delimited by a single character
  209.     Scanner: in out scanner_Type;
  210.     S: in string
  211.     )
  212. is
  213.     quote: character;
  214.  
  215. begin
  216.     Scanner.First := Scanner.Index;
  217.     if Scanner.Index <= Scanner.Max_Index then
  218.     quote := S(Scanner.Index);
  219.     Scanner.Index := Scanner.Index + 1;
  220.     Scanner.First := Scanner.Index;
  221.     while Scanner.Index <= Scanner.Max_Index 
  222.           and then S(Scanner.Index) /= quote
  223.     loop
  224.       Scanner.Index := Scanner.Index + 1;
  225.     end loop;
  226.     end if;
  227.     Scanner.Length := Scanner.Index - Scanner.First;
  228.     Scanner.Last := Scanner.Index - 1;
  229.     if Scanner.Index <= Scanner.Max_Index
  230.     and then S(Scanner.Index) = quote then    -- Null string?
  231.     Scanner.Index := Scanner.Index + 1;
  232.     end if;
  233.  
  234. end scan_Delimited;
  235.  
  236. ----------------------------------------------------------------------------
  237.  
  238. procedure scan_Quoted(    --| Scan quoted string
  239.     Scanner: in out scanner_Type;
  240.     S: in out string
  241.     )
  242. is
  243.     quote: character;
  244.     di: natural;
  245.  
  246. begin
  247.     Scanner.First := Scanner.Index;
  248.     di := Scanner.Index;
  249.     if Scanner.Index <= Scanner.Max_Index then
  250.     quote := S(Scanner.Index);
  251.     Scanner.Index := Scanner.Index + 1;
  252.     Scanner.First := Scanner.Index;
  253.     di := scanner.Index;
  254.     while Scanner.Index <= Scanner.Max_Index loop
  255.        if S(Scanner.Index) = quote then    -- Closing quote?
  256.         if Scanner.Index < Scanner.Max_Index
  257.         and then S(Scanner.Index + 1) = quote then    -- Doubled quote?
  258.         Scanner.Index := Scanner.Index + 1;    -- skip it
  259.         else
  260.         exit;    -- Found closing quote at Scanner.Index
  261.         end if;
  262.       end if;
  263.       S(di) := S(Scanner.Index);
  264.       Scanner.Index := Scanner.Index + 1;
  265.       di := di + 1;
  266.     end loop;
  267.     end if;
  268.     Scanner.Length := di - Scanner.First;
  269.     Scanner.Last := di - 1;
  270.     Scanner.Index := Scanner.Index + 1;    -- Skip closing quote
  271.  
  272. end scan_Quoted;
  273.  
  274. ----------------------------------------------------------------------------
  275. -- Local function bodies:
  276.  
  277. function is_Space(C: Character) return boolean is
  278. --| Return True iff C is a space or tab.
  279. begin
  280.     return C = ' ' or else C = ASCII.HT;
  281.  
  282. end is_Space;
  283.  
  284. ----------------------------------------------------------------------------
  285.  
  286. end scanners;
  287. ::::::::::::::
  288. scanners.out
  289. ::::::::::::::
  290.        HALSTEAD COMPLEXITY FOR THE SPECIFICATION OF LIBRARY UNIT scanners       
  291.  
  292.  
  293. PACKAGE SPECIFICATION OF SCANNERS AT LINE           1
  294.  
  295. UNIQUE OPERATORS                 26     UNIQUE OPERANDS                    32   
  296. TOTAL OPERATORS                 110     TOTAL OPERANDS                     32   
  297. VOCABULARY                       58                                             
  298. PROGRAM LENGTH                  142     ESTIMATED LENGTH                  282.08
  299. PROGRAM VOLUME                  827.83  POTENTIAL VOLUME                  140.06
  300. PROGRAM LEVEL                      .17  ESTIMATED LEVEL                    78.77
  301. INTELLIGENCE CONTENT          65207.61  PROGRAMMING EFFORT               4892.79
  302. PROGRAMMING TIME                978.56  LANGUAGE LEVEL                     23.70
  303. DELIVERED ERRORS                   .94  ESTIMATED ERRORS                     .28
  304.  
  305.  
  306.            HALSTEAD COMPLEXITY FOR THE BODY OF LIBRARY UNIT scanners            
  307.  
  308.  
  309. PROCEDURE BODY OF SCANNERS.START_SCANNER AT LINE          11
  310.  
  311. UNIQUE OPERATORS                  9     UNIQUE OPERANDS                    13   
  312. TOTAL OPERATORS                  19     TOTAL OPERANDS                     18   
  313. VOCABULARY                       22                                             
  314. PROGRAM LENGTH                   37     ESTIMATED LENGTH                   76.57
  315. PROGRAM VOLUME                  164.99  POTENTIAL VOLUME                   24   
  316. PROGRAM LEVEL                      .15  ESTIMATED LEVEL                    52   
  317. INTELLIGENCE CONTENT           8579.70  PROGRAMMING EFFORT               1134.29
  318. PROGRAMMING TIME                226.86  LANGUAGE LEVEL                      3.49
  319. DELIVERED ERRORS                   .22  ESTIMATED ERRORS                     .05
  320.  
  321.  
  322. FUNCTION BODY OF SCANNERS.IS_EMPTY AT LINE          29
  323.  
  324. UNIQUE OPERATORS                  8     UNIQUE OPERANDS                     4   
  325. TOTAL OPERATORS                  10     TOTAL OPERANDS                      5   
  326. VOCABULARY                       12                                             
  327. PROGRAM LENGTH                   15     ESTIMATED LENGTH                   32   
  328. PROGRAM VOLUME                   53.76  POTENTIAL VOLUME                    8   
  329. PROGRAM LEVEL                      .15  ESTIMATED LEVEL                     5   
  330. INTELLIGENCE CONTENT            268.79  PROGRAMMING EFFORT                361.24
  331. PROGRAMMING TIME                 72.25  LANGUAGE LEVEL                      1.19
  332. DELIVERED ERRORS                   .07  ESTIMATED ERRORS                     .02
  333.  
  334.  
  335. FUNCTION BODY OF SCANNERS.IS_ALPHA AT LINE          40
  336.  
  337. UNIQUE OPERATORS                 15     UNIQUE OPERANDS                    10   
  338. TOTAL OPERATORS                  25     TOTAL OPERANDS                     16   
  339. VOCABULARY                       25                                             
  340. PROGRAM LENGTH                   41     ESTIMATED LENGTH                   91.13
  341. PROGRAM VOLUME                  190.30  POTENTIAL VOLUME                   15.50
  342. PROGRAM LEVEL                      .08  ESTIMATED LEVEL                    21.33
  343. INTELLIGENCE CONTENT           4059.71  PROGRAMMING EFFORT               2335.87
  344. PROGRAMMING TIME                467.17  LANGUAGE LEVEL                      1.26
  345. DELIVERED ERRORS                   .45  ESTIMATED ERRORS                     .06
  346.  
  347.  
  348. FUNCTION BODY OF SCANNERS.IS_DIGIT AT LINE          54
  349.  
  350. UNIQUE OPERATORS                 13     UNIQUE OPERANDS                     8   
  351. TOTAL OPERATORS                  18     TOTAL OPERANDS                     11   
  352. VOCABULARY                       21                                             
  353. PROGRAM LENGTH                   29     ESTIMATED LENGTH                   72.04
  354. PROGRAM VOLUME                  127.38  POTENTIAL VOLUME                   15.50
  355. PROGRAM LEVEL                      .12  ESTIMATED LEVEL                    13.54
  356. INTELLIGENCE CONTENT           1724.48  PROGRAMMING EFFORT               1046.54
  357. PROGRAMMING TIME                209.31  LANGUAGE LEVEL                      1.89
  358. DELIVERED ERRORS                   .20  ESTIMATED ERRORS                     .04
  359.  
  360.  
  361. FUNCTION BODY OF SCANNERS.IS_SIGN AT LINE          67
  362.  
  363. UNIQUE OPERATORS                 14     UNIQUE OPERANDS                     8   
  364. TOTAL OPERATORS                  23     TOTAL OPERANDS                     14   
  365. VOCABULARY                       22                                             
  366. PROGRAM LENGTH                   37     ESTIMATED LENGTH                   77.07
  367. PROGRAM VOLUME                  164.99  POTENTIAL VOLUME                   15.50
  368. PROGRAM LEVEL                      .09  ESTIMATED LEVEL                    16   
  369. INTELLIGENCE CONTENT           2639.91  PROGRAMMING EFFORT               1755.96
  370. PROGRAMMING TIME                351.19  LANGUAGE LEVEL                      1.46
  371. DELIVERED ERRORS                   .34  ESTIMATED ERRORS                     .05
  372.  
  373.  
  374. FUNCTION BODY OF SCANNERS.IS_DIGIT_OR_SIGN AT LINE          80
  375.  
  376. UNIQUE OPERATORS                 16     UNIQUE OPERANDS                    10   
  377. TOTAL OPERATORS                  29     TOTAL OPERANDS                     19   
  378. VOCABULARY                       26                                             
  379. PROGRAM LENGTH                   48     ESTIMATED LENGTH                   97.22
  380. PROGRAM VOLUME                  225.38  POTENTIAL VOLUME                   15.50
  381. PROGRAM LEVEL                      .07  ESTIMATED LEVEL                    23.75
  382. INTELLIGENCE CONTENT           5352.89  PROGRAMMING EFFORT               3276.61
  383. PROGRAMMING TIME                655.32  LANGUAGE LEVEL                      1.07
  384. DELIVERED ERRORS                   .63  ESTIMATED ERRORS                     .08
  385.  
  386.  
  387. PROCEDURE BODY OF SCANNERS.SKIP_BLANKS AT LINE          95
  388.  
  389. UNIQUE OPERATORS                 15     UNIQUE OPERANDS                    10   
  390. TOTAL OPERATORS                  33     TOTAL OPERANDS                     31   
  391. VOCABULARY                       25                                             
  392. PROGRAM LENGTH                   64     ESTIMATED LENGTH                   91.13
  393. PROGRAM VOLUME                  297.05  POTENTIAL VOLUME                   15.50
  394. PROGRAM LEVEL                      .05  ESTIMATED LEVEL                    41.33
  395. INTELLIGENCE CONTENT          12278.14  PROGRAMMING EFFORT               5691.68
  396. PROGRAMMING TIME               1138.34  LANGUAGE LEVEL                       .81
  397. DELIVERED ERRORS                  1.10  ESTIMATED ERRORS                     .10
  398.  
  399.  
  400. PROCEDURE BODY OF SCANNERS.TRIM_BLANKS AT LINE         115
  401.  
  402. UNIQUE OPERATORS                 15     UNIQUE OPERANDS                     8   
  403. TOTAL OPERATORS                  41     TOTAL OPERANDS                     33   
  404. VOCABULARY                       23                                             
  405. PROGRAM LENGTH                   74     ESTIMATED LENGTH                   81.91
  406. PROGRAM VOLUME                  334.71  POTENTIAL VOLUME                   15.50
  407. PROGRAM LEVEL                      .05  ESTIMATED LEVEL                    35.20
  408. INTELLIGENCE CONTENT          11781.88  PROGRAMMING EFFORT               7226.36
  409. PROGRAMMING TIME               1445.27  LANGUAGE LEVEL                       .72
  410. DELIVERED ERRORS                  1.39  ESTIMATED ERRORS                     .11
  411.  
  412.  
  413. PROCEDURE BODY OF SCANNERS.SCAN_UNTIL AT LINE         132
  414.  
  415. UNIQUE OPERATORS                 17     UNIQUE OPERANDS                    14   
  416. TOTAL OPERATORS                  38     TOTAL OPERANDS                     37   
  417. VOCABULARY                       31                                             
  418. PROGRAM LENGTH                   75     ESTIMATED LENGTH                  122.56
  419. PROGRAM VOLUME                  366.15  POTENTIAL VOLUME                   24   
  420. PROGRAM LEVEL                      .07  ESTIMATED LEVEL                    60.94
  421. INTELLIGENCE CONTENT          22313.32  PROGRAMMING EFFORT               5585.93
  422. PROGRAMMING TIME               1117.19  LANGUAGE LEVEL                      1.57
  423. DELIVERED ERRORS                  1.08  ESTIMATED ERRORS                     .12
  424.  
  425.  
  426. PROCEDURE BODY OF SCANNERS.SCAN_WORD AT LINE         159
  427.  
  428. UNIQUE OPERATORS                 16     UNIQUE OPERANDS                    11   
  429. TOTAL OPERATORS                  42     TOTAL OPERANDS                     41   
  430. VOCABULARY                       27                                             
  431. PROGRAM LENGTH                   83     ESTIMATED LENGTH                  102.05
  432. PROGRAM VOLUME                  393.88  POTENTIAL VOLUME                   15.50
  433. PROGRAM LEVEL                      .04  ESTIMATED LEVEL                    56.38
  434. INTELLIGENCE CONTENT          22205.13  PROGRAMMING EFFORT              10007.14
  435. PROGRAMMING TIME               2001.43  LANGUAGE LEVEL                       .61
  436. DELIVERED ERRORS                  1.93  ESTIMATED ERRORS                     .13
  437.  
  438.  
  439. PROCEDURE BODY OF SCANNERS.SCAN_NUMBER AT LINE         181
  440.  
  441. UNIQUE OPERATORS                 19     UNIQUE OPERANDS                    14   
  442. TOTAL OPERATORS                  49     TOTAL OPERANDS                     48   
  443. VOCABULARY                       33                                             
  444. PROGRAM LENGTH                   97     ESTIMATED LENGTH                  133.78
  445. PROGRAM VOLUME                  489.31  POTENTIAL VOLUME                   15.50
  446. PROGRAM LEVEL                      .03  ESTIMATED LEVEL                    70.74
  447. INTELLIGENCE CONTENT          34612     PROGRAMMING EFFORT              15443.24
  448. PROGRAMMING TIME               3088.65  LANGUAGE LEVEL                       .49
  449. DELIVERED ERRORS                  2.97  ESTIMATED ERRORS                     .16
  450.  
  451.  
  452. PROCEDURE BODY OF SCANNERS.SCAN_DELIMITED AT LINE         205
  453.  
  454. UNIQUE OPERATORS                 17     UNIQUE OPERANDS                    11   
  455. TOTAL OPERATORS                  60     TOTAL OPERANDS                     61   
  456. VOCABULARY                       28                                             
  457. PROGRAM LENGTH                  121     ESTIMATED LENGTH                  107.54
  458. PROGRAM VOLUME                  579.68  POTENTIAL VOLUME                   15.50
  459. PROGRAM LEVEL                      .03  ESTIMATED LEVEL                    78.94
  460. INTELLIGENCE CONTENT          45760.71  PROGRAMMING EFFORT              21674.78
  461. PROGRAMMING TIME               4334.96  LANGUAGE LEVEL                       .41
  462. DELIVERED ERRORS                  4.17  ESTIMATED ERRORS                     .19
  463.  
  464.  
  465. PROCEDURE BODY OF SCANNERS.SCAN_QUOTED AT LINE         235
  466.  
  467. UNIQUE OPERATORS                 20     UNIQUE OPERANDS                    12   
  468. TOTAL OPERATORS                  76     TOTAL OPERANDS                     80   
  469. VOCABULARY                       32                                             
  470. PROGRAM LENGTH                  156     ESTIMATED LENGTH                  129.45
  471. PROGRAM VOLUME                  780     POTENTIAL VOLUME                   15.50
  472. PROGRAM LEVEL                      .02  ESTIMATED LEVEL                    96   
  473. INTELLIGENCE CONTENT          74880.01  PROGRAMMING EFFORT              39243.30
  474. PROGRAMMING TIME               7848.66  LANGUAGE LEVEL                       .31
  475. DELIVERED ERRORS                  7.55  ESTIMATED ERRORS                     .26
  476.  
  477.  
  478. FUNCTION BODY OF SCANNERS.IS_SPACE AT LINE         274
  479.  
  480. UNIQUE OPERATORS                 11     UNIQUE OPERANDS                     4   
  481. TOTAL OPERATORS                  13     TOTAL OPERANDS                      5   
  482. VOCABULARY                       15                                             
  483. PROGRAM LENGTH                   18     ESTIMATED LENGTH                   46.05
  484. PROGRAM VOLUME                   69.50  POTENTIAL VOLUME                    8   
  485. PROGRAM LEVEL                      .12  ESTIMATED LEVEL                     3.64
  486. INTELLIGENCE CONTENT            252.72  PROGRAMMING EFFORT                603.73
  487. PROGRAMMING TIME                120.75  LANGUAGE LEVEL                       .92
  488. DELIVERED ERRORS                   .12  ESTIMATED ERRORS                     .02
  489.  
  490.  
  491. PACKAGE BODY OF SCANNERS AT LINE           1
  492.  
  493. UNIQUE OPERATORS                 22     UNIQUE OPERANDS                     1   
  494. TOTAL OPERATORS                  22     TOTAL OPERANDS                      1   
  495. VOCABULARY                       23                                             
  496. PROGRAM LENGTH                   23     ESTIMATED LENGTH                   98.10
  497. PROGRAM VOLUME                  104.03  POTENTIAL VOLUME                    4.75
  498. PROGRAM LEVEL                      .05  ESTIMATED LEVEL                      .09
  499. INTELLIGENCE CONTENT              9.46  PROGRAMMING EFFORT               2277.68
  500. PROGRAMMING TIME                455.54  LANGUAGE LEVEL                       .22
  501. DELIVERED ERRORS                   .44  ESTIMATED ERRORS                     .03
  502.  
  503.  
  504. ::::::::::::::
  505. scanners.spc
  506. ::::::::::::::
  507. package scanners is    --| Scan tokens from strings
  508.  
  509. --| Overview
  510. --| This package is used to break strings into tokens in a very simple
  511. --| but efficient manner.  For maximum efficiency, the scanner type
  512. --| is not private so that it can be used directly.  The following 
  513. --| conventions are adopted to allow the Ada string handling primitives
  514. --| to be used to maximum advantage:
  515. --|-
  516. --|  1. Strings are never copied.  The scanner type contains First and
  517. --|     Last components so that slices may be used to obtain the desired
  518. --|     tokens (substrings).
  519. --| 
  520. --|  2. The scanner type does not include a copy of the string being
  521. --|     scanned, also to avoid copying strings.
  522. --| 
  523. --|  3. The Length component of a scanner is always set to the length of the
  524. --|     item scanned.  If it is zero it means that no such item was found,
  525. --|     either because it wasn't there or because the scanner is exhausted.
  526. --|     The is_Empty operation may be used to determint if a scanner is
  527. --|     exhausted (usually before attempting to scan something).
  528. --| 
  529. --|  4. All operations have well defined behavior for any consistent input.
  530. --|     There are no exceptions declared in this package or raised directly
  531. --|     by the operations in the package.
  532. --|+
  533.  
  534.                   -- Types --
  535.  
  536. type scanner_type is 
  537.   record
  538.     Index: natural;    --| Index of next character to be scanned
  539.     Max_Index: natural;    --| Index of last scannable character
  540.     First: natural;    --| Index of first character of the result of a scan
  541.     Last: Natural;    --| Index of last character of the result of a scan
  542.     Length: Natural;    --| Length of the item scanned.
  543.   end record;
  544.  
  545. ------------------------------------------------------------------------
  546.  
  547. procedure start_Scanner(        --| Initialize a scanner
  548.     Scanner: in out Scanner_Type;    --| Scanner to be initialized
  549.     S: in string;            --| String to be scanned
  550.     Last: in natural            --| Last scannable character in S.
  551.     );
  552.  
  553. --| Effects:  Initialize Scanner for scanning S.  S and Last are
  554. --| typically obtained by calling text_io.Get_Line.  The first character
  555. --| scanned will be S'First and the last character scanned will be Last,
  556. --| which will generally be different from S'Last.
  557.  
  558. --| N/A: Requires, Modifies, Raises
  559.  
  560. ------------------------------------------------------------------------
  561.  
  562. function is_Empty(    --| Return False if Scanner can scan more characters
  563.     Scanner: in Scanner_Type
  564.     ) return boolean;
  565.  
  566. --| Effects: Return True iff Scanner.Index > Scanner.Max_Index.
  567. --| N/A: Requires, Modifies, Raises
  568.  
  569. ------------------------------------------------------------------------
  570.  
  571. function is_Alpha(    --| Check for alphabetic character
  572.     Scanner: in scanner_Type;
  573.     S: in string
  574.     ) return boolean;
  575.  
  576. --| Effects: Return True iff S(Scanner.Index) is an alphabetic character.
  577. --| Requires: Scanner must have been created on S using start start_Scanner
  578. --| prior to calling this routine.
  579.  
  580. --| N/A: Modifies, Raises
  581.  
  582. ------------------------------------------------------------------------
  583.  
  584. function is_Digit(    --| Check for start of  unsigned number
  585.     Scanner: in scanner_Type;
  586.     S: in string
  587.     ) return boolean;
  588.  
  589. --| Effects: Return True iff S(Scanner.Index) is a decimal digit.
  590. --| Requires: Scanner must have been created on S using start start_Scanner
  591. --| prior to calling this routine.
  592.  
  593. --| N/A: Modifies, Raises
  594.  
  595. ------------------------------------------------------------------------
  596.  
  597. function is_Sign(    --| Check for '+' or '-'
  598.     Scanner: in scanner_Type;
  599.     S: in string
  600.     ) return boolean;
  601.  
  602. --| Effects: Return True iff S(Scanner.Index) is '+' or '-'
  603. --| Requires: Scanner must have been created on S using start start_Scanner
  604. --| prior to calling this routine.
  605.  
  606. --| N/A: Modifies, Raises
  607.  
  608. ------------------------------------------------------------------------
  609.  
  610. function is_Digit_or_Sign(    --| Check for start of optionally signed number
  611.     Scanner: in scanner_Type;
  612.     S: in string
  613.     ) return boolean;
  614.  
  615. --| Effects: Return True iff S(Scanner.Index) is '+', '-', or a decimal digit.
  616. --| Requires: Scanner must have been created on S using start start_Scanner
  617. --| prior to calling this routine.
  618. --| N/A: Modifies, Raises
  619.  
  620. ------------------------------------------------------------------------
  621.  
  622. procedure skip_Blanks(    --| Skip leading blanks and tabs in S
  623.     Scanner: in out Scanner_Type;    --| Scanner to be updated
  624.     S: in string            --| String being scanned
  625.     );
  626.  
  627. --| Effects: Increment Scanner.Index until S(Scanner.Index) is neither a
  628. --| blank nor a tab character, or until it is greater than Scanner.Max_Index.
  629.  
  630. --| Requires: Scanner must have been created on S using start start_Scanner
  631. --| prior to calling this routine.
  632.  
  633. --| N/A: Modifies, Raises
  634.  
  635. ------------------------------------------------------------------------
  636.  
  637. procedure trim_blanks(
  638.     Scanner: in out Scanner_Type;
  639.     S: in string
  640.     );
  641.  
  642. --| Effects: Adjust Scanner.First and Scanner.Last such that 
  643. --| S(Scanner.First..Scanner.Last) contains neither leading nor trailing
  644. --| blanks or tabs.  Scanner.Length is adjusted accordingly.  This is
  645. --| useful to remove blanks after a call to scan_Delimited, Scan_Quoted,
  646. --| scan_Until, etc.
  647.  
  648. --| Requires: Scanner must have been created on S using start start_Scanner
  649. --| prior to calling this routine.
  650.  
  651. --| N/A: Modifies, Raises
  652.  
  653. ------------------------------------------------------------------------
  654.  
  655. procedure scan_Until(    --| Scan up to but not including character C
  656.     Scanner: in out Scanner_Type;
  657.     S: in string;
  658.     C: in character
  659.     );
  660.  
  661. --| Effects: Scan in string S starting at Scanner.Index until the character
  662. --| C is encountered or the string ends.  On return, if Scanner.Length > 0
  663. --| then S(Scanner.First..Scanner.Last) contains the characters that
  664. --| appeared before C and Scanner(Index) = C.  If C was not found, then
  665. --| the scanner is not affected except to set Scanner.Length to 0.
  666.  
  667. --| Requires: Scanner must have been created on S using start start_Scanner
  668. --| prior to calling this routine.
  669.  
  670. --| N/A: Modifies, Raises
  671.  
  672. ------------------------------------------------------------------------
  673.  
  674. procedure scan_Word(    --| Scan past a sequence of non-blank characters
  675.     Scanner: in out Scanner_Type;
  676.     S: in string
  677.     );
  678.  
  679. --| Effects: Scan in string S for a sequence of non-blank characters,
  680. --| starting at Scanner.Index.  On return, if Scanner.Length > 0
  681. --| then S(Scanner.First..Scanner.Last) is a word and Scanner.Index is 
  682. --| just past the end of the word (Scanner.Last+1), ready to scan the next
  683. --| item.  
  684.  
  685. --| Requires: Scanner must have been created on S using start start_Scanner
  686. --| prior to calling this routine.  The scanner must be at a non blank
  687. --| character (the beginning of a word) or nothing will be scanned.
  688.  
  689. --| N/A: Modifies, Raises
  690.  
  691. ------------------------------------------------------------------------
  692.  
  693. procedure scan_Number(
  694.     Scanner: in out scanner_Type;
  695.     S: in string
  696.     );
  697.  
  698. --| Effects: Scan in string S for a sequence of numeric characters,
  699. --| optionally preceeded by a sign (+/-), starting at Scanner.Index.  On
  700. --| return, if Scanner.Length > 0 then S(Scanner.First..Scanner.Last) is a
  701. --| number and Scanner.Index is just past the end of the number
  702. --| (Scanner.Last+1), ready to scan the next item.
  703.  
  704. --| Requires: Scanner must have been created on S using start start_Scanner
  705. --| prior to calling this routine.  Scanner must be positioned at a digit
  706. --| or sign (+/-) when this routine is called or nothing will be scanned.
  707.  
  708. --| N/A: Modifies, Raises
  709.  
  710. ------------------------------------------------------------------------
  711.  
  712. procedure scan_Delimited(    --| Scan string delimited by a single character
  713.     Scanner: in out scanner_Type;
  714.     S: in string
  715.     );
  716.  
  717. --| Effects: The character S(Scanner.Index) is considered a "quote".  
  718. --| Scanner.First is set to the Scanner.Index+1, and Scanner.Index is 
  719. --| incremented until another "quote" is encountered or the end of the
  720. --| string is reached.  On return, Scanner.Last is the index of the closing
  721. --| "quote" or the last character in S if no closing "quote" was found.
  722.  
  723. --| Requires: Scanner must have been created on S using start start_Scanner
  724. --| prior to calling this routine.
  725. --| N/A: Modifies, Raises
  726.  
  727. ------------------------------------------------------------------------
  728.  
  729. procedure scan_Quoted(    --| Scan quoted string
  730.     Scanner: in out scanner_Type;
  731.     S: in out string
  732.     );
  733.  
  734. --| Effects: The character S(Scanner.Index) is considered a "quote".  
  735. --| The string S is scanned for a closing "quote".  During the scan,
  736. --| two quotes in a row are replaced by a single quote.  On return,
  737. --| Scanner.First is the first character of the quoted string, and
  738. --| Scanner.Last is the last character.  (The outermost quotes are
  739. --| not included.)  Scanner.Index is the first character after the
  740. --| closing quote, Scanner.Length is the number of characters in the
  741. --| quoted string.  Note that the string being scanned (S) is modified
  742. --| by this routine (to remove the extra quotes, if any).
  743.  
  744. --| Requires: Scanner must have been created on S using start start_Scanner
  745. --| prior to calling this routine.
  746.  
  747. --| N/A: Modifies, Raises
  748.  
  749. ------------------------------------------------------------------------
  750.  
  751. end scanners;
  752.