faqts : Computers : Programming : Languages : Tse : Parser

+ Search
Add Entry AlertManage Folder Edit Entry Add page to http://del.icio.us/
Did You Find This Entry Useful?

Entry

TSE: Parser: Simple: Syntax: Structure: Class: How to parse the initialization of a new object?

Sep 24th, 2003 16:25
Knud van Eeden,


----------------------------------------------------------------------
--- Knud van Eeden --- 24 September 2003 - 11:43 pm ------------------

TSE: Parser: Simple: Syntax: Structure: Class: How to parse the 
initialization of a new object?

To possibly parse an object initialization of a given class in e.g.
Java, C#, ..., with the general format:

 '<yourclassname> <yourvariablename> = new <yourclassname> ( 
yourparameter1, yourparameter2, ..., yourparameterlast )'

---

for example given:

 Font myfontO = new Font( "Hello world from Java", 5, 25 )

how could you possibly parse this:

---

Syntax diagram:

1. First you have your class initialization:

 -->--[yourclassname]-->--[yourvariablename]-->--[=]-->--[new]---...


                            +------------>-----------+
                            |                        |
 ...-->--[yourclassname]-->-+->--[yourparameters]-->-+->--



2. Where this 'yourparameters' are like this:

                                 +------------>--------+
                                 |                     |
 -->--[(]-->-+->--[parameter]-->-+->--[,]-->-+-->-+-->-+-[)]-->--
             |                                    |
             +--------------<---------------------+

---

Backus Naur Form (BNF) in words:

'object initalization'= 1. not followed by 'yourclassname': error

                        2. followed by 'your classname'

                           1. not followed by 'yourvariablename': error

                           2. followed by 'yourvariablename'

                              1. not followed by '=': error

                              2. followed by '='

                                 1. not followed by 'new': error

                                 2. followed by 'new'

                                    1. not followed by 'yourclassname':
                                       error

                                    2. followed by 'yourclassname'

                                       1. not followed by 1 or
                                          more 'parameters'

                                       2. followed by 1 or
                                          more 'parameters'


Where you have:

'parameters' = 1. not followed by 1 'open parenthesis': error

               2. followed by 1 'open parenthesis'

                 1. not followed by 1 or more 'parameters': error

                 2. followed by 1 or more 'parameters'

                    1. not followed by a 'comma'

                       1. not followed by a 'closed parenthesis': error

                       2. followed by a 'closed parenthesis'

                    2. followed by a 'comma'

---

Note: so this structure is a clear binary tree, all the time totally 2
possibilities per branch (a correct path, and a NOT correct path)

       NOT ok
      +-------
      |
      |
      |
      |             NOT ok
 -----+            +-------
      |            |
      |            |
      |            |
      |            |             NOT ok
      +------------+            +-------
       ok          |            |
                   |            |
                   |            |
                   |            |            NOT ok
                   +------------+           +-------
                    ok          |           |
                                |           |
                                |           |
                                |           |
                                +-------....+
                                 ok         |
                                            |
                                            |
                                            |
                                            +-------
                                             ok

---

If it is OK, you take off that word, and continue.

If it is NOT OK, you show an error message, and exit (=return) from 
this subroutine.

---

Pseudocode:

if not 'yourclassname', error, return false
get 'yourclassname'
if not 'yourvariablename', error, return false
get 'yourvariablename'
if not '=', error, return false
get '='
if not 'new', error, return false
get 'new'
if not 'yourclassname', error, return false
get 'yourclassname'
if 'parameters'
 if not '(', error, return false
 get '('
  repeat
   if not 'parameter', error, return false
   get 'parameter'
   if ',' get ',' : commaB=true
  until ( not commaB ) or ')'
  if not ')', error, return false
  get ')'

---

So you see that this source code strictly follows the binary tree, with
9 times a possible error, as a direct reflection of the 9 possible
error branches of the binary tree.

---

Translation of pseudocode in a TSE program:

PROC Main()

 Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font ( 
parameter1 , parameter2 , parameter3 , parameter4 , 
parameter5 )" ) ) // gives e.g. TRUE // note: spaces between all 
tokens, so use also spaces between the commas ',' and '(', for 
simplicity

 Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font ( parameter1 
parameter2 , parameter3 , parameter4 , parameter5 )" ) ) // gives e.g. 
FALSE // note: spaces between all tokens, so use also spaces between 
the commas ',' and '(', for simplicity

END

--- cut here ----------------------------------------------------------

FORWARD INTEGER PROC FNMathCheckLogicNotB( INTEGER i1 )

FORWARD INTEGER PROC FNParserSyntaxObjectNewB( STRING s1 )

FORWARD INTEGER PROC FNParserSyntaxParameterB( STRING s1 )

FORWARD INTEGER PROC FNStringCheckEqualB( STRING s1, STRING s2 )

FORWARD INTEGER PROC FNStringCheckEqualCaseInsensitiveB( STRING s1,
STRING s2 )

FORWARD INTEGER PROC FNStringCheckIsVariableB( STRING s1 )

FORWARD INTEGER PROC FNStringCheck_EqualCaseInsensitiveNotB( STRING s1,
STRING s2 )

FORWARD INTEGER PROC FNStringGetLengthI( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsClassnameB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsCommaB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsEqualSignB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsNewB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsParameterB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsParenthesisCloseB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsParenthesisOpenB( STRING s1 )

FORWARD INTEGER PROC FNTokenCheckIsVariableB( STRING s1 )

FORWARD PROC Main()

FORWARD STRING PROC FNInitializeNewStringS()

FORWARD STRING PROC FNStringDeleteWordFrontS( STRING s1, STRING s2 )

FORWARD STRING PROC FNStringGetCarS( STRING s1 )

FORWARD STRING PROC FNStringGetCaseUpperS( STRING s1 )

FORWARD STRING PROC FNStringGetCdrS( STRING s1 )

FORWARD STRING PROC FNStringGetEmptyS()

FORWARD STRING PROC FNStringRemoveSpaceBeginS( STRING s1 )

// --- MAIN --- //

PROC Main()

 Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font ( parameter1
 , parameter2 , parameter3 , parameter4 , parameter5 )" ) ) // gives
 e.g. TRUE // note: spaces between all tokens, so use also spaces
 between the commas ',' and '(', for simplicity

 Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font ( parameter1
 parameter2 , parameter3 , parameter4 , parameter5 )" ) ) // gives e.g.
 FALSE // note: spaces between all tokens, so use also spaces between
 the commas ',' and '(', for simplicity

END

<F12> Main()

// --- LIBRARY --- //

// library: parser: syntax: object: new (filenamemacro=syntpaon.s) [kn,
ni, we, 24-09-2003 23:40:45]

INTEGER PROC FNParserSyntaxObjectNewB( STRING inS )

 // e.g. PROC Main()

 // e.g.  Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font (
 parameter1 , parameter2 , parameter3 , parameter4 , parameter5 )" ) )
 // gives e.g. TRUE // note: spaces between all tokens, so use also
 spaces between the commas ',' and '(', for simplicity

 // e.g.  Warn( FNParserSyntaxObjectNewB( "Font myfontO = new Font (
 parameter1 parameter2 , parameter3 , parameter4 , parameter5 )" ) ) //
 gives e.g. FALSE // note: spaces between all tokens, so use also
 spaces between the commas ',' and '(', for simplicity

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING s[255] = inS

 STRING yourclassnameS[255] = FNInitializeNewStringS()

 IF NOT FNTokenCheckIsClassnameB( s ) Warn( 'error: no valid classname
 found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF // if not
 'yourclassname', error, return false

 yourclassnameS = FNStringGetCarS( s ) // store that classname, as you
 will have to check for equality, if it shows up again some steps later

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off 'yourclassname' // get 'yourclassname'

 IF NOT FNTokenCheckIsVariableB( s ) Warn( 'error: no valid
 variablename found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF // if not
 'yourvariablename', error, return false

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off 'yourvariablename' // get 'yourvariablename'

 IF NOT FNTokenCheckIsEqualSignB( s ) Warn( "error: no '=' found:" + '
 ' + '^' + s ) RETURN( FALSE ) ENDIF // if not '=', error, return false

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off '=' // get '='

 IF NOT FNTokenCheckIsNewB( s ) Warn( "error: no 'new' found:" + ' ' +
 '^' + s ) RETURN( FALSE ) ENDIF // if not 'new', error, return false

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off 'new' // get 'new'

 IF NOT FNTokenCheckIsClassnameB( s ) Warn( 'error: no valid classname
 found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF // if not
 'yourclassname', error, return false

 IF FNStringCheck_EqualCaseInsensitiveNotB( yourclassnameS,
 FNStringGetCarS( s ) ) Warn( 'classnames should be equal' + ' ' +
 yourclassnameS + ' ' + FNStringGetCarS( s ) ) RETURN( FALSE) ENDIF //
 both classnames in your class should be exactly equal (also because
 Java is case sensitive)

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off 'yourclassname' // get 'yourclassname'

 IF FNTokenCheckIsParenthesisOpenB( s ) // if any parameters present,
 then check it via the subroutine parse 'parameters'

  RETURN( FNParserSyntaxParameterB( s ) )

 ENDIF

 RETURN( TRUE )

END

// library: string: initialize [kn, ri, mo, 09-07-2001 12:00:07]

STRING PROC FNInitializeNewStringS()

 RETURN( FNStringGetEmptyS() )

END

// library: token: check: is: classname (filenamemacro=chectoid.s) [kn,
ni, we, 24-09-2003 23:05:31]

INTEGER PROC FNTokenCheckIsClassnameB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsClassnameB( "classname1" ) ) // gives
 e.g. TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNTokenCheckIsVariableB( firstwordS ) ) // a classname is
 usually a variablename

END

// library: string: get: word: token: get: first: FNStringGetCarS():
Get the first word of a string (words delimited by a space " " (=space
delimited list)). (filenamemacro=getstgca.s) [kn, ni, zo, 02-08-1998
15:54:17]

STRING PROC FNStringGetCarS( STRING s )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: get: word: token: get:
 first: s = ", "this is a test" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  Message( FNStringGetCarS( s1 ) ) // gives e.g. "this"

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 //

 // variation: RETURN( FNStringGetTokenFirstS( s, " " ) )

 RETURN( GetToken( s, " ", 1 ) ) // faster, but not central

END

// library: string: get: word: token: get: rest: FNCdr(): Get a string,
without the first word (words delimited by a space " " (=space
delimited list)). E.g. Message( FNStringGetCarS( "Knud is the best" ) )
gives "Knud" // (filenamemacro=getstgcd.s) [kn, ni, zo, 02-08-1998
15:54:17]

STRING PROC FNStringGetCdrS( STRING s )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: get: word: token: get: rest:
 s = ", "this is a test" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  Message( FNStringGetCdrS( s1 ) ) // gives e.g. "this is a
 test"

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( FNStringRemoveSpaceBeginS( FNStringDeleteWordFrontS(
 FNStringRemoveSpaceBeginS( s ), FNStringGetCarS( s ) ) ) ) // Remove
 trailing spaces, determine the First word. Delete the first word
 (=FNCarS), and finally remove the trailing spaces from the result

END

// library: token: check: is: variable (filenamemacro=chectoiw.s) [kn,
ni, we, 24-09-2003 23:29:05]

INTEGER PROC FNTokenCheckIsVariableB( STRING s )

 // e.g. PROC Main()

 // e.g.  Warn( FNTokenCheckIsVariableB( "thisisavariable1" ) ) //
 gives 'TRUE'

 // e.g.  Warn( FNTokenCheckIsVariableB( "thisis avariable1" ) ) //
 gives 'TRUE' // because of first word 'thisis' in string separated by
 spaces is a variable

 // e.g.  Warn( FNTokenCheckIsVariableB( "9thisis avariable1" ) ) //
 gives 'FALSE' // because of first word '9this' starting with a digit

 // e.g.  Warn( FNTokenCheckIsVariableB( "thisis&avariable1" ) ) //
 gives 'FALSE' // because of '&' character

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = FNStringGetCarS( s ) // take off first word
 (in a string separated by spaces)

 RETURN( FNStringCheckIsVariableB( firstwordS ) )

END

// library: token: check: is: equal sign '=' [kn, ni, we, 24-09-2003
23:08:18]

INTEGER PROC FNTokenCheckIsEqualSignB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsEqualSignB( "= test" ) ) // gives TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNStringCheckEqualB( firstwordS, "=" ) )

END

// library: token: check: is: token 'new' [kn, ni, we, 24-09-2003
23:08:26]

INTEGER PROC FNTokenCheckIsNewB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsEqualSignB( "new test" ) ) // gives
 TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNStringCheckEqualB( firstwordS, "new" ) )

END

// library: string: check: equal: case: insensitive: not
(filenamemacro=checstin.s) [kn, ni, we, 24-09-2003 23:00:46]

INTEGER PROC FNStringCheck_EqualCaseInsensitiveNotB( STRING s1, STRING
s2 )

 // e.g. PROC Main()

 // e.g.  Message( FNStringCheck_EqualCaseInsensitiveNotB( "equal",
 "equal" ) ) // gives FALSE (gives TRUE when the characters in both
 strings are unequal (case insensitive))

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( FNMathCheckLogicNotB( FNStringCheckEqualCaseInsensitiveB( s1,
 s2 ) ) )

END

// library: token: check: is: parenthesis: open
(filenamemacro=chectopo.s) [kn, ni, we, 24-09-2003 18:49:37]

INTEGER PROC FNTokenCheckIsParenthesisOpenB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsParenthesisOpenB( "( test )" ) ) //
 gives TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNStringCheckEqualB( firstwordS, "(" ) )

END

// library: parser: syntax: parameter (filenamemacro=syntpasp.s) [kn,
ni, we, 24-09-2003 18:55:42]

INTEGER PROC FNParserSyntaxParameterB( STRING inS )

 // e.g. PROC Main()

 // e.g.  Warn( FNParserSyntaxParameterB( "( parameter1 , parameter2 ,
 parameter3 , parameter4 , parameter5 )" ) ) // gives e.g. TRUE //
 note: use also spaces between the commas ',' for simplicity

 // e.g.  Warn( FNParserSyntaxParameterB( "( parameter1 parameter2 ,
 parameter3 , parameter4 , parameter5 )" ) ) // gives e.g. FALSE //
 note: use also spaces between the commas ',' for simplicity

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING s[255] = inS

 INTEGER tokencommaB = FALSE

 IF NOT FNTokenCheckIsParenthesisOpenB( s ) Warn( 'error: no open
 parenthesis found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF // if not
 '(', error, return false

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off '(' // get '('

 REPEAT // repeat

  IF NOT FNTokenCheckIsParameterB( s ) Warn( 'error: no parameter
  found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF // if not
  'parameter', error, return false

  s = FNStringGetCdrS( s ) // take off first word of the remaining
  string, thus take off parameter // get 'parameter'

  IF FNTokenCheckIsCommaB( s ) s = FNStringGetCdrS( s ) tokencommaB =
  TRUE ENDIF // if ',' get ',' : commaB=true

 UNTIL ( NOT tokencommaB ) OR FNTokenCheckIsParenthesisCloseB( s ) //
 until ( not commaB ) or ')'

 IF NOT FNTokenCheckIsParenthesisCloseB( s ) Warn( 'error: no comma or
 close parenthesis found:' + ' ' + '^' + s ) RETURN( FALSE ) ENDIF //
 if not ')', error, return false

 s = FNStringGetCdrS( s ) // take off first word of the remaining
 string, thus take off ')' // get ')'

 RETURN( TRUE )

END

// library: string: empty: return an empty string [kn, ri, za,
20-05-2000 20:11:03]

STRING PROC FNStringGetEmptyS()

 RETURN( "" )

END

// library: string: space: remove: begin (filenamemacro=remostsb.s)
[kn, ri, th, 15-02-2001 06:06:51]

STRING PROC FNStringRemoveSpaceBeginS( STRING s )

 // e.g. PROC Main()

 // e.g.  STRING s[255] = FNInitializeNewStringS()

 // e.g.  s = FNStringGetInputS( "string: space: remove: begin: string
 = ", "   test    " )

 // e.g.  IF FNEscapeB( s ) RETURN() ENDIF

 // e.g.  Message( "'", FNStringRemoveSpaceBeginS( s ), "'" ) // gives
 e.g. "test    "

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( LTrim( s ) )

END

// library: string: word: token: delete: first: delete 1 occurence of a
given other string in front of a given string. E.g.
StringWordDeleteFront( "00001234567", "0" ) gives "0001234567".
Possible application: deleting the '0' in front of a phonenumber (e.g.
when dialing internationally). [kn, ni, zo, 02-08-1998 16:30:45]

STRING PROC FNStringDeleteWordFrontS( STRING s, STRING deleteS )

 // e.g. <F12> PROCMessage( FNStringDeleteWordFrontS( "this is", "this"
 ) ) // gives " is"

 // e.g. <F12> PROCMessage( FNStringDeleteWordFrontS( "the girl", "the"
 ) ) // gives " girl"

 // STRING PROC FNStringWordDeleteFirstS( STRING s, STRING deleteS )

 INTEGER lengthdeleteI = FNStringGetLengthI( deleteS )

 RETURN( SubStr( s, lengthdeleteI + 1, FNStringGetLengthI( s ) -
 lengthdeleteI ) )

END

// library: string: check: is: variable (filenamemacro=chectoiv.s) [kn,
ni, we, 24-09-2003 18:23:35]

INTEGER PROC FNStringCheckIsVariableB( STRING s )

 // e.g. PROC Main()

 // e.g.  Warn( FNStringCheckIsVariableB( "thisisavariable1" ) ) //
 gives 'TRUE'

 // e.g.  Warn( FNStringCheckIsVariableB( "thisis avariable1" ) ) //
 gives 'FALSE' // because of space

 // e.g.  Warn( FNStringCheckIsVariableB( "9thisis avariable1" ) ) //
 gives 'FALSE' // because of starting with a digit

 // e.g.  Warn( FNStringCheckIsVariableB( "thisis&avariable1" ) ) //
 gives 'FALSE' // because of '&' character

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 // RETURN( IsAlpha( s ) ) // variation

 INTEGER I = 0

 INTEGER totalI = FNStringGetLengthI( s )

 IF NOT ( s[1] IN 'A'..'Z', 'a'..'z', '_' ) RETURN( FALSE ) ENDIF //
 first character alphanumeric character or underscore

 I = 2 - 1

 REPEAT

  I = I + 1

  IF NOT ( s[I] IN 'A'..'Z', 'a'..'z', '_', '0'..'9' ) RETURN( FALSE )
  ENDIF // each character (after the first) should be alphanumeric,
  underscore or a digit

 UNTIL I >= totalI

 RETURN( TRUE )

END

// library: string: equal: are two given strings equal? (stored in
'checstcf.s') [kn, zoe, wo, 04-10-2000 18:23:27]

INTEGER PROC FNStringCheckEqualB( STRING s1, STRING s2 )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  STRING s2[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: check: equal: first string =
 ", "a" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  s2 = FNStringGetInputS( "string: check: equal: second string
 = ", "a" )

 // e.g.  IF FNEscapeB( s2 ) RETURN() ENDIF

 // e.g.  Message( FNStringCheckEqualB( s1, s2 ) ) // gives e.g. TRUE
 when string1 is equal to string2

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 //

 // // <F12> PROCMessage( FNStringCheckEqualB( "knud", "knud" ) ) //
 gives TRUE

 // // <F12> PROCMessage( FNStringCheckEqualB( "knud", "van" ) ) //
 gives FALSE

 RETURN( s1 == s2 )

END

// library: math: check: logic: not (filenamemacro=checmaln.s) [kn, ri,
tu, 15-05-2001 16:54:21]

INTEGER PROC FNMathCheckLogicNotB( INTEGER B )

 // e.g. PROC Main()

 // e.g.  STRING s[255] = FNInitializeNewStringS()

 // e.g.  s = FNStringGetInputS( "math: check: logic: not: number = ",
 "1" )

 // e.g.  IF FNEscapeB( s ) RETURN() ENDIF

 // e.g.  Message( FNMathCheckLogicNotB( FNStringGetToIntegerI( s ) ) )

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( NOT B )

END

// library: string: check: equal: case: insensitive: convert first the
two strings to upper case, then compare for equality
(filenamemacro=checstcj.s) [kn, ri, th, 18-10-2001 23:04:06]

INTEGER PROC FNStringCheckEqualCaseInsensitiveB( STRING s1, STRING s2 )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  STRING s2[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: check: equal: case:
 insensitive: first string = ", "tESTiNg" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  s2 = FNStringGetInputS( "string: check: equal: case:
 insensitive: second string = ", "TeStING" )

 // e.g.  IF FNEscapeB( s2 ) RETURN() ENDIF

 // e.g.  Message( FNStringCheckEqualCaseInsensitiveB( s1, s2 ) ) //
 gives TRUE when the characters in both strings are equal (case
 insensitive)

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( FNStringCheckEqualB( FNStringGetCaseUpperS( s1 ),
 FNStringGetCaseUpperS( s2 ) ) )

END

// library: token: check: is: parameter (filenamemacro=chectoip.s) [kn,
ni, we, 24-09-2003 18:50:18]

INTEGER PROC FNTokenCheckIsParameterB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsParameterB( "parameter1" ) ) // gives
 e.g. TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNTokenCheckIsVariableB( firstwordS ) ) // assume a parameter
 (to keep the simplicity) is a (usual) variable name

END

// library: token: check: is: comma (filenamemacro=chectoic.s) [kn, ni,
we, 24-09-2003 18:50:22]

INTEGER PROC FNTokenCheckIsCommaB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsCommaB( ", test" ) ) // gives TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNStringCheckEqualB( firstwordS, "," ) )

END

// library: token: check: is: parenthesis: close
(filenamemacro=chectopc.s) [kn, ni, we, 24-09-2003 18:50:15]

INTEGER PROC FNTokenCheckIsParenthesisCloseB( STRING s )

 // e.g. PROC Main()

 // e.g.  Message( FNTokenCheckIsParenthesisCloseB( ") test" ) ) //
 gives TRUE

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 STRING firstwordS[255] = ""

 firstwordS = FNStringGetCarS( s ) // get first word

 RETURN( FNStringCheckEqualB( firstwordS, ")" ) )

END

// library: string: line: length: what is the length
(filenamemacro=getstgle.s) [kn, ri, wo, 25-11-1998 20:20:58]

INTEGER PROC FNStringGetLengthI( STRING s )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: line: length: string = ",
 "this is a test" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  Message( FNStringGetLengthI( s1 ) ) // gives e.g. 14

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 //

 // e.g. // <F12> Message( FNStringGetLengthI( "knud" ) ) // gives 4

 // e.g. // <F12> Message( FNStringGetLengthI( "the" ) ) // gives 3

 RETURN( Length( s ) )

END

// library: string: get: case: uppercase/lowercase: upper case: convert
characters in string to upper case (filenamemacro=getstcuq.s) [kn, zoe,
wo, 30-06-1999 01:21:07]

STRING PROC FNStringGetCaseUpperS( STRING s )

 // e.g. PROC Main()

 // e.g.  STRING s1[255] = FNInitializeNewStringS()

 // e.g.  s1 = FNStringGetInputS( "string: get: case: upper: string =
 ", "This is a test" )

 // e.g.  IF FNEscapeB( s1 ) RETURN() ENDIF

 // e.g.  Message( FNStringGetCaseUpperS( s1 ) ) // gives e.g. "THIS IS
 A TEST"

 // e.g. END

 // e.g.

 // e.g. <F12> Main()

 RETURN( Upper( s ) )

END

--- cut here ----------------------------------------------------------

Internet: see also:

TSE: Parser: Simple: Syntax: Structure: Parameter: How to 
parse '(parameter1,..., parameterlast)'?

http://www.faqts.com/knowledge_base/view.phtml/aid/24668/fid/1236

----------------------------------------------------------------------