home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / misc_programming / battutor.l!h / PARSER.INC < prev    next >
Text File  |  1990-11-02  |  10KB  |  215 lines

  1. ;
  2. ;                       parser.inc
  3. ;
  4. ;
  5. ;       This INCLUDE file implements a PSP command line parser of
  6. ;       the following command line syntax:
  7. ;
  8. ;       <byte count> [leading delims][ / [cmd1 [cmd2 cmd3] / ][ <string> ]
  9. ;
  10. ;       where:
  11. ;
  12. ;               <byte count>    is a mandatory one-byte count of the rest of
  13. ;                               the characters in the command line.
  14. ;                               The byte count may be zero (null cmd line).
  15. ;
  16. ;               leading delims  are leading blanks or tabs before the first
  17. ;                               slash or the first non-blank character of
  18. ;                               <string>.
  19. ;
  20. ;               cmdi            is the ith one-character command code following
  21. ;                               the first "/" encountered on the line.  These
  22. ;                               commands are executed as they are encountered
  23. ;                               during the left-to-right parsing of the line.
  24. ;
  25. ;               <string>        all characters, including any blanks or tabs,
  26. ;                               that follow the second slash if present; or
  27. ;                               all characters that follow leading blanks or
  28. ;                               tabs, if no slashes are present.
  29. ;
  30. ;
  31. ;       on entry, this code expects the following register values:
  32. ;
  33. ;               SI =    offset of the byte count (the first byte of the line)
  34. ;
  35. ;       this code trashes the following registers:
  36. ;
  37. ;               AX, BX, CX, DX, possibly BP
  38. ;
  39. ;       this parser discards any leading delimiters up to the first optional
  40. ;       slash.  It then decodes and executes any valid one-character commands
  41. ;       found between the first and second slash encountered.  The definition
  42. ;       and execution of the commands is table driven, a table interface is
  43. ;       provided by the host program that INCLUDEs this code.  When the second
  44. ;       slash is encountered, parsing is done.  The CX register contains the
  45. ;       number of string characters left after the second slash (including
  46. ;       delimiters) or, if no slashes are encountered before the first non-
  47. ;       delimiter, the number of string characters starting at the first non-
  48. ;       delimiter.  The BX register points to the corresponding character,
  49. ;       relative to [SI].
  50. ;
  51. ;       examples:
  52. ;
  53. ;       null string             parser finds no cmds            CX = 0
  54. ;                                                               BX undefined
  55. ;
  56. ;       <space><tab><space>     parser finds no cmds            CX = 0
  57. ;                                                               BX undefined
  58. ;
  59. ;       / cmd1                  parser executes cmd1            CX = 0
  60. ;                                                               BX undefined
  61. ;
  62. ;       /<string>               parser executes any valid       CX = 0
  63. ;                               command characters found        BX undefined
  64. ;                               in string
  65. ;
  66. ;       /cmd1 cmd2/<tab><string> parser executes cmd1 and       CX = count of
  67. ;                                cmd2.                               string +
  68. ;                                                                    tab char
  69. ;                                                               BX points at tab
  70. ;
  71. ;       <space><space><string>  parser finds no commands        CX = count of
  72. ;                                                                    string only
  73. ;                                                               BX points at
  74. ;                                                                  first char of
  75. ;                                                                  string.
  76. ;
  77. ;       This code expects the following table interface to be defined in the
  78. ;       host code.
  79. ;
  80. ;       CMD_TOTAL       DW      n       ;total number of commands defined
  81. ;
  82. ;       CMD_LETTERS     DB      'cmd1','CMD1'  ;two characters each of which
  83. ;                       .                      ; signify a command
  84. ;                       .
  85. ;                       DB      'cmdn','CMDn'  ;(typically lower and upper case
  86. ;                                              ; of one letter)
  87. ;
  88. ;       CMD_OFFSETS     DW       offset_proc1   ;the corresponding procedure for
  89. ;                       .                       ;the command defined above
  90. ;                       .
  91. ;                       DW       offset_procn   ;(NEAR procedures in host code)
  92. ;
  93. ;       symbols defined within the INCLUDE code will have a leading "_"
  94. ;
  95. ;               equates
  96. ;
  97. _TAB            EQU     9                       ;ascii TAB code
  98. _BLANK          EQU     ' '                     ;ascii BLANK code
  99. _SLASH          EQU     '/'                     ;ascii '/' code
  100. ;
  101. ;                       start the parse
  102. ;
  103. ;       if command line is empty, skip parsing, report back that CX = 0
  104. ;
  105. ;
  106. _START_PARSE:   SUB     CX,CX                   ;zero CX
  107.                 MOV     CL,[SI]                 ;get char count from 1st byte
  108.                 OR      CL,CL                   ;is it zero?
  109.                 JZ      _PARSE_DONE             ;done if yes, CX = 0
  110. ;
  111. ;       cmd line is not null
  112. ;
  113. ;       set up loop indices:    CX = number of chars left in string
  114. ;                               BX = index relative to [SI] of the
  115. ;                                    next character to be tested
  116. ;
  117.                 SUB     BX,BX                   ;initialize index  (first iter
  118.                                                 ; of loop will increment BX
  119. ;
  120. ;       parse leading blanks and tabs until either a "/" is found or else
  121. ;       all leading blanks and tabs are discarded
  122. ;
  123. _PARSE_BLANKS:  INC     BX                      ;point to next character in line
  124.                 MOV     AL,[SI][BX]             ;next character into AL
  125.                 CMP     AL,_BLANK               ;is it blank?
  126.                 JZ      _LOOP_BLANK             ;keep parsing if yes
  127.                 CMP     AL,_TAB                 ;is it tab?
  128.                 JZ      _LOOP_BLANK             ;keep parsing if yes
  129.                 CMP     AL,_SLASH               ;is it first slash?
  130.                 JZ      _NEXT_CMD               ;jump if yes, start decoding
  131.                                                 ; commands between slashes
  132.                 JMP     _PARSE_DONE             ;else first non-blank non-tab
  133.                                                 ;delimiter.
  134. ;
  135. ;       leading blank or tab found, continue looking for leading delimiters
  136. ;
  137. _LOOP_BLANK:    LOOP    _PARSE_BLANKS
  138.                 JMP     _PARSE_DONE
  139. ;
  140. ;       parse next character after first slash
  141. ;
  142. _CMD_PARSE:     MOV     AL,[SI][BX]             ;get next char in cmd line
  143.                 CMP     AL,_SLASH               ;is it second slash?
  144.                 JNE     _CHECK_TABLES           ;if not, go to tables to find
  145.                                                 ;the command.
  146. ;
  147. ;       second slash found.  parsing is done.  point BX to next character and
  148. ;       decrement CX so it equals characters left after second slash
  149. ;
  150.                 INC     BX                      ;leave BX pointing to next char
  151.                 DEC     CX                      ;leave CX as count of all chars
  152.                                                 ; after the second slash.
  153.                 JMP     _PARSE_DONE             ;and exit this parser code
  154. ;
  155. ;       set up inner loop to search through CMD_LETTERS table for a match of
  156. ;       command characters with char in AL.  If not in table, ignore character
  157. ;       in AL and parse next character in cmd line.
  158. ;
  159. _CHECK_TABLES:  PUSH    BX                      ;save outer loop context
  160.                 PUSH    CX
  161.                 MOV     CX,CMD_TOTAL            ;table length for inner loop
  162.                 SUB     BX,BX                   ;clear index
  163. ;
  164. ;       for each CMD_LETTERS 2-byte entry, check both characters for a match
  165. ;
  166. _TABLE_LOOP:    CMP     AL,CMD_LETTERS[BX]      ;does left byte match?
  167.                 JE      _DO_CMD                 ;jump if yes, do command
  168.                 CMP     AL,CMD_LETTERS[BX+1]    ;else does right match?
  169.                 JNE     _MORE_TABLE
  170. ;
  171. ;       command "letter" matches AL.  After saving context, enter host-
  172. ;       supplied procedure indirectly through corresponding entry in
  173. ;       CMD_OFFSETS table.
  174. ;
  175. _DO_CMD:        PUSH    AX                      ;save context
  176.                 PUSH    BX
  177.                 PUSH    CX
  178.                 PUSH    SI
  179.                 CALL    CMD_OFFSETS[BX]         ;call indirect through table
  180.                 POP     SI
  181.                 POP     CX
  182.                 POP     BX
  183.                 POP     AX                      ;restore context
  184.                 JMP     _MORE_PARSE             ;parse next char
  185. ;
  186. ;       else haven't matched AL yet, so look at next table entry in inner loop
  187. ;
  188. _MORE_TABLE:    INC     BX                      ;point to next word
  189.                 INC     BX
  190.                 LOOP    _TABLE_LOOP             ;and loop on table length
  191. ;
  192. ;       command definition table exhausted (so ignore this character) or
  193. ;       character command was found in table and executed.
  194. ;
  195. ;       restore outer loop context and parse the next character in line
  196. ;
  197. _MORE_PARSE:    POP     CX                      ;restore outer loop context
  198.                 POP     BX
  199. _NEXT_CMD:      INC     BX                      ;point to next char in cmd line
  200.                 LOOP    _CMD_PARSE              ;parse until 2nd slash or CX=0
  201. ;
  202. ;       CX is   characters left after second slash
  203. ;               or, characters left after leading delimiters if no slashes
  204. ;               or, zero if no characters at all
  205. ;               or, zero if no slashes and no non-blank or non-tab characters
  206. ;               or, zero if no characters at all after second slash
  207. ;
  208. ;       BX is   pointing to corresponding character in string if CX > 0
  209. ;               or, undefined if CX = 0
  210. ;
  211. _PARSE_DONE     LABEL   NEAR                    ;done
  212. ;
  213. ;       ------------     end of parser.inc    ------------
  214. ;
  215.