home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pub / ucsdterak / parser.text < prev    next >
Text File  |  2020-01-01  |  10KB  |  327 lines

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