这个问题是在 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",
}
如果有人告诉我一些正确填充哈希表的方法,我将不胜感激。请帮忙。