Beispiel #1
0
__GTL_BEGIN_NAMESPACE

struct GML_pair* GML_parser (FILE* source, struct GML_stat* stat, int open) {
    
    struct GML_token token;
    struct GML_pair* pair;
    struct GML_pair* list;
    struct GML_pair* tmp = NULL;
    struct GML_list_elem* tmp_elem;

    assert (stat);

    pair = (struct GML_pair*) malloc (sizeof (struct GML_pair));
    pair->next = NULL;
    list = pair;

    for (;;) {
	token = GML_scanner (source);
	
	if (token.kind == GML_END) {
	    if (open) {
		stat->err.err_num = GML_OPEN_BRACKET;
		stat->err.line = GML_line;
		stat->err.column = GML_column;
		free (pair);

		if (tmp == NULL) {
		  return NULL;
		} else {
		  tmp->next = NULL;
		  return list;
		}
	    }

	    break;

	} else if (token.kind == GML_R_BRACKET) {
	    if (!open) {
		stat->err.err_num = GML_TOO_MANY_BRACKETS;
		stat->err.line = GML_line;
		stat->err.column = GML_column;
		free (pair);

		if (tmp == NULL) {
		  return NULL;
		} else {
		  tmp->next = NULL;
		  return list;
		}
	    }

	    break;

	} else if (token.kind == GML_ERROR) {
	    stat->err.err_num = token.value.err.err_num;
	    stat->err.line = token.value.err.line;
	    stat->err.column = token.value.err.column;
	    free (pair);
	      
	    if (tmp == NULL) {
		return NULL;
	    } else {
		tmp->next = NULL;
		return list;
	    }

	} else if (token.kind != GML_KEY) {
	    stat->err.err_num = GML_SYNTAX;
	    stat->err.line = GML_line;
	    stat->err.column = GML_column;
	    free (pair);
	   
	    if (token.kind == GML_STRING) {
		free (token.value.str);
	    }

	    if (tmp == NULL) {
		return NULL;
	    } else {
		tmp->next = NULL;
		return list;
	    }
	}
	   
	if (!stat->key_list) {
	    stat->key_list = (struct GML_list_elem*) 
		malloc (sizeof (struct GML_list_elem));
	    stat->key_list->next = NULL;
	    stat->key_list->key = token.value.str;
	    pair->key = token.value.str;
	
	} else {
	    tmp_elem = stat->key_list;
	    
	    while (tmp_elem) {
		if (!strcmp (tmp_elem->key, token.value.str)) {
		    free (token.value.str);
		    pair->key = tmp_elem->key;
		    break;
		}
		
		tmp_elem = tmp_elem->next;
	    }
	
	    if (!tmp_elem) {
		tmp_elem = (struct GML_list_elem*)
		    malloc (sizeof (struct GML_list_elem));
		tmp_elem->next = stat->key_list;
		stat->key_list = tmp_elem;
		tmp_elem->key = token.value.str;
		pair->key = token.value.str;
	    }
	}
	
	token = GML_scanner (source);

	switch (token.kind) {
	case GML_INT:
	    pair->kind = GML_INT;
	    pair->value.integer = token.value.integer;
	    break;

	case GML_DOUBLE:
	    pair->kind = GML_DOUBLE;
	    pair->value.floating = token.value.floating;
	    break;

	case GML_STRING:
	    pair->kind = GML_STRING;
	    pair->value.str = token.value.str;
	    break;

	case GML_L_BRACKET:
	    pair->kind = GML_LIST;
	    pair->value.list = GML_parser (source, stat, 1);
	    
	    if (stat->err.err_num != GML_OK) {
		return list;
	    }

	    break;

	case GML_ERROR:
	    stat->err.err_num = token.value.err.err_num;
	    stat->err.line = token.value.err.line;
	    stat->err.column = token.value.err.column;
	    free (pair);
		
	    if (tmp == NULL) {
		return NULL;
	    } else {
		tmp->next = NULL;
		return list;
	    }

	default:    
	    stat->err.line = GML_line;
	    stat->err.column = GML_column;
	    stat->err.err_num = GML_SYNTAX;
	    free (pair);

	    if (tmp == NULL) {
		return NULL;
	    } else {
		tmp->next = NULL;
		return list;
	    }
	}

	tmp = pair;
	pair = (struct GML_pair*) malloc (sizeof (struct GML_pair));
	tmp->next = pair;
	pair->next = NULL;
    }

    stat->err.err_num = GML_OK;
    free (pair);
    
    if (tmp == NULL) {
	return NULL;
    } else {
	tmp->next = NULL;
	return list;
    }
}
Beispiel #2
0
struct GML_token GML_scanner (FILE* source) {
    
    unsigned int cur_max_size = INITIAL_SIZE;
    static char buffer[INITIAL_SIZE];
    char* tmp = buffer;
    char* ret = tmp;
    struct GML_token token;
    int is_float = 0;
    unsigned int count = 0;
    int next;
    char ISO_buffer[8];
    int ISO_count;

    assert (source != NULL);
    
    /* 
     * eliminate preceeding white spaces
     */
    
    do {
	next = fgetc (source);
	GML_column++;

	if (next == '\n') {
	    GML_line++;
	    GML_column = 1;
	}
	
    } while (isspace (next) && next != EOF);

    if (next == EOF) {

       /*
	* reached EOF
	*/
    
       token.kind = GML_END;
       return token; 
       
    } else if (isdigit (next) || next == '.' || next == '+' || next == '-') {
	
	/* 
	 * floating point or integer 
	 */
	    
	do {
	    if (count == INITIAL_SIZE - 1) {
		token.value.err.err_num = GML_TOO_MANY_DIGITS;
		token.value.err.line = GML_line;
		token.value.err.column = GML_column + count;
		token.kind = GML_ERROR;
		return token;
	    }

	    if (next == '.' || next == 'E') {
		is_float = 1;
	    }

	    buffer[count] = next;
	    count++;
	    next = fgetc (source);

	} while (!isspace(next) && next != ']' && next != EOF);

	buffer[count] = 0;

	if (next == ']') {
	   ungetc (next, source);
	}

	if (next == '\n') {
	   GML_line++;
	   GML_column = 1;
	} else {
	   GML_column += count;
	}
	    
	if (is_float) {
	    token.value.floating = atof (tmp);
	    token.kind = GML_DOUBLE;
	} else {
	    token.value.integer = atol (tmp);
	    token.kind = GML_INT;
	}

	return token;
	
    } else if (isalpha (next) || next == '_') {
	
	/*
	 * key
	 */
	        
	do {
	    if (count == cur_max_size - 1) {
		*tmp = 0;
		tmp =  (char*) malloc(2 * cur_max_size * sizeof (char));
		strcpy (tmp, ret);
		
		if (cur_max_size > INITIAL_SIZE) {
		    free (ret);
		}

		ret = tmp;
		tmp += count;
		cur_max_size *= 2;
	    }
	    
	    *tmp++ = next;
	    count++;
	    next = fgetc (source);
	} while (isalnum (next) || next == '_');

	if (next == '\n') {
	   GML_line++;
	   GML_column = 1;
	} else {
	   GML_column += count;
	}
	
	if (next == '[') {
	   ungetc (next, source);
	} else if (!isspace (next)) {
	   token.value.err.err_num = GML_UNEXPECTED;
	   token.value.err.line = GML_line;
	   token.value.err.column = GML_column + count;
	   token.kind = GML_ERROR;
	   
	   if (cur_max_size > INITIAL_SIZE) {
	      free (ret);
	   }
    
	   return token;   
	} 

	*tmp = 0;
	token.kind = GML_KEY;
	token.value.string = (char*) malloc((count+1) * sizeof (char));
	strcpy (token.value.string, ret);
	
	if (cur_max_size > INITIAL_SIZE) {
	    free (ret);
	}
    
	return token;

    } else {
	/*
	 * comments, brackets and strings
	 */

	switch (next) {
	case '#':
	    do {
		next = fgetc (source);
	    } while (next != '\n' && next != EOF);
		
	    GML_line++;
	    GML_column = 1;
	    return GML_scanner (source);

	case '[':
	    token.kind = GML_L_BRACKET;
	    return token;

	case ']':
	    token.kind = GML_R_BRACKET;
	    return token;
		
	case '"':
	    next = fgetc (source);
	    GML_column++;

	    while (next != '"') {
		
		if (count >= cur_max_size - 8) {
		    *tmp = 0;
		    tmp = (char*) malloc (2 * cur_max_size * sizeof(char));
		    strcpy (tmp, ret);
		    
		    if (cur_max_size > INITIAL_SIZE) {
			free (ret);
		    }

		    ret = tmp;
		    tmp += count;
		    cur_max_size *= 2;
		}
	    
		if (next == '&') {
		  ISO_count = 0;

		  while (next != ';') {
			if (next == '"' || next == EOF) {
			  ungetc (next, source);
			  ISO_count = 0;
			  break;
			}
			
			if (ISO_count < 8) {
			  ISO_buffer[ISO_count] = next;
			  ISO_count++;
			}

			next = fgetc (source);
		  }
			
		  if (ISO_count == 8) {
			ISO_count = 0;
		  }

		  if (ISO_count) {
			ISO_buffer[ISO_count] = ';';
			ISO_count++;
			next = GML_search_ISO (ISO_buffer, ISO_count);
			ISO_count = 0;
		  } else {
			next = '&';
		  }
		} 

		*tmp++ = next;
		count++;
		GML_column++;
			
		next = fgetc (source);

		if (next == EOF) {
		    token.value.err.err_num = GML_PREMATURE_EOF;
		    token.value.err.line = GML_line;
		    token.value.err.column = GML_column + count;
		    token.kind = GML_ERROR;
		    
		    if (cur_max_size > INITIAL_SIZE) {
			free (ret);
		    }
			
		    return token;
		}

		if (next == '\n') {
		    GML_line++;
		    GML_column = 1;
		}
	    }

	    *tmp = 0;
	    token.kind = GML_STRING;
	    token.value.string = (char*) malloc((count+1) * sizeof (char));
	    strcpy (token.value.string, ret);
	    
	    if (cur_max_size > INITIAL_SIZE) {
		free (ret);
	    }

	    return token;
	    
	default:
	    token.value.err.err_num = GML_UNEXPECTED;
	    token.value.err.line = GML_line;
	    token.value.err.column = GML_column;
	    token.kind = GML_ERROR;
	    return token;
	}		
    }
}