'===========================================================================
' Subject: TEXT PARSER                        Date: 04-12-94 (00:00)       
'  Author: Scott Tucker                       Code: PB                     
'  Origin: Creative Software Alliance       Packet: PB.ABC
'===========================================================================
' ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
' º   Main Program Name : Parser.Bas                 º»
' º   Last Update       : 04/12/1994                 ºº
' º   Compiled with PowerBasic vers  3.00c           ºº
' º                                                  ºº
' º   Uploaded by:                                   ºº
' º   ============                                   ºº
' º   Scott Tucker                                   ºº
' º   Creative Software Alliance                     ºº
' º   16 Lakeville Ave.                              ºº
' º   Petaluma, CA  94952                            ºº
' º   (707) 778-1591                                 ºº
' º                                                  ºº
' ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼º
'  ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ¼
Cls
ReDim A$(0)

' Example #1
'===========
'T$ = "This is a sample line of some words."
'Call Parser(T$, " ", A$(), 2)

' Example #2
'===========
'T$ = "This is a sample line of some words."+Chr$(13)+_
'      "It contains 2 sentences to parse apart."
'Call Parser(T$, Chr$(13), A$(), 2)

' Example #3
'===========
T$ = "\mn /tp /op /t:rew /lfre /abcdefg -pdq -dA:filename"
Call Parser(T$, "/-\", A$(), 1)

' Print items returned from procedure.
For K%=1 to UBound(A$)
  Print K%; "*" + RTrim$(A$(K%)) + "*"
Next

End
'========================================
Sub Parser(ByVal Text$, ByVal Delimiter$, Parms$(), ByVal Flag%)
  ' This procedure parses text based on a given set of delimiters.
  ' The delimiter can either separate the items in the string, or
  ' it can precede items in the string. The resulting parsed items
  ' are returned in the array PARMS$().

  ' Parameter Descriptions
  ' ======================
  ' Text$      = This is the string of text containing the delimiters to
  '              parse.
  ' Delimiters$= This is the list of delimiters used to parse the string.
  '              These delimiters can be any single string item, or a
  '              multiple list of items. Examples: "/" or "/\-"
  ' Parms$()   = The array that contains each item parsed out of the string.
  '              This array is redimensioned (from 1) to hold the proper
  '              number of parsed items. It should initially be Dim'ed to
  '              Parms$(0) before being passed into this procedure. If no
  '              delimiters are found in the string, the array will have a
  '              dim'ed index of (0) and a null value is returned
  '              in the array.
  ' Flag%      = A flag indicating whether the delimiters separate the
  '              string, or precede delimited items.
  '              1 = Precede      2 = Separate

  '              The difference is defined as follows:
  '    Type 1    A type 1 delimiter means that you are only interested in
  '              the text that follows a delimiter. For example, as in a
  '              command line string, you may have a string passed into your
  '              Program that looks like Text$=" /n /o /d". The parser would
  '              return 3 items in the array Parms$(1)="n", (2)="o", (3)="d".
  '              All text up to the first delimiter is ignored.

  '    Type 2   A type 2 delimiter means that text is separated by the
  '             delimiter, an all values on both sides of the delimiters
  '             are returned. For example: If you have a string that is to be
  '             broken apart based on where a Chr$(13) char is inserted, it
  '             may look like this: Text$="This is"+Chr$(13)+"a sample."
  '             The parser would return 2 items in the array.
  '             Parms$(1)="This is "   and    Parms$(2)="a sample."

  '             Given these examples, it should be very easy to create other
  '             types of delimiters. For example, it might be desirable to
  '             have a delimiter type that is at the end of a string section.
  '             This would be the opposite of a Type 1, such that any text
  '             after the last delimiter would be ignored. Example:

  '             Text$ = "This is| a sample| text line."
  '             Call Parser$(Text$, "|", Parms$(), 3)   ' type 3
  '             This would return 2 items; Parms$(1)="This is", (2)="a sample"
  '========================================================================
  Local L%, T%, C%

  C%=0                                        ' item counter

  Select Case Flag%
    Case 1            ' delimiter precedes items being returned
      ' Example  Del="/"  String$="/m /no /yes"
      ' returns 3 items

      T% = Tally(Text$, ANY Delimiter$)       ' number of delimiters found

      If T% = 0 then                          ' no delimiters
        ReDim Parms$(0)                       ' erase array values
        Exit Select                           ' exit sub
      End If

      ReDim Parms$(1: T%)                     ' create array to hold items

      DO
        Incr C%                               ' increment counter
        L% = Instr(Text$, ANY Delimiter$)     ' pointer for first delimiter
        Text$ = Right$(Text$, Len(Text$)-L%)  ' ignore all up to first delim
                                              ' since the delimiter precedes.

        L% = Instr(Text$, ANY Delimiter$)     ' pointer for next delimiter

        If L% <> 0 then
          Parms$(C%) = Left$(Text$, L%-1)     ' get all up to next delim.
        Else
          Parms$(C%) = Text$                  ' get all remaining
        End If

        Text$ = Right$(Text$, Len(Text$)-Len(Parms$(C%)))
      LOOP While Len(Text$)

    Case 2            ' delimiter separates items being returned
      ' Example  Del=Chr$(13)  String$="This is"+Chr$(13)+" a test".
      ' returns 2 items

      T% = Tally(Text$, ANY Delimiter$)       ' number of delimiters found

      If T% = 0 then                          ' no delimiters
        ReDim Parms$(0)                       ' erase array values
        Exit Select                           ' exit sub
      End If

      ReDim Parms$(1: T%+1)                   ' create array to hold items

      DO
        Incr C%                               ' increment counter
        L% = Instr(Text$, ANY Delimiter$)     ' pointer for delimiter

        If L% <> 0 then
          Parms$(C%) = Left$(Text$, L%-1)     ' get all up to delimiter
          Text$ = Right$(Text$, Len(Text$) - Len(Parms$(C%))-1)
        Else
          Parms$(C%) = Text$                  ' get all remaining
          Text$      = ""
        End If
      LOOP While Len(Text$)

    Case Else                                 ' some other flag
      Parms$(1) = Text$                       ' Bad flag
  End Select

End Sub
