# File lib/cgikit.rb, line 3304
                def parse(string, filename = '')
                        scanner = StringScanner.new( string, false )

                        # The way to use these local variables is bad.                       
                        definitions     = {}
                        in_attrs        = false
                        line_num        = 1                  
                        current_element = nil
                        element_name    = nil
                        element_type    = nil
                        term            = "(;|\n)"

                        # in the future, we may have to change this Proc object.
                        pos_proc = proc do 
                                "#{filename}:#{line_num}: "
                        end
                        
                        while scanner.rest?
                                # line break
                                if scanner.skip(/(\r)?\n/) then
                                        line_num += 1
                                        next
                                end

                                # skip commnet or space
                                if scanner.skip(/(?:#.*$|[ \r\f\t]+)/) then
                                        next
                                end

                                if in_attrs then
                                        # attribute
                                        if scanner.skip(/([a-zA-Z0-9_]+[\!\?]?)[ \r\f\t]*=[ \r\f\t]*/)
                                                key = scanner[1]

                                                # array and hash literal
                                                if scanner.skip(/^[^"'](.*)\[/) then
                                                        list   = nil
                                                        object = scanner[1]

                                                        if scanner.match?(/^(["'])/) then
                                                                # string literal
                                                                close = scanner[1]
                                                                if         close == '"' and scanner.skip(/"(.*?)"\]/)
                                                                elsif   close == "'" and scanner.skip(/'(.*?)'\]/)
                                                                else
                                                                        raise CKDParseError, \
                                                                                pos_proc.call << scanner.peek(60).inspect << \
                                                                                "\nString literal error. Or, \";\" doesn't exist."
                                                                end
                                                                list = "\"#{scanner[1]}\""
                                                        else
                                                                if scanner.skip(/([a-zA-Z0-9_\.\!\^^?]+)\][ \r\t\f]*#{term}/)
                                                                        list = scanner[1]
                                                                else
                                                                        raise CKDParseError, pos_proc.call << \
                                                                                scanner.peek(60).inspect << \
                                                                                "\nArray or Hash literal error. Or, \";\" doesn't exist.\n"
                                                                end
                                                        end
                                                        value = "#{object}[#{list}]"
                                                        line_num += value.count("\n")

                                                # value of attribute
                                                elsif scanner.match?(/^(["'])/) then
                                                        # string lietral
                                                        close = scanner[1]
                                                        if          close == '"' and scanner.skip(/"(.*?)"[ \r\f\t]*#{term}/m)
                                                        elsif    close == "'" and scanner.skip(/'(.*?)'[ \r\f\t]*#{term}/m)
                                                        else
                                                                raise CKDParseError, \
                                                                        pos_proc.call << scanner.peek(60).inspect << \
                                                                        "\nString literal error. Or, \";\" doesn't exist."
                                                        end

                                                        value = "\"#{scanner[1]}\""
                                                        line_num += value.count("\n")
                                                else
                                                        # others
                                                        #
                                                        # This regexp is not accurate.
                                                        if scanner.skip(/([a-zA-Z0-9_\.\!\^^?]+)[ \r\t\f]*#{term}/)
                                                                value = scanner[1]
                                                        else
                                                                raise CKDParseError, pos_proc.call << \
                                                                        scanner.peek(60).inspect << \
                                                                        "\nMethod name error. Or, \";\" doesn't exist." "\n" 
                                                        end
                                                end

                                                current_element[key] = value                      
                                                next
                                        end

                                        # end of definition
                                        if scanner.skip(/\s*\}/)
                                                definitions[element_name] = current_element
                                                current_element = nil
                                                in_attrs = false
                                                next
                                        end

                                        # skips space and separator.
                                        #
                                        # (ex.)
                                        # foo : CKString{;}
                                        if scanner.skip(/[ \r\t\f]*#{term}/)
                                                next
                                        end
                                else
                                        # extracts name of the element and its class
                                        # class's regexp is not precise.
                                if scanner.skip(/([a-zA-Z0-9_]+)\s*:\s*([a-zA-Z0-9_]+)\s*\{/)
                                        element_name = scanner[1]
                                        element_type = scanner[2]
                                        current_element = {}
                                        current_element['oid'] = element_name
                                        current_element['element'] = element_type

                                        if definitions.key? element_name then
                                                raise CKDParseError, pos_proc.call << \
                                                        scanner.peek(60).inspect << \
                                                        "\n'#{element_name}' definition is already existed." "\n" 
                                        end

                        
                                        in_attrs = true
                                        next
                                end
                        end

                        def_str = _pretty_print(definitions)
                                raise CKDParseError, pos_proc.call << scanner.peek(60).inspect << \
                                        "\nNot match any rule.\n\n" << def_str << "\n" 
                        end

                        # Now, there is no data to be parsed.                        
                        if in_attrs 
                                raise CKDParseError, pos_proc.call << \
                                        "The last element is not enclosed.\n\n"
                        end
                        
                        definitions
                end