home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ucsdibmpc.zip / parser.text < prev    next >
Text File  |  1984-05-23  |  11KB  |  355 lines

  1. (*$S+*)
  2. unit parser;
  3.  
  4. INTERFACE
  5.  
  6. uses {$U kermglob.code} kermglob;
  7.  
  8.  
  9.    function parse: statustype;
  10.  
  11.    procedure initvocab;
  12.  
  13.  
  14. IMPLEMENTATION
  15.  
  16. uses
  17.    {$U kermutil.code} kermutil;
  18.  
  19.  
  20. procedure eatspaces(var s: string255);
  21.  
  22. var done: boolean;
  23.     i: integer;
  24.  
  25.   begin
  26.     done := (length(s) = 0);
  27.     while not done do
  28.       begin
  29.         if s[1] = ' ' then
  30.           begin
  31.             i := length(s) - 1;
  32.             s := copy(s,2,i);
  33.             done := length(s) = 0
  34.           end (* if *)
  35.         else
  36.             done := true
  37.       end (* while *)
  38.   end; (* eatspaces *)
  39.  
  40. procedure isolate_word(var line, s: string255);
  41.  
  42. var i: integer;
  43.     done: boolean;
  44.  
  45.   begin
  46.     done := false;
  47.     i := 1;
  48.     s := copy(' ',0,0);
  49.     while (i <= length(line)) and not done do
  50.       begin
  51.         if line[i] = ' ' then
  52.             done := true
  53.         else
  54.             s := concat(s,copy(line,i,1));
  55.         i := i + 1;
  56.       end; (* while *)
  57.     line := copy(line,i,length(line)-i+1);
  58.   end; (* isolate_word *)
  59.  
  60. function get_fn(var line, fn: string255): boolean;
  61.  
  62. var i, l: integer;
  63.  
  64.   begin
  65.     get_fn := true;
  66.     isolate_word(line, fn);
  67.     l := length(fn);
  68. (* Watch out, the set below had an ASCII null (0) in quotes as its 5th *)
  69. (* member, between '_' and '/'.  The null character has been deleted to *)
  70. (* allow tape and network distribution of this program. *)
  71.     if (l > 15) or (l < 1) then
  72.         get_fn := false
  73.     else
  74.         for i := 1 to l do
  75.             if not (fn[i] in ['0'..'9','A'..'Z', '-', '_', '', '/', '.']) then
  76.                 get_fn := false
  77.   end; (* get_fn *)
  78.  
  79. function get_num( var line: string255; var n: integer ): boolean;
  80.  
  81. var
  82.    numstr: string255;
  83.    i, l: integer;
  84. begin
  85.    get_num := true;
  86.    isolate_word( line, numstr );
  87.    l := length(numstr);
  88.    if (l>5) or (l<1) then begin
  89.       n := 0;
  90.       get_num := false
  91.    end
  92.    else begin
  93.       n := 0; i := 1;
  94.       numstr := concat( numstr, ' ' );
  95.       while (numstr[i] in ['0'..'9']) do begin
  96.          if n<(maxint div 10) then
  97.             n := n*10 + ord( numstr[i] ) - ord( '0' );
  98.          i := i + 1
  99.       end
  100.    end
  101. end; { get_num }
  102.  
  103. function nextch(var ch: char): boolean;
  104.  
  105. var s: string255;
  106.  
  107.   begin
  108.     isolate_word(line,s);
  109.     if length(s) <> 1 then
  110.         nextch := false
  111.     else
  112.       begin
  113.         ch := s[1];
  114.         nextch := true
  115.       end (* else *)
  116.   end; (* nextch *)
  117.  
  118. function parse(*: statustype*);
  119.  
  120. type states = (start, fin, get_filename, get_set_parm, get_parity, get_on_off,
  121.                get_char, get_show_parm, get_help_show, get_help_parm,
  122.                exitstate, get_baud);
  123.  
  124. var status: statustype;
  125.     word: vocab;
  126.     state: states;
  127.  
  128. function get_sym(var word: vocab): statustype;
  129.  
  130. var i: vocab;
  131.     s: string255;
  132.     stat: statustype;
  133.     done: boolean;
  134.     matches: integer;
  135.  
  136.   begin
  137.     eat_spaces(line);
  138.     if length(line) = 0 then
  139.         getsym := ateol
  140.     else
  141.       begin
  142.         stat := null;
  143.         done := false;
  144.         isolate_word(line,s);
  145.         i := allsym;
  146.         matches := 0;
  147.         repeat
  148.             if (pos(s,vocablist[i]) = 1) and (i in expected) then
  149.               begin
  150.                 matches := matches + 1;
  151.                 word := i
  152.               end
  153.             else if (s[1] < vocablist[i,1]) then
  154.                 done := true;
  155.             if (i = spacesym) then
  156.                 done := true
  157.             else
  158.                 i := succ(i)
  159.         until (matches > 1) or done;
  160.         if matches > 1 then
  161.             stat := ambiguous
  162.         else if (matches = 0) then
  163.             stat := unrec;
  164.         getsym := stat
  165.       end (* else *)
  166.   end; (* getsym *)
  167.  
  168.   begin
  169.     state := start;
  170.     parse := null;
  171.     noun := nullsym;
  172.     verb := nullsym;
  173.     adj := nullsym;
  174.     uppercase(line);
  175.     repeat
  176.         case state of
  177.           start:
  178.               begin
  179.                 expected := [consym, exitsym, helpsym, quitsym, recsym, sendsym,
  180.                              setsym, showsym];
  181.                 status := getsym(verb);
  182.                 if status = ateol then
  183.                   begin
  184.                     parse := null;
  185.                     exit(parse)
  186.                   end (* if *)
  187.                 else if (status <> unrec) and (status <>  ambiguous) then
  188.                     case verb of
  189.                       consym: state := fin;
  190.                       exitsym, quitsym: state := fin;
  191.                       helpsym: state := get_help_parm;
  192.                       recsym: state := fin;
  193.                       sendsym: state := getfilename;
  194.                       setsym: state := get_set_parm;
  195.                       showsym: state := get_show_parm;
  196.                     end (* case *)
  197.               end; (* case start *)
  198.           fin:
  199.               begin
  200.                 expected := [];
  201.                 status := getsym(verb);
  202.                 if status = ateol then
  203.                   begin
  204.                     parse := null;
  205.                     exit(parse)
  206.                   end (* if status *)
  207.                 else
  208.                     status := unconfirmed
  209.               end; (* case fin *)
  210.           getfilename:
  211.             begin
  212.               expected := [];
  213.               if getfn(line,xfilename) then
  214.                 begin
  215.                   status := null;
  216.                   state := fin
  217.                 end (* if *)
  218.               else
  219.                   status := fnexpected
  220.             end; (* case get file name *)
  221.           get_set_parm:
  222.               begin
  223.                 expected := [paritysym, localsym, ibmsym, emulatesym, escsym,
  224.                              debugsym, filewarnsym, baudsym];
  225.                 status := getsym(noun);
  226.                 if status = ateol then
  227.                     status := parm_expected
  228.                 else if (status <> unrec) and (status <>  ambiguous) then
  229.                     case noun of
  230.                       paritysym: state := get_parity;
  231.                       localsym: state := get_on_off;
  232.                       ibmsym: state := get_on_off;
  233.                       emulatesym: state := get_on_off;
  234.                       escsym: state := getchar;
  235.                       debugsym: state := get_on_off;
  236.                       filewarnsym: state := get_on_off;
  237.                       baudsym: state := get_baud
  238.                     end (* case *)
  239.             end; (* case get_set_parm *)
  240.           get_parity:
  241.               begin
  242.                 expected := [marksym, spacesym, nonesym, evensym, oddsym];
  243.                 status := getsym(adj);
  244.                 if status = ateol then
  245.                     status := parm_expected
  246.                 else if (status <> unrec) and (status <> ambiguous) then
  247.                     state := fin
  248.               end; (* case get_parity  *)
  249.           get_baud:
  250.              begin
  251.                expected := [];
  252.                if get_num( line, newbaud ) then begin
  253.                   status := null; state := fin
  254.                end
  255.                else begin
  256.                   newbaud := 0;
  257.                   status := parm_expected
  258.                end
  259.              end; (* case get_baud *)
  260.           get_on_off:
  261.               begin
  262.                 expected := [onsym, offsym];
  263.                 status := getsym(adj);
  264.                 if status = ateol then
  265.                     status := parm_expected
  266.                 else if (status <> unrec) and (status <> ambiguous) then
  267.                     state := fin
  268.               end; (* get_on_off *)
  269.           get_char:
  270.               if nextch(newescchar) then
  271.                  state := fin
  272.               else
  273.                  status := ch_expected;
  274.           get_show_parm:
  275.               begin
  276.                 expected := [allsym, paritysym, localsym, ibmsym, escsym,
  277.                              debugsym, filewarnsym, baudsym];
  278.                 status := getsym(noun);
  279.                 if status = ateol then
  280.                     status := parm_expected
  281.                 else if (status <> unrec) and (status <>  ambiguous) then
  282.                     state := fin
  283.               end; (* case get_show_parm *)
  284.           get_help_show:
  285.               begin
  286.                 expected := [paritysym, localsym, ibmsym, escsym,
  287.                            debugsym, filewarnsym, baudsym, emulatesym];
  288.                 status := getsym(adj);
  289.                 if (status = at_eol) then
  290.                   begin
  291.                     status := null;
  292.                     state := fin
  293.                   end
  294.                 else if (status <> unrec) and (status <>  ambiguous) then
  295.                     state := fin
  296.               end; (* case get_help_show *)
  297.           get_help_parm:
  298.               begin
  299.                 expected := [consym, exitsym, helpsym, quitsym, recsym,
  300.                              sendsym, setsym, showsym];
  301.                 status := getsym(noun);
  302.                 if status = ateol then
  303.                   begin
  304.                     parse := null;
  305.                     exit(parse)
  306.                   end;
  307.                 if (status <> unrec) and (status <>  ambiguous) then
  308.                     case noun of
  309.                       consym: state := fin;
  310.                       sendsym: state := fin;
  311.                       recsym: state := fin;
  312.                       setsym: state := get_help_show;
  313.                       showsym: state := fin;
  314.                       helpsym: state := fin;
  315.                       exitsym, quitsym: state := fin;
  316.                     end (* case *)
  317.               end; (* case get_help_show *)
  318.         end (* case *)
  319.     until (status <> null);
  320.     parse := status
  321.   end; (* parse *)
  322.  
  323. procedure initvocab;
  324.  
  325. var i: integer;
  326.  
  327.   begin
  328.     vocablist[allsym] := 'ALL';
  329.     vocablist[baudsym] := 'BAUD';
  330.     vocablist[consym] := 'CONNECT';
  331.     vocablist[debugsym] := 'DEBUG';
  332.     vocablist[emulatesym] := 'EMULATE';
  333.     vocablist[escsym] := 'ESCAPE';
  334.     vocablist[evensym] := 'EVEN';
  335.     vocablist[exitsym] := 'EXIT';
  336.     vocablist[filewarnsym] := 'FILE-WARNING';
  337.     vocablist[helpsym] := 'HELP';
  338.     vocablist[ibmsym] := 'IBM';
  339.     vocablist[localsym] := 'LOCAL-ECHO';
  340.     vocablist[marksym] := 'MARK';
  341.     vocablist[nonesym] := 'NONE';
  342.     vocablist[oddsym] := 'ODD';
  343.     vocablist[offsym] := 'OFF';
  344.     vocablist[onsym] := 'ON';
  345.     vocablist[paritysym] := 'PARITY';
  346.     vocablist[quitsym] := 'QUIT';
  347.     vocablist[recsym] := 'RECEIVE';
  348.     vocablist[sendsym] := 'SEND';
  349.     vocablist[setsym] := 'SET';
  350.     vocablist[showsym] := 'SHOW';
  351.     vocablist[spacesym] := 'SPACE';
  352.   end; (* initvocab *)
  353.  
  354.   end. (* end of unit *)
  355.