0

この質問は、glib のハッシュ コンテナーでの flex+bison 出力の議論に続きます 。再投稿させてください (最後の投稿は、いくつかの議論の後、未回答のままです。) flex と bison を使用して bibtex ファイルを解析し、gtk ライブラリを使用してそれらのデータを表示します( Cで)。レクサーは

%{
#include "bib.tab.h"
%}

%%
[A-Za-z][A-Za-z0-9]*      { yylval.sval = strdup(yytext); return KEY; }
\"([^\"]|\\.)*\"|\{([^\"]|\\.)*\}  { yylval.sval = strdup(yytext); return VALUE; }
[ \t\n]                   ; /* ignore whitespace */
[{}@=,]                   { return *yytext; }
.                         { fprintf(stderr, "Unrecognized character %c in input\n", *yytext); }
%%

パーサーは次のとおりです。

%{
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gstdio.h>
#include <fcntl.h>
enum
{
  COL_BIB_KEY=0,
  COL_BIB_TYPE, COL_BIB_AUTHOR, COL_BIB_YEAR,
  NUM_COLS} ;
#define slen 1024
GHashTable* table;
GtkTreeIter siter;
GtkListStore *store;
%}

// Symbols.
%union
{
    char    *sval;
};
%token <sval> VALUE
%token <sval> KEY
%token OBRACE
%token EBRACE
%token QUOTE
%token SEMICOLON 

%start Input
%%
Input: 
     /* empty */ 
     | Input Entry ;  /* input is zero or more entires */
Entry: 
     '@' KEY '{' KEY ','{ g_hash_table_insert(table, g_strdup("TYPE"), g_strdup($2));
                  g_hash_table_insert(table, g_strdup("ID"), g_strdup($4));
          g_printf("%s:%s\n","KEY=>",g_hash_table_lookup(table,"TYPE"));
//                  g_printf("%s: %s\n", $2, $4);
              } 
     KeyVals '}' 
     ;
KeyVals: 
       /* empty */ 
       | KeyVals KeyVal ; /* zero or more keyvals */
KeyVal: 
      KEY '=' VALUE ',' { g_hash_table_insert(table, g_strdup($1), g_strdup($3));
//                          g_printf("%s: %s\n", $1, $3); 
              };

%%

int yyerror(char *s) {
  printf("yyerror : %s\n",s);
}

int main(int argc, char** argv) {
gtk_init(&argc, &argv);
GtkWidget  *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);    
  GtkWidget *tree=gtk_tree_view_new();
  setup_tree(tree);

gtk_container_add (GTK_CONTAINER (window), tree);
store= gtk_list_store_new (NUM_COLS, 
      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
  table = g_hash_table_new(g_str_hash, g_str_equal);
gint i;
do{
   g_hash_table_remove_all (table);
   yyparse();
   parse_entry (table);
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (store));
g_object_unref (store);
  }
  while(!EOF);
  g_hash_table_destroy (table);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
void parse_entry (GHashTable *table)
{
  GHashTableIter iter;
  gchar *key, *val;
  char *keys[] = {"id", "type", "author", "year", "title", "publisher", "editor", 
    "volume", "number", "pages", "month", "note", "address", "edition", "journal",
    "series", "book", "chapter", "organization", NULL};
  char *vals[] = {NULL,  NULL,  NULL, NULL, NULL,
    NULL,  NULL,  NULL, NULL, NULL,
    NULL,  NULL,  NULL, NULL, NULL,
    NULL,    NULL,  NULL, NULL, NULL};

  gchar **kiter;
  gint i;
  g_hash_table_iter_init (&iter, table);
  while (g_hash_table_iter_next (&iter, (void **)&key, (void **)&val))
  {
    for (kiter = keys, i = 0; *kiter; kiter++, i++)
    {
      if (!g_ascii_strcasecmp(*kiter, key))
      {
    vals[i] = g_strndup(val,slen);
//    g_printf("%s:%s\n",keys[i],g_hash_table_lookup(table,keys[i]));
    g_printf("%d=>%s:%s\n",i,keys[i],vals[i]);
    break;
      }
    }
  }
    gtk_list_store_append (store, &siter);
    gtk_list_store_set (store, &siter,
      COL_BIB_TYPE,         vals[COL_BIB_TYPE],
      COL_BIB_KEY,      vals[COL_BIB_KEY],
      COL_BIB_AUTHOR,       vals[COL_BIB_AUTHOR],
      COL_BIB_YEAR,         vals[COL_BIB_YEAR],
      -1);
}

void setup_tree(GtkWidget *tree){
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;

renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes
("Type", renderer, "text",COL_BIB_TYPE , NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes
("Author", renderer, "text", COL_BIB_AUTHOR, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes
("Year", renderer, "text",COL_BIB_YEAR, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
g_printf("HIIIIIIIIIi");
}

問題は、リストビューではなく、ハッシュ テーブルに入力することです (リスト ストアを囲んで、人々が私の最終目標を確認し、改善を提案できるようにしました)。

g_printf("%s:%s\n",$1,g_hash_table_lookup(table,$1));

行番号 50 では、ハッシュ テーブルのコンテンツが正しく出力されますが、行番号 105 のコメントを外してコンテンツが必要な場合は、最後のエントリのみが解析されます。したがって、私の推測では、ハッシュ ファイルを正しく処理していません (行番号 97 ~ 107 でしょうか?)。

メイクファイルは次のとおりです。

CC=gcc -g
FLEX=flex
BISON=bison
LIBS=lfl
PROG=parse

${PROG}:bib.y bib.l
    ${BISON} -d bib.y
    ${FLEX} -i bib.l
    ${CC} lex.yy.c bib.tab.c `pkg-config --cflags --libs glib-2.0``pkg-config --cflags --libs gtk+-3.0` -${LIBS} -o $@

clean:
    rm -f lex.yy.c bib.tab.c ${PROG}
    touch bib.l bib.y

サンプルの bibtex ファイルは次のとおりです。

@Book{a1,
    Title="ASR",
    Publisher="oxf",
    author = "a {\"m}ook, Rudra Banerjee",
    Year="2010",
    Address="UK",
    Edition="1",
}
@Booklet{ab19,
    Author="Rudra Banerjee and A. Mookerjee",
    Title="Fe{\"Ni}Mo",
    Editor="sm1",
    Title="sm2",
    Publisher="sm3",
    Volume="sm4",
    Number="sm5",
    Pages="sm6",
    Month="sm8",
    Note="sm9",
    Key="sm10",
    Year="1980",
    Address="osm1",
    Edition="osm2",
}

誰かがハッシュテーブルを正しく設定する方法を教えてくれたらありがたいです. 助けてください。

4

1 に答える 1

0

すべてのデータを 1 つのハッシュ テーブルにダンプしているようです。TYPEしたがって、最初のエントリはキー、IDTitle、などの下のハッシュ テーブルに入りますPublisher。次に、2 番目のエントリが同じキーと値を上書きし (ただし、Authorの代わりに使用しますauthor)、2 つのエントリが混在します。

ハッシュテーブルを使用する場合は、各エントリのハッシュ テーブルと、そのエントリの情報を含むハッシュ テーブルに ID をマップするためのハッシュ テーブルのハッシュ テーブルが必要になると思います。または、各エントリを解析してリストまたはその他のコンテナー構造にし、ID をリスト/コンテナーにマッピングする単一のハッシュテーブルを作成することもできます。

KEYまた、それぞれに新しいメモリを割り当てるかVALUE、メモリを複製してハッシュテーブルに入れるため、メモリリークが非常に急速に発生します。

于 2013-03-30T00:02:46.277 に答える