home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / ucsdpecan / parser.text < prev    next >
Text File  |  1990-08-04  |  14KB  |  429 lines

  1. (*$S+*)
  2. unit parser;
  3.  
  4. INTERFACE
  5.  
  6. uses {$U kermglob.code} kermglob;
  7.  
  8. {Change log:
  9. 13 May 89, V1.1: Fixed several bugs in parsing of HELP commands   RTC
  10. 13 May 89, V1.1: Added parsing for COMMENT command
  11. 30 Apr 89, V1.1: Added parsing for SET INTERFACE command   RTC
  12. 26 Apr 89, V1.1: minor cleanups   RTC
  13. 16 Apr 89, V1.1: Added BYE & FINISH command parsing       RTC
  14. 14 Apr 89, V1.1: Added parsing for GET, PUT & SHOW VERSION commands   RTC
  15. 13 Apr 89, V1.1: Added Version message       RTC
  16. 14 Aug 88: Added parsing for LOG, CLOSE, and SET SYSTEM commands   RTC
  17. 02 Jul 88: Added -NAMES, -TYPE, TAKE command parsing   RTC
  18.  
  19. }
  20.  
  21.    function parse: statustype;
  22.  
  23.    procedure initvocab;
  24.  
  25.    procedure par_version;
  26.  
  27.  
  28. IMPLEMENTATION
  29.  
  30. uses
  31.    {$U kermutil.code} kermutil;
  32.  
  33. const
  34.   my_version = '   Parser Unit V1.1, 13 May 89';
  35.  
  36.  
  37. procedure eatspaces(var s: string255);
  38.  
  39. var done: boolean;
  40.     i: integer;
  41.  
  42.   begin
  43.     done := (length(s) = 0);
  44.     while not done do
  45.       begin
  46.         if s[1] = ' ' then
  47.           begin
  48.             i := length(s) - 1;
  49.             s := copy(s,2,i);
  50.             done := length(s) = 0
  51.           end (* if *)
  52.         else
  53.             done := true
  54.       end (* while *)
  55.   end; (* eatspaces *)
  56.  
  57. procedure isolate_word(var line, s: string255);
  58.  
  59. var i: integer;
  60.     done: boolean;
  61.  
  62.   begin
  63.     done := false;
  64.     i := 1;
  65.     s := copy(' ',0,0);
  66.     while (i <= length(line)) and not done do
  67.       begin
  68.         if line[i] = ' ' then
  69.             done := true
  70.         else
  71.             s := concat(s,copy(line,i,1));
  72.         i := i + 1;
  73.       end; (* while *)
  74.     line := copy(line,i,length(line)-i+1);
  75.   end; (* isolate_word *)
  76.  
  77. function get_fn(var line, fn: string255): boolean;
  78.  
  79. var i, l: integer;
  80.  
  81.   begin
  82.     get_fn := true;
  83.     isolate_word(line, fn);
  84.     l := length(fn);
  85.     if (l < 1) then
  86.         get_fn := false
  87.   end; (* get_fn *)
  88.  
  89. function get_num( var line: string255; var n: integer ): boolean;
  90.  
  91. var
  92.    numstr: string255;
  93.    i, l: integer;
  94. begin
  95.    get_num := true;
  96.    isolate_word( line, numstr );
  97.    l := length(numstr);
  98.    if (l>5) or (l<1) then begin
  99.       n := 0;
  100.       get_num := false
  101.    end
  102.    else begin
  103.       n := 0; i := 1;
  104.       numstr := concat( numstr, ' ' );
  105.       while (numstr[i] in ['0'..'9']) do begin
  106.          if n<(maxint div 10) then
  107.             n := n*10 + ord( numstr[i] ) - ord( '0' );
  108.          i := i + 1
  109.       end
  110.    end
  111. end; { get_num }
  112.  
  113. function nextch(var ch: char): boolean;
  114.  
  115. var s: string255;
  116.  
  117.   begin
  118.     isolate_word(line,s);
  119.     if length(s) <> 1 then
  120.         nextch := false
  121.     else
  122.       begin
  123.         ch := s[1];
  124.         nextch := true
  125.       end (* else *)
  126.   end; (* nextch *)
  127.  
  128. function parse(*: statustype*);
  129.  
  130. type states = (start, fin, get_filename, get_set_parm, get_parity,
  131.                get_on_off, get_f_type, get_char, get_show_parm,
  132.                get_help_show, get_int_type, get_naming, get_help_parm,
  133.                exitstate, get_baud, get_line, get_log_parm, get_help_log);
  134.  
  135. var status: statustype;
  136.     word: vocab;
  137.     state: states;
  138.  
  139. function get_a_sym(var word: vocab): statustype;
  140.  
  141. var i: vocab;
  142.     s: string255;
  143.     stat: statustype;
  144.     done: boolean;
  145.     matches: integer;
  146.  
  147.   begin
  148.     eat_spaces(line);
  149.     if length(line) = 0 then
  150.         get_a_sym := ateol
  151.     else
  152.       begin
  153.         stat := null;
  154.         done := false;
  155.         isolate_word(line,s);
  156.         i := allsym;
  157.         matches := 0;
  158.         repeat
  159.             if (pos(s,vocablist[i]) = 1) and (i in expected) then
  160.               begin
  161.                 matches := matches + 1;
  162.                 word := i
  163.               end
  164.             else if (s[1] < vocablist[i,1]) then
  165.                 done := true;
  166.             if (i = versionsym) then
  167.                 done := true
  168.             else
  169.                 i := succ(i)
  170.         until (matches > 1) or done;
  171.         if matches > 1 then
  172.             stat := ambiguous
  173.         else if (matches = 0) then
  174.             stat := unrec;
  175.         get_a_sym := stat
  176.       end (* else *)
  177.   end; (* get_a_sym *)
  178.  
  179.   begin
  180.     state := start;
  181.     parse := null;
  182.     noun := nullsym;
  183.     verb := nullsym;
  184.     adj := nullsym;
  185.     uppercase(line);
  186.     repeat
  187.         case state of
  188.           start:
  189.               begin
  190.                 expected := [comsym, consym, exitsym, helpsym, quitsym,
  191.                              logsym, closesym, getsym, putsym, byesym, finsym,
  192.                              recsym, sendsym, setsym, showsym, takesym];
  193.                 status := get_a_sym(verb);
  194.                 if status = ateol then
  195.                   begin
  196.                     parse := null;
  197.                     exit(parse)
  198.                   end (* if *)
  199.                 else if (status <> unrec) and (status <>  ambiguous) then
  200.                     case verb of
  201.                       comsym: state := get_line;
  202.                       consym, exitsym, quitsym,
  203.                       byesym, finsym, recsym: state := fin;
  204.                       getsym, putsym,
  205.                       sendsym, takesym: state := getfilename;
  206.                       helpsym: state := get_help_parm;
  207.                       logsym, closesym: state := get_log_param;
  208.                       setsym: state := get_set_parm;
  209.                       showsym: state := get_show_parm;
  210.                     end (* case *)
  211.               end; (* case start *)
  212.           fin:
  213.               begin
  214.                 expected := [];
  215.                 status := get_a_sym(verb);
  216.                 if status = ateol then
  217.                   begin
  218.                     parse := null;
  219.                     exit(parse)
  220.                   end (* if status *)
  221.                 else
  222.                     status := unconfirmed
  223.               end; (* case fin *)
  224.           getfilename:
  225.             begin
  226.               expected := [];
  227.               if getfn(line,xfilename) then
  228.                 begin
  229.                   status := null;
  230.                   state := fin
  231.                 end (* if *)
  232.               else
  233.                   status := fnexpected
  234.             end; (* case get file name *)
  235.           get_set_parm:
  236.               begin
  237.                 expected := [paritysym, localsym, ibmsym, emulatesym,
  238.                              escsym, debugsym, filenamsym, filetypesym,
  239.                              intsym, filewarnsym, baudsym, systemsym];
  240.                 status := get_a_sym(noun);
  241.                 if status = ateol then
  242.                     status := parm_expected
  243.                 else if (status <> unrec) and (status <>  ambiguous) then
  244.                     case noun of
  245.                       paritysym: state := get_parity;
  246.                       localsym: state := get_on_off;
  247.                       ibmsym: state := get_on_off;
  248.                       emulatesym: state := get_on_off;
  249.                       escsym: state := getchar;
  250.                       debugsym: state := get_on_off;
  251.                       filenamsym : state := get_naming;
  252.                       filetypesym : state := get_f_type;
  253.                       filewarnsym: state := get_on_off;
  254.                       intsym: state := get_int_type;
  255.                       baudsym: state := get_baud;
  256.                       systemsym: state := get_line
  257.                     end (* case *)
  258.             end; (* case get_set_parm *)
  259.           get_log_parm:
  260.               begin
  261.                 expected := [debugsym];
  262.                 status := get_a_sym(adj);
  263.                 if status = ateol then
  264.                     status := parm_expected
  265.                 else if (status <> unrec) and (status <> ambiguous) then
  266.                     if verb = logsym
  267.                       then state := getfilename
  268.                       else state := fin
  269.               end; (* case get_log_parm *)
  270.           get_line:
  271.               begin
  272.                 eat_spaces(line);
  273.                 parse := null;
  274.                 exit(parse)
  275.               end; {case get_line}
  276.           get_parity, get_naming, get_int_type, get_on_off, get_f_type:
  277.               begin
  278.                 case state of
  279.                   get_parity:   expected := [marksym, spacesym,
  280.                                              nonesym, evensym, oddsym];
  281.                   get_naming:   expected := [convsym, litsym];
  282.                   get_int_type: expected := [kermitsym, ucsdsym];
  283.                   get_on_off:   expected := [onsym, offsym];
  284.                   get_f_type:   expected := [binsym, textsym];
  285.                 end {case state};
  286.                 status := get_a_sym(adj);
  287.                 if status = ateol then
  288.                     status := parm_expected
  289.                 else if (status <> unrec) and (status <> ambiguous) then
  290.                     state := fin
  291.               end; (* case get_parity  *)
  292.           get_baud:
  293.              begin
  294.                expected := [];
  295.                if get_num( line, newbaud ) then begin
  296.                   status := null; state := fin
  297.                end
  298.                else begin
  299.                   newbaud := 0;
  300.                   status := parm_expected
  301.                end
  302.              end; (* case get_baud *)
  303.           get_char:
  304.               if nextch(newescchar) then
  305.                  state := fin
  306.               else
  307.                  status := ch_expected;
  308.           get_show_parm:
  309.               begin
  310.                 expected := [allsym, paritysym, localsym, ibmsym,
  311.                              emulatesym, escsym, debugsym,
  312.                              filenamsym, filetypesym, filewarnsym,
  313.                              baudsym, systemsym, versionsym];
  314.                 status := get_a_sym(noun);
  315.                 if status = ateol then
  316.                     status := parm_expected
  317.                 else if (status <> unrec) and (status <>  ambiguous) then
  318.                     state := fin
  319.               end; (* case get_show_parm *)
  320.           get_help_show, get_help_log:
  321.               begin
  322.                 case noun of
  323.                   logsym, closesym:
  324.                     expected := [debugsym];
  325.                   setsym:
  326.                     expected := [paritysym, localsym, ibmsym, escsym,
  327.                                  intsym, debugsym, filenamsym, filetypesym,
  328.                                  filewarnsym, baudsym, emulatesym, systemsym];
  329.                   showsym:
  330.                     expected := [paritysym, localsym, ibmsym, escsym,
  331.                                  debugsym, filenamsym, filetypesym,
  332.                                  filewarnsym, baudsym, emulatesym, systemsym,
  333.                                  allsym, versionsym];
  334.                 end {case noun};
  335.                 status := get_a_sym(adj);
  336.                 if (status = at_eol) then
  337.                   begin
  338.                     status := null;
  339.                     state := fin
  340.                   end
  341.                 else if (status <> unrec) and (status <>  ambiguous) then
  342.                     state := fin
  343.               end; (* case get_help_show *)
  344.           get_help_parm:
  345.               begin
  346.                 expected := [consym, exitsym, helpsym, quitsym, recsym,
  347.                              comsym, getsym, putsym, byesym, finsym, takesym,
  348.                              logsym, closesym, sendsym, setsym, showsym];
  349.                 status := get_a_sym(noun);
  350.                 if status = ateol then
  351.                   begin
  352.                     parse := null;
  353.                     exit(parse)
  354.                   end;
  355.                 if (status <> unrec) and (status <>  ambiguous) then
  356.                     case noun of
  357.                       consym, comsym, getsym, putsym,
  358.                       sendsym, finsym, byesym, takesym,
  359.                       recsym: state := fin;
  360.                       closesym, logsym: state := get_help_log;
  361.                       showsym, setsym: state := get_help_show;
  362.                       helpsym: state := fin;
  363.                       exitsym, quitsym: state := fin;
  364.                     end (* case *)
  365.               end; (* case get_help_show *)
  366.         end (* case *)
  367.     until (status <> null);
  368.     parse := status
  369.   end; (* parse *)
  370.  
  371. procedure initvocab;
  372.  
  373. var i: integer;
  374.  
  375.   begin
  376.     vocablist[allsym] :=        'ALL';
  377.     vocablist[baudsym] :=       'BAUD';
  378.     vocablist[binsym] :=        'BINARY';
  379.     vocablist[byesym] :=        'BYE';
  380.     vocablist[closesym] :=      'CLOSE';
  381.     vocablist[comsym] :=        'COMMENT';
  382.     vocablist[consym] :=        'CONNECT';
  383.     vocablist[convsym] :=       'CONVERTED';
  384.     vocablist[debugsym] :=      'DEBUG';
  385.     vocablist[emulatesym] :=    'EMULATE';
  386.     vocablist[escsym] :=        'ESCAPE';
  387.     vocablist[evensym] :=       'EVEN';
  388.     vocablist[exitsym] :=       'EXIT';
  389.     vocablist[filenamsym] :=    'FILE-NAMES';
  390.     vocablist[filetypesym] :=   'FILE-TYPE';
  391.     vocablist[filewarnsym] :=   'FILE-WARNING';
  392.     vocablist[finsym] :=        'FINISH';
  393.     vocablist[getsym] :=        'GET';
  394.     vocablist[helpsym] :=       'HELP';
  395.     vocablist[ibmsym] :=        'IBM';
  396.     vocablist[intsym] :=        'INTERFACE';
  397.     vocablist[kermitsym] :=     'KERMIT';
  398.     vocablist[litsym] :=        'LITERAL';
  399.     vocablist[localsym] :=      'LOCAL-ECHO';
  400.     vocablist[logsym] :=        'LOG';
  401.     vocablist[marksym] :=       'MARK';
  402.     vocablist[nonesym] :=       'NONE';
  403.     vocablist[oddsym] :=        'ODD';
  404.     vocablist[offsym] :=        'OFF';
  405.     vocablist[onsym] :=         'ON';
  406.     vocablist[paritysym] :=     'PARITY';
  407.     vocablist[putsym] :=        'PUT';
  408.     vocablist[quitsym] :=       'QUIT';
  409.     vocablist[recsym] :=        'RECEIVE';
  410.     vocablist[sendsym] :=       'SEND';
  411.     vocablist[setsym] :=        'SET';
  412.     vocablist[showsym] :=       'SHOW';
  413.     vocablist[spacesym] :=      'SPACE';
  414.     vocablist[systemsym] :=     'SYSTEM-ID';
  415.     vocablist[takesym] :=       'TAKE';
  416.     vocablist[textsym] :=       'TEXT';
  417.     vocablist[ucsdsym] :=       'UCSD';
  418.     vocablist[versionsym] :=    'VERSION';
  419.   end; (* initvocab *)
  420.  
  421. procedure par_version;
  422.  
  423.   begin
  424.     writeln(my_version)
  425.   end {par_version};
  426.  
  427. end. (* end of unit *)
  428.  
  429.