cref.p
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:11k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. $debug$
  2. $ sysprog, partial_eval $
  3. program crefprog(input, output);
  4. const
  5.  {  linesperpage = 139;  }
  6.    maxnamelen = 30;
  7. type
  8.    str255 = string[255];
  9.    occurptr = ^occur;
  10.    occur =
  11.       record
  12.          next : occurptr;
  13.          lnum : integer;
  14.          fnum : integer;
  15.          defn : boolean;
  16.       end;
  17.    kinds = (k_normal, k_proc, k_var, k_const, k_type, k_strlit, k_extproc,
  18.             k_kw, k_prockw, k_varkw, k_constkw, k_typekw, k_beginkw);
  19.    nodeptr = ^node;
  20.    node =
  21.       record
  22.          left, right : nodeptr;
  23.          name : string[maxnamelen];
  24.          first : occurptr;
  25.          kind : kinds;
  26.       end;
  27. var
  28.    f : text;
  29.    fn : string[120];
  30.    fnum : integer;
  31.    buf, name : str255;
  32.    good : boolean;
  33.    i, j : integer;
  34.    lnum : integer;
  35.    np, base : nodeptr;
  36.    op : occurptr;
  37.    curkind, section : kinds;
  38.    paren : integer;
  39.    brace : integer;
  40. procedure lookup(var name : str255; var np : nodeptr);
  41.    var
  42.       npp : ^nodeptr;
  43.    begin
  44.       if strlen(name) > maxnamelen then
  45.          setstrlen(name, maxnamelen);
  46.       npp := addr(base);
  47.       while (npp^ <> nil) and (npp^^.name <> name) do
  48.          begin
  49.             if name < npp^^.name then
  50.                npp := addr(npp^^.left)
  51.             else
  52.                npp := addr(npp^^.right);
  53.          end;
  54.       if (npp^ = nil) then
  55.          begin
  56.             new(np);
  57.             npp^ := np;
  58.             np^.name := name;
  59.             np^.first := nil;
  60.             np^.left := nil;
  61.             np^.right := nil;
  62.             np^.kind := k_normal;
  63.          end
  64.       else
  65.          np := npp^;
  66.    end;
  67. procedure kw(name : str255; kind : kinds);
  68.    var
  69.       np : nodeptr;
  70.    begin
  71.       lookup(name, np);
  72.       np^.kind := kind;
  73.    end;
  74. procedure cref(np : nodeptr; kind : kinds);
  75.    var
  76.       op : occurptr;
  77.    begin
  78.       new(op);
  79.       op^.next := np^.first;
  80.       np^.first := op;
  81.       op^.lnum := lnum;
  82.       op^.fnum := fnum;
  83.       op^.defn := (kind in [k_var, k_type, k_const, k_proc]);
  84.       if op^.defn or (kind = k_strlit) or
  85.          ((kind = k_extproc) and (np^.kind = k_normal)) then
  86.          np^.kind := kind;
  87.    end;
  88. procedure traverse(np : nodeptr);
  89.    var
  90.       op : occurptr;
  91.       i : integer;
  92.    begin
  93.       if (np <> nil) then
  94.          begin
  95.             traverse(np^.left);
  96.             if np^.kind < k_kw then
  97.                begin
  98.                   case np^.kind of
  99.                      k_var:
  100.                         write(f, 'V:');
  101.                      k_type:
  102.                         write(f, 'T:');
  103.                      k_const:
  104.                         write(f, 'C:');
  105.                      k_proc:
  106.                         write(f, 'P:');
  107.                      k_strlit:
  108.                         write(f, 'S:');
  109.                      k_extproc:
  110.                         write(f, 'E:');
  111.                      k_normal:
  112.                         write(f, 'X:');
  113.                   end;
  114.                   write(f, np^.name);
  115.                   i := 0;
  116.                   op := np^.first;
  117.                   while op <> nil do
  118.                      begin
  119.                         if i = 0 then
  120.                            begin
  121.                               writeln(f);
  122.                               write(f, '   ');
  123.                               i := 5;
  124.                            end;
  125.                         write(f, ' ', op^.lnum:1, '/', op^.fnum:1);
  126.                         if op^.defn then
  127.                            write(f, '*');
  128.                         i := i - 1;
  129.                         op := op^.next;
  130.                      end;
  131.                   writeln(f);
  132.                end;
  133.             traverse(np^.right);
  134.          end;
  135.    end;
  136. begin
  137.    base := nil;
  138.    fnum := 0;
  139.    kw('procedure', k_prockw);
  140.    kw('function', k_prockw);
  141.    kw('var', k_varkw);
  142.    kw('record', k_varkw);
  143.    kw('type', k_typekw);
  144.    kw('const', k_constkw);
  145.    kw('begin', k_beginkw);
  146.    kw('end', k_kw);
  147.    kw('do', k_kw);
  148.    kw('for', k_kw);
  149.    kw('to', k_kw);
  150.    kw('while', k_kw);
  151.    kw('repeat', k_kw);
  152.    kw('until', k_kw);
  153.    kw('if', k_kw);
  154.    kw('then', k_kw);
  155.    kw('else', k_kw);
  156.    kw('case', k_kw);
  157.    kw('of', k_kw);
  158.    kw('div', k_kw);
  159.    kw('mod', k_kw);
  160.    kw('nil', k_kw);
  161.    kw('not', k_kw);
  162.    kw('and', k_kw);
  163.    kw('or', k_kw);
  164.    kw('with', k_kw);
  165.    kw('array', k_kw);
  166.    kw('integer', k_kw);
  167.    kw('char', k_kw);
  168.    kw('boolean', k_kw);
  169.    kw('true', k_kw);
  170.    kw('false', k_kw);
  171.    writeln;
  172.    writeln('Pascal Cross Reference Utility');
  173.    writeln;
  174.    repeat
  175.       fnum := fnum + 1;
  176.       write('Name of cross-reference file #', fnum:1, '? ');
  177.       readln(fn);
  178.       good := true;
  179.       if (fn <> '') then
  180.          begin
  181.             try
  182.                reset(f, fn);
  183.             recover
  184.                if escapecode <> -10 then
  185.                   escape(escapecode)
  186.                else
  187.                   begin
  188.                      good := false;
  189.                      writeln('Can''t read file!');
  190.                   end;
  191.          end
  192.       else
  193.          good := false;
  194.       if good then
  195.          begin
  196.             lnum := 0;
  197.             section := k_normal;
  198.             curkind := k_normal;
  199.             paren := 0;
  200.             while not eof(f) do
  201.                begin
  202.                   lnum := lnum + 1;
  203.                   readln(f, buf);
  204.                   strappend(buf, #0);
  205.                   i := 1;
  206.                   while (buf[i] = ' ') do
  207.                      i := i + 1;
  208.                   repeat
  209.                      while not (buf[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_', #0]) do
  210.                         begin
  211.                            case buf[i] of
  212.                               ':', '=':
  213.                                  if brace = 0 then
  214.                                     curkind := k_normal;
  215.                               ';':
  216.                                  if brace = 0 then
  217.                                     curkind := section;
  218.                               '''':
  219.                                  if brace = 0 then
  220.                                     begin
  221.                                        i := i + 1;
  222.                                        j := i;
  223.                                        while ((buf[i] <> '''') or (buf[i+1] = '''')) and
  224.                                              (buf[i] <> #0) do
  225.                                           begin
  226.                                              if (buf[i] = '''') then
  227.                                                 i := i + 2
  228.                                              else
  229.                                                 i := i + 1;
  230.                                           end;
  231.                                        if (buf[i] = #0) then
  232.                                           i := i - 1;
  233.                                        name := '''' + str(buf, j, i-j) + '''';
  234.                                        lookup(name, np);
  235.                                        cref(np, k_strlit);
  236.                                     end;
  237.                               '(':
  238.                                  if brace = 0 then
  239.                                     if (buf[i+1] = '*') then
  240.                                        begin
  241.                                           brace := 1;
  242.                                           i := i + 1;
  243.                                        end
  244.                                     else
  245.                                        begin
  246.                                           paren := paren + 1;
  247.                                           curkind := k_normal;
  248.                                        end;
  249.                               ')':
  250.                                  if brace = 0 then
  251.                                     paren := paren - 1;
  252.                               '*':
  253.                                  if (buf[i+1] = ')') then
  254.                                     begin
  255.                                        brace := 0;
  256.                                        i := i + 1;
  257.                                     end;
  258.                               '{': brace := 1;
  259.                               '}': brace := 0;
  260.                               otherwise ;
  261.                            end;
  262.                            i := i + 1;
  263.                         end;
  264.                      if (buf[i] <> #0) then
  265.                         begin
  266.                            j := i;
  267.                            if (buf[i] in ['0'..'9']) and (i > 1) and (buf[i-1] = '-') then
  268.                               j := j - 1;
  269.                            while (buf[i] in ['a'..'z', 'A'..'Z', '0'..'9', '_']) do
  270.                               i := i + 1;
  271.                            if brace = 0 then
  272.                               begin
  273.                                  name := str(buf, j, i-j);
  274.                                  for j := 1 to strlen(name) do
  275.                                     if (buf[j] in ['A'..'Z']) then
  276.                                        buf[j] := chr(ord(buf[j]) + 32);
  277.                                  while (buf[i] = ' ') do
  278.                                     i := i + 1;
  279.                                  lookup(name, np);
  280.                                  case np^.kind of
  281.                                     k_varkw:
  282.                                        if paren = 0 then
  283.                                           begin
  284.                                              section := k_var;
  285.                                              curkind := section;
  286.                                           end;
  287.                                     k_typekw:
  288.                                        begin
  289.                                           section := k_type;
  290.                                           curkind := section;
  291.                                        end;
  292.                                     k_constkw:
  293.                                        begin
  294.                                           section := k_const;
  295.                                           curkind := section;
  296.                                        end;
  297.                                     k_prockw:
  298.                                        begin
  299.                                           section := k_normal;
  300.                                           curkind := k_proc;
  301.                                        end;
  302.                                     k_beginkw:
  303.                                        begin
  304.                                           section := k_normal;
  305.                                           curkind := k_normal;
  306.                                        end;
  307.                                     k_kw: ;
  308.                                     otherwise
  309.                                        if (curkind = k_normal) and (buf[i] = '(') then
  310.                                           cref(np, k_extproc)
  311.                                        else
  312.                                           cref(np, curkind);
  313.                                  end;
  314.                               end;
  315.                         end;
  316.                   until buf[i] = #0;
  317.                end;
  318.             if paren <> 0 then
  319.                writeln('Warning: ending paren count = ', paren:1);
  320.             close(f);
  321.          end;
  322.    until fn = '';
  323.    writeln;
  324.    repeat
  325.       write('Output file name: ');
  326.       readln(fn);
  327.    until fn <> '';
  328.    rewrite(f, fn);
  329.    traverse(base);
  330.    close(f, 'save');
  331. end.