! PARSER.TPU 31-OCT-1989 18:35 Page 1 !++ ! Table of Contents ! ! PARSER.TPU ! 31-OCT-1989 18:35 ! ! Procedure name Page Description ! -------------- ---- ------------ ! ! eve_parse_test 1 Test scafolding for simple parser ! cdb_parse_command 2 Utility command parser !-- procedure eve_parse_test ! Test scafolding for simple parser (given_command); local tpu_statement, parameter_string, hits; if cdb_parse_command (given_command, tpu_statement, parameter_string, hits) then message ("returned true"); else message ("returned false"); endif; message ("given_command: " + given_command); message ("tpu_statement: " + tpu_statement); message ("hits: " + str (hits)); endprocedure ! eve_parse_test ! PARSER.TPU Page 2 procedure cdb_parse_command ! Utility command parser ! Abstract: ! This parser is faster and more simple than EVE's parser. It won't ! disambiguate as well as EVE's parser but it does a fair job of figuring out ! what the user meant. (given_command, ! A command line as the user has entered it tpu_statement, ! A TPU procedure call parameter_string, ! A string containing all paramaters hits) ! 1:Success 2:Ambiguous command 0:Unknown command local edited_command, ! Upcased, excess blanks removed, etc. maskof_command, ! Result of TRANSLATE, parsing aid, input to EXPAND trial_mask, ! A subset of maskof_command try_array, ! Array of trial masks command_end_ndx; ! Character index on_error [TPU$_CONTROLC]: ! Return meaningful parameters tpu_statement := ""; hits := 0; parameter_string := ""; return FALSE; [TPU$_NONAMES, TPU$_MULTIPLENAMES]: ! trap expand_name errors [OTHERWISE]: endon_error; hits := 0; tpu_statement := ""; parameter_string := ""; edited_command := edit (given_command, UPPER, TRIM, COMPRESS, ON, NOT_IN_PLACE); ! mask shows "9" for anything that isn't part of the command, and ! "*" for whitespace maskof_command := translate (edited_command, "*9999999999999*", " *0123456789" + "'" + '"' + ascii (9), NOT_IN_PLACE); message (" given_command: " + given_command); message ("edited_command: " + edited_command); message ("maskof_command: " + maskof_command); ! Drop anything that's an obvious parameter from the end of the mask command_end_ndx := index (maskof_command, '9'); if command_end_ndx > 0 then parameter_string := substr (edited_command, command_end_ndx); maskof_command := substr (maskof_command, 1, command_end_ndx - 1); endif; message ("maskof_command: " + maskof_command); ! Build an array of tokens strings indexed by their length. For example: ! try_array {4} := "SET*"; (assume input was "set key edt") ! try_array {9} := "SET*_KEY*"; ! try_array {14} := "SET*_KEY*_EDT*"; try_array := create_array; trial_mask := ""; loop message ("maskof_command: " + maskof_command); message ("trial_mask: " + trial_mask); command_end_ndx := index (maskof_command, '*'); trial_mask := trial_mask + substr (maskof_command, 1, command_end_ndx); try_array {length (trial_mask)} := trial_mask; maskof_command := substr (maskof_command, command_end_ndx + 1); exitif maskof_command = ""; trial_mask := trial_mask + "_"; endloop; ! Now try each of our array entries, starting at the longest one. If we ! get an exact match we're done. We're also done if we get more than one ! match or exhaust our arrays without getting a match; in this case we've ! failed to parse the command and must return an error try_ndx := get_info (try_array, 'last'); loop message ("maskof_command: " + maskof_command); message ("tpu_statement: " + tpu_statement); exitif try_ndx = tpu$k_unspecified; maskof_command := try_array {try_ndx}; tpu_statement := expand_name ("EVE_" + maskof_command, PROCEDURES); exitif tpu_statement <> ""; try_ndx := get_info (try_array, 'previous'); endloop; if index (tpu_statement, ' ') > 0 ! Ambiguous command then hits := 2; return FALSE; endif; if tpu_statement = "" ! Unknown command then hits := 0; return FALSE; endif; hits := 1; ! Exact match return TRUE; endprocedure; ! cdb_parse_command Contents of message buffer after few sample tests - ! given_command: s l m 15 !edited_command: S L M 15 !maskof_command: S*L*M*99 !maskof_command: S*L*M* !maskof_command: S*L*M* !trial_mask: !maskof_command: L*M* !trial_mask: S*_ !maskof_command: M* !trial_mask: S*_L*_ !maskof_command: !tpu_statement: !returned true !given_command: s l m 15 !tpu_statement: EVE_SET_LEFT_MARGIN !hits: 1 ! ! given_command: s l 15 !edited_command: S L 15 !maskof_command: S*L*99 !maskof_command: S*L* !maskof_command: S*L* !trial_mask: !maskof_command: L* !trial_mask: S*_ !maskof_command: !tpu_statement: !returned false !given_command: s l 15 !tpu_statement: EVE_SHIFT_LEFT EVE_START_OF_LINE EVE_SET_LEFT_MARGIN !hits: 2 ! ! given_command: se l 15 !edited_command: SE L 15 !maskof_command: SE*L*99 !maskof_command: SE*L* !maskof_command: SE*L* !trial_mask: !maskof_command: L* !trial_mask: SE*_ !maskof_command: !tpu_statement: !returned true !given_command: se l 15 !tpu_statement: EVE_SET_LEFT_MARGIN !hits: 1