2013-03-29 132 views
0

这个问题如下flex+bison output in a glib's hash container 的讨论让我重新发布它(一些讨论后,最后一个职位仍然没有答案。) 我想分析使用Flex和野牛一个中文提供文件,并将使用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,它正确打印哈希表的内容,但如果我们希望conten t通过取消注释行号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 [email protected] 

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

和样本中文提供的文件是:

@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", 
} 

如果有人向我展示某种方式正确填充散列表,我将不胜感激。 请帮忙。

回答

0

它看起来像你只是将所有的数据转储到一个单一的哈希表。因此,第一个条目将进入散列表下方的键TYPE,ID,Title, Publisher等等。然后第二个条目将覆盖那些相同的键和值(除了它使用Author而不是author),导致混合两个条目。

如果你想使用散列表,我会希望你会需要每个条目的散列表,以及可用散列表来将ID映射到包含该条目的信息的散列表。或者,您可以将每个条目解析为列表或其他容器结构,并将单个哈希表映射ID映射到列表/容器。

你也泄漏内存非常迅速,因为你分配每个KEYVALUE新的内存,然后复制内存放入散列表。

+0

你可以好好解释一下hashtable的hashtable吗? – BaRud