2013-03-15 52 views
0

我已經在解析bib文件方面取得了相當大的進展,但是對於我目前的理解水平來說,下一步是非常艱難的。 我已經創建了野牛和Flex代碼,上面正確解析圍脖文件:在glib的散列容器中flex + bison輸出

%{ 
#include <stdio.h> 
%} 

// 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 ','{ printf("===========\n%s : %s\n",$2, $4); } 
    KeyVals '}' 
    ; 
KeyVals: 
     /* empty */ 
     | KeyVals KeyVal ; /* zero or more keyvals */ 
KeyVal: 
     KEY '=' VALUE ',' { printf("%s : %s\n",$1, $3); }; 

%% 

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

int main(void) { 
    yyparse(); 
} 

%{ 
#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); } 
%% 

我想在一個容器中的值。在過去的幾天裏,我閱讀了glib的大量文檔,併發布了散列容器,最適合我的情況。 下面是一個基本的哈希碼,一旦這些值被放入數組鍵和值中,它就具有正確的哈希值。

#include <glib.h> 
#define slen 1024 

int main(gint argc, gchar** argv) 
{ 
    char *keys[] = {"id", "type", "author", "year",NULL}; 
    char *vals[] = {"one", "Book", "RB", "2013", NULL}; 
    gint i; 
    GHashTable* table = g_hash_table_new(g_str_hash, g_str_equal); 
    GHashTableIter iter; 
    g_hash_table_iter_init (&iter, table); 
    for (i= 0; i<=3; i++) 
    { 
    g_hash_table_insert(table, keys[i],vals[i]); 
    g_printf("%d=>%s:%s\n",i,keys[i],g_hash_table_lookup(table,keys[i])); 
    } 
} 

問題是,我如何整合這兩個代碼,即在C代碼中使用解析的數據。 任何形式的幫助表示讚賞。

編輯:作爲解釋@UncleO迴應: @UncleO,

感謝您的評論。我不知道如何更好地解釋它。這是一個嘗試。 最近我的代碼(野牛)狀態:

%{ 
#include <stdio.h> 
#include <glib.h> 
%} 

// 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 ','{ printf("===========\n%s : %s\n",$2, $4); } 
    KeyVals '}' 
    ; 
KeyVals: 
     /* empty */ 
     | KeyVals KeyVal ; /* zero or more keyvals */ 
KeyVal: 
     KEY '=' VALUE ',' { printf("%s : %s\n",$1, $3); }; 

%% 

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

int main(void) { 
GHashTable* table = g_hash_table_new(g_str_hash, g_str_equal); 
    char *keys[] = {"id", "type", "author", "year",NULL}; 
    char *vals[] = {"one", "Book", "RB", "2013", NULL}; 
    gint i; 
    yyparse(); 
    GHashTableIter iter; 
    g_hash_table_iter_init (&iter, table); 
    for (i= 0; i<=3; i++) 
    { 
    g_hash_table_insert(table, keys[i],vals[i]); 
    g_printf("%d=>%s:%s\n",i,keys[i],g_hash_table_lookup(table,keys[i])); 
    } 
} 

與法文件不變。數組鍵和val的元素用於測試目的。 輸入文件的實例是

@Booklet{ab19, 
    Author="Rudra Banerjee and A. Mookerjee", 
    Editor="sm1", 
    Title="sm2", 
    Publisher="sm3", 
    Volume="sm4", 
    Issue="sm5", 
    Page="sm6", 
    Month="sm8", 
    Note="sm9", 
    Key="sm10", 
    Year="1980", 
    Add="osm1", 
    Edition="osm2", 
} 

所以,在解析,代碼正確地解析值。我想使用解析輸入中的值插入散列表中,這對每個輸入都是不同的。因此,我的最終目標是從代碼中移除數組鍵和val;

g_hash_table_insert(table, <$1 from bison>,<$3 from bison>); 

這是否有道理:和線

g_hash_table_insert(table, keys[i],vals[i]); 

應該像更換?

編輯:=====================================

@ Uncle0:這是更新的代碼;可能我的意圖是明確的這一個。我想了很多解決這個問題,但同時從野牛線打印是打印的東西如預期,其並非如此,而從哈希表打印(代碼的最後一行)

%{ 
#include <stdio.h> 
#include <glib.h> 
#define slen 1024 
GHashTable* table; 
%} 

// 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, "TYPE", $2); 
        g_hash_table_insert(table, "ID", $4); 
       g_printf("%s: %s\n", $2, $4); 
       } 
    KeyVals '}' 
    ; 
KeyVals: 
     /* empty */ 
     | KeyVals KeyVal ; /* zero or more keyvals */ 
KeyVal: 
     KEY '=' VALUE ',' { g_hash_table_insert(table, $1, $3); 
          g_printf("%s: %s\n", $1, $3); }; 

%% 

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

int main(void) { 
    table = g_hash_table_new(g_str_hash, g_str_equal); 
gint i; 
do{ 
    g_hash_table_remove_all (table); 
    yyparse(); 
    parse_entry (table); 
// g_printf("%s:%s\n","Author=>",g_hash_table_lookup(table,"Author")); 
// g_printf("%s:%s\n","KEY=>",g_hash_table_lookup(table,"KEY")); 
    } 
    while(!EOF); 
} 
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); 
    break; 
     } 
    g_printf("%d=>%s:%s\n",i,keys[i],vals[i]); 
    } 
    } 
} 

回答

1

你沒有已經清楚你想要對輸入做什麼,但是這裏有一個解釋讓你開始。

flex將採用正則表達式的文件並生成一個名爲yylex()的函數。

野牛將採取您的語法文件併產生一個稱爲yyparse()的函數,該函數重複使用yylex()函數來標記字符串。 main()函數只會調用yyparse()一次,並且每次yyparse()函數都匹配語法中的規則時,它將執行您指定的代碼片段。現在,你只是打印值,但你可以做其他事情,比如插入哈希表或任何你想要的。

grammar.y文件在yyparse()的定義和之後的代碼之前有代碼段。如果你願意,可以把main()函數放在這個文件的末尾,但是最好把它放在另一個文件中作爲鏈接。通常,main()函數會執行諸如打開讀取輸入等操作,然後調用yyparse()執行大部分工作。在yyparse()返回後,main可以清理。

編輯:嗨樓陀羅,

我看你想保留的main()的語法文件。沒關係。

現在您只需更改片段中的printf語句以插入表格中,table變量必須在main()之外聲明以便yyparse()查看它。

%{ 
#include <stdio.h> 
#include <glib.h> 

GHashTable* table; 

%} 

// 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 ','{ printf("===========\n%s : %s\n",$2, $4); } 
    KeyVals '}' 
    ; 
KeyVals: 
     /* empty */ 
     | KeyVals KeyVal ; /* zero or more keyvals */ 
KeyVal: 
     KEY '=' VALUE ',' { g_hash_table_insert(table, $1, $3); printf("%s : %s\n",$1, $3); }; 

%% 

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

int main(void) { 
    table = g_hash_table_new(g_str_hash, g_str_equal); 

    yyparse(); 
} 

你確定你不想對數據中的第一項做任何事嗎?好像你沒有使用它們做任何事情。

+0

感謝您的評論。我不知道如何更好地解釋它。這是一個嘗試。 我的代碼(野牛)的最新狀態是: – BaRud 2013-03-17 22:28:32

+0

@Rudra進行了一些更改。 – UncleO 2013-03-17 23:48:22

+0

Hi @UncleO, 感謝您的回覆。 是的,我會以同樣的方式與第2個任期使用它們,以及: 'g_hash_table_insert(表中,「類型」,$ 1) g_hash_table_insert(表中,「ID」,$ 3)' 讓我看看怎麼樣遠遠的我可以去這個,我會回到這個線程。 再次感謝。 – BaRud 2013-03-18 00:43:37