Parsing Methods

In this section we will look in more depth at the different methods that is used to parse the defs files and the resulting Vector.

parseSExpr

parseFile calls parseSExpr to parse everything in the round braces. Using recursion parseExpr reads the contents and stores it in a Vector (forming a tree) that it returns. Here follows three examples:

Example 4-1. .defs Snippet:

(define-object GtkButton (GtkContainer)
  (fields
   (GtkWidget child)
   (bool in_button)
   (bool button_down)))

Example 4-1 will be parsed into the following Vector:

define-object
    |
GtkButton
    |
    -------- GtkContainer
    |
    -------- field -------- | -------- | -------- |
                            |          |          |
		        GtkWidget    bool       bool
		          child   in_button  button_down

Example 4-2. .defs Snippet:

(define-func gtk_button_new
  GtkWidget
  ())

(define-func gtk_button_new_with_label
  GtkWidget
  ((string label)))

Example 4-2 will be parsed into the following Vector:

define-func                    define-func
    |                              |
gtk_button_new                 gtk_button_new_with_label
    |                              |
GtkWidget                      GtkWidget
    |                              |
    --------|                      -------- |
            |                               |
                                         string
                                         label

Example 4-3. .defs Snippet:

(define-func gtk_button_pressed
  none
  ((GtkButton button)))

Example 4-3 will be parsed into the following Vector:

define-func
    |
gtk_button_pressed
    |
  none
    |
    --------|
            |
        GtkButton
         button

parseDefineObject

The method parseDefineObject takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

define-object
    |
"Object name"
    |
    -------- "Object inherited from"
    |                                 (Everything below this is not used)
    -------- field -------- | ... (Zero or more)
                            | 
		      "Variable type"
		        "Variable"

Everything between "" is a description and everything that is not between them is always there.

parseDefineObject retrieves the Object name from the Vector as well as the name of the Object it is inherited from. It adds the type(s) of objects to the Vector typesnames (if it is not already in it) via the addTypeDefinition method. It then defines and adds a ClassDefinition to the classnames vector via the addClassDefinition method.

parseDefineEnum

The method parseDefineEnum takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

define-enum||define-string-enum
    |
"Enum name"
    |
    -------- "Scheme name" -------- "Gtk enum value"
   ... (Zero(?) or more)

Everything between "" is a description and everything that is not between them is always there. || indicates a standard OR, or in laymens terms means that either the one value or the other can be there (but not both).

parseDefineEnum handles both define-enum and define-string-enum the same way since the structure is the same as can be seen from the above. parseDefineEnumfirst get the enum name from the Vector. It then check and set all typesnames that is an Object and that should be an enum and change it's type to an enum.

parseDefineEnum then parses through the rest of the Vector and remove the Scheme name. It creates an TypeDefinition for each Gtk enum value and add it to the Vector typesnames (if it is not already in it) using the addTypeDefinition method. It then creates an EnumDefinition and adds it to the Vector enumsnames using the addEnumDefinition method.

parseDefinedFlags

The method parseDefineFlags takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

define-flags
    |
"Flags name"
    |
    -------- "Scheme name" -------- "Gtk flag value"
   ... (Zero(?) or more)

Everything between "" is a description and everything that is not between them is always there. || indicates a standard OR, or in laymens terms means that either the one value or the other can be there (but not both).

The parseDefineFlags method is VERY similar to the parseDefineEnum method (and is incomplete). parseDefineFlags first gets the enum name from the Vector. It then checks and sets all typesnames that is an Object and that should be an enum and change it's type to an enum. (Do not quote me on this since as far as I can see it currently never happens.)

parseDefineFlags then parses through the rest of the Vector and removes the Scheme name. It creates an TypeDefinition for each Gtk flag value and adds it to the Vector typesnames (if it is not already in it) using the addTypeDefinition method. It then creates an FlagDefinition and adds it to the Vector enumsnames using the addEnumDefinition method.

parseDefineFunc

The method parseDefineFunc takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

define-func
    |
"Object name"
    |
"Object returned"
    |
    -------- | ... (Zero or more)
    |        | 
    |  "Variable type"
    |    "Variable"
    |      [ |     
    |        -------- null-ok ]
    |      [ |
    |         -------- |
    |                  |
    |                  =
    |          "Default value" ]
  [ |              
    -------- java-code (continued on next line)
                 -------- "Pre code" -------- "Java call" -------- "Post code"]

Everything between "" is a description and everything that is not between them is always there. Everything between [] is optional.

parseDefineFunc is more complex than parseDefineObject since it adds the variables and additonal arguments. It also have to take the constructors and the java-code into consideration.

parseDefineFunc first get the method name from the Vector and then see whether it is a constructor (contains new), it then gets the return type and adds it to the Vector typesnames (if it is not already in it) via the addTypeDefinition method. It then parse the variable and argument list (using args).

The Vector args is used to store the variable and argument list. For each Vector in args the argument type is extracted and added to the Vector typesnames (if it is not already in it) via the addTypeDefinition method. The variable type is extracted and this is then added to a list of arguments (a). The default value and null-ok is then parsed (This is not handled later on).

It then parse the java-code section if it is available. (So far it is only used with gnome_init.) The pre call code, java call code and post call code is then parsed if the java-code section is available.

If the function is a constructor a new Constructor is created and added to constantnames via the addConstructorDefinition method after the pre call code, the java call and the post call code is set. If the function is not a constructor a new Method is created and added to methodnames via the addMethodDefinition method after the pre call code, the java call code and the post call code is set.

parseDefineBoxed

The method parseDefineBoxed takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

define-boxed
    |
"Object name"
    |                           (Everything below this is not used)
    -------- copy -------- "Copy/Ref function"
    |
    -------- free -------- "Free/Unref function"
  [ |
    -------- size -------- sizeof("Object name") ]
  [ |
    -------- conversion -------- "Conversion function" ]
  [ |
    -------- field -------- | ... (Zero or more)
                            |
                      "Variable type"
		         "Variable"]

Everything between "" is a description and everything that is not between them is always there. Everything between [] is optional.

As one can see from the diagram most of the tree is not used and parseDefineBoxed is therefore relative simple.

parseDefineBoxed retrieves the boxed name from the Vector, it then adds the type to the Vector typesnames (if it is not already in it) via the addTypeDefinition method. It also creates a ClassDefinition and add it to classnames (if it is not already in it) via the addClassnamesDefinition method.

parseImport

The method parseImport takes the Vector generated by parseSExpr and parse it further. The Vector returned by parseSExpr is of the following structure:

import
    |
"Package name"

Everything between "" is a description and everything that is not between them is always there.

parseImport gets the package name from the Vector. It then adds the package to the Vector modules after removing the .defs extension.