Problem B
Pascal Program Profile

Pascal is a fairly straightforward block structured language. The key control structures in "simplified" Pascal programs and their forms are shown below with a structure number for each.

program ...      procedure ...     function ...       for ... do
  declarations     declarations      declarations       stmt
begin            begin             begin                      4
  statements       statements        statements
end.         1   end;         2    end;         3	

while ... do     repeat            if ... then   stmt    else    stmt
  stmt             statements                     7                8
          5      until ...    6

where "stmt" in each form may be a simple statement or a compound statement. Compound statements have the form:

    begin
      statements
    end

The word "begin" immediately follows the "do", "then" or "else". The "repeat ... until" does not need "begin" and "end" around the statements.

The rules for nesting these structures are that 1) procedures and functions may be nested within the declaration areas of each other or within the declarations of a program; and 2) other forms may be nested arbitrarily wherever the components "statements" and "stmt" appear. In this "simplified" Pascal, "case" statements, "with" statements, and variant record forms are not allowed.

Write a program that can analyze a "simplified" Pascal program and output a control structure profile - a sequence of structure numbers and letters that captures the essential form of the Pascal program. Output the structure number when the structure is recognized and the letter 'B' if a "begin" is found at its start (always output a 'B' for the "repeat" structure). If an "end" is found to match the "begin", output the structure number and the letter "E" (with "until" treated like an "end"). On the back is a sample Pascal program from SEEWORD.PAS; its profile is 1 2B 4B 4E 2EB 5B 4 7B 7E 8 5E 1E Notice the displaced 'B' for the program, because of the nested procedure in the program. Also, note the 4 in the middle, showing a "for" with no begin or end. Although not shown here, you have a second file SIMULATE.PAS which has the profile

1 2B 4B 4E 2E 2B 7 8B 8E 2E 2 3B 4 7B 7E 3EB 2E 2B 7 7B 7 7E 2E 2B 7 7 2E 2B 4B
 5B 7B 7E 5E 5B 5E 4E 2E 2B 2EB 6B 7B 7E 8 7B 7 8 7E 8 7B 7E 8 6E 1E

To eliminate possible complications, you may assume that the Pascal programs have NO comments, that NONE of the keywords appear in any strings but always have the control meaning suggested above, that all keywords are in lowercase, and that the program is syntactically correct. Each keyword appears only surrounded by white space, except for "end" which may appear as "end" or "end;" or "end." Finally, there is one place where "end;" appears in which it must be ignored - in record declarations. Naturally, records may be nested like all other structures in Pascal; but they are data structures, not control structures, and are not to be part of the profile. Records appear as

  	
   record
     field declarations
   end;

Sample program

program seeword (input, inf, output, outf);
type
        eight = packed array [1..8] of char;
        rec = packed record
           cs:     packed array [1..4] of char;
           num:    longint;
        end;
var
    inf:     file of rec;
    outf:    text;
    one:     rec;
    name, 
    outname:    string[30];
    j:      integer;
    hex:    eight;
procedure makehex (num: longint; var s: eight);
var
   digits: 	packed array [0..15] of char;
   j, k, d:	integer;
begin
   digits := '0123456789ABCDEF';
   for k := 8 downto 1 do
   begin
        d := num mod 16;
        s[k] := digits[d];
        num := num div 16;
   end;
end;
begin
    write ('Enter file name: ');
    readln (name);
    assign (inf, name);
    reset (inf);
    write ('Enter display file name: ');
    readln (outname);
    assign (outf, outname);
    rewrite (outf);
    while not eof (inf) do
    begin
        read (inf, one);
        makehex (one.num, hex);
        write (outf, hex, '   ');
        for j := 1 to 4 do
            if (ord(one.cs[j]) > 30) and (ord(one.cs[j]) < 128) then
            begin
                write (outf, one.cs[j]);
            end
            else  write (outf, '.');
        writeln (outf);
    end;
    close (inf);    close (outf);
end.