parsing bibtex using gscanner



Dear Friends,
I am trying to parse a bibtex file using gscanner.
The problem is that, due to many formats accepted by bibtex, it seems
bit hard to parse it.
What I mean is as long as the bibtex is of the form key="some value",
then g_scanner_get_next_token can get the string.
But it fails if it is in the format key={value}.

I am attaching my code. Some help (outside using btparse/ bison )is
needed.
guint parse_entry (GScanner   *scanner,
    GHashTable *table)
{
  int tokount;
  /* Entry starts with @ */
  g_scanner_get_next_token (scanner);
  if (scanner->token != '@')
    return G_TOKEN_ERROR;

  /* Now get identifier */
  g_scanner_get_next_token (scanner);
  if (scanner->token != G_TOKEN_IDENTIFIER)
    return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup ("type"),
      g_strdup (scanner->value.v_identifier));

  /* Brace */
  g_scanner_get_next_token (scanner);
  if (scanner->token != G_TOKEN_LEFT_CURLY){
    return G_TOKEN_ERROR;}
  else
    tokount += tokount;

  /* ID */
  g_scanner_get_next_token (scanner);
  if (scanner->token != G_TOKEN_IDENTIFIER)
    return G_TOKEN_ERROR;

  g_hash_table_insert (table, g_strdup ("id"),
      g_strdup (scanner->value.v_identifier));

  while (TRUE)
  {
    char *key, *val;

    g_scanner_get_next_token (scanner);
    if (scanner->token != G_TOKEN_COMMA)
      return G_TOKEN_ERROR;


    g_scanner_get_next_token (scanner);
    if (scanner->token != G_TOKEN_IDENTIFIER)
      return G_TOKEN_ERROR;

    key = g_strdup (scanner->value.v_identifier);

/*    g_scanner_peek_next_token (scanner);
    if (scanner->token == G_TOKEN_LEFT_CURLY)
      tokount += tokount;*/

    g_scanner_get_next_token (scanner);
    if (scanner->token != '=')
    {
      g_free (key);
      return G_TOKEN_ERROR;
    }

    g_scanner_get_next_token (scanner);
    if (scanner->token != G_TOKEN_STRING)
    {
      g_free (key);
      return G_TOKEN_ERROR;
    }

    val = g_strdup (scanner->value.v_string);
    g_hash_table_insert(table, key, val);

    g_scanner_peek_next_token (scanner);
    if (scanner->next_token == G_TOKEN_RIGHT_CURLY)
      break;
  }

  g_scanner_get_next_token (scanner);
  return G_TOKEN_NONE;
}




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]