C flex+;野牛在油嘴滑舌中的输出';s散列容器

C flex+;野牛在油嘴滑舌中的输出';s散列容器,c,hashtable,bison,glib,flex-lexer,C,Hashtable,Bison,Glib,Flex Lexer,我已经在解析bib文件方面取得了相当大的进展,但下一步对于我目前的理解水平来说是相当困难的。 我已经创建了bison和flex代码,可以正确解析上面的bib文件: %{ #include <stdio.h> %} // Symbols. %union { char *sval; }; %token <sval> VALUE %token <sval> KEY %token OBRACE %token EBRACE %token QUOTE %t

我已经在解析bib文件方面取得了相当大的进展,但下一步对于我目前的理解水平来说是相当困难的。 我已经创建了bison和flex代码,可以正确解析上面的bib文件:

%{
#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();
}
我想把这些值放在一个容器中。在过去的几天里,我阅读了大量关于glib的文档,并提出了最适合我的hash容器。 下面是一个基本的哈希代码,一旦将值放入数组键和VAL中,它就可以正确地使用哈希

#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]));
  }
}
因此,在解析时,代码正确解析值。我想使用要插入到哈希表中的解析输入中的值,每个输入的值都不同。 因此,我的最终目标是从代码中删除数组键和VAL;线路呢

g_hash_table_insert(table, keys[i],vals[i]);
应替换为以下内容:

g_hash_table_insert(table, <$1 from bison>,<$3 from bison>);
g_hash_table_insert(table,);
这有意义吗

编辑:=====================================

@0:这里是更新后的代码;也许我的意图很清楚。我正在努力解决这个问题,但是,虽然从bison line打印是按预期打印内容,但从哈希表(代码的最后一行)打印时却不是这样

%{
#包括
#包括
#定义slen 1024
GHashTable*表;
%}
//符号。
%联合
{
char*sval;
};
%代币价值
%令牌密钥
%象征性种族
%令牌交换
%象征性报价
%标记分号
%开始输入
%%
输入:
/*空*/
|输入项;/*输入为零或多个实体*/
条目:
'@'键'{'键','{g_哈希表}插入(表,“类型”,$2);
g_hash_table_insert(表,“ID”,4美元);
g_printf(“%s:%s\n”$2$4);
} 
KeyVals'}'
;
KeyVals:
/*空*/
|KeyVals KeyVal;/*零个或多个keyvals*/
凯瓦尔:
键“=”值“,”{g_hash_table_insert(table,$1,$3);
g_printf(“%s:%s\n”$1,$3);};
%%
int yyerror(字符*s){
printf(“YY错误:%s\n”,s);
}
内部主(空){
table=g_hash_table_new(g_str_hash,g_str_equal);
金特一世;
做{
g_散列_表_删除_全部(表);
yyparse();
解析_项(表);
//g_printf(“%s:%s\n”,“Author=>”,g_hash_table_lookup(table,“Author”));
//g_printf(“%s:%s\n”,“KEY=>”,g_哈希表查找(表,“KEY”));
}
而(!EOF);
}
无效解析_项(GHashTable*table)
{
GHashTableIter iter;
gchar*键,*val;
字符*键[]={“id”、“类型”、“作者”、“年份”、“标题”、“出版商”、“编辑”,
“卷”、“数”、“页”、“月”、“注”、“地址”、“版本”、“期刊”,
“系列”、“书籍”、“章节”、“组织”,空};
char*vals[]={NULL,NULL,NULL,NULL,NULL,
空,空,空,空,空,
空,空,空,空,空,
NULL,NULL,NULL,NULL,NULL,NULL};
gchar**kiter;
金特一世;
g_hash_table_iter_init(&iter,table);
while(g_hash_table_iter_next(&iter,(void**)和key,(void**)和val))
{
对于(kiter=keys,i=0;*kiter;kiter++,i++)
{
如果(!g_ascii_strcasecmp(*kiter,key))
{
vals[i]=g_strndup(val,slen);
打破
}
g_printf(“%d=>%s:%s\n”,i,键[i],VAL[i]);
}
}
}

您还不清楚要对输入执行什么操作,但这里有一个解释可以帮助您开始

flex将获取正则表达式文件并生成一个名为yylex()的函数

bison将获取您的语法文件并生成一个名为yyparse()的函数,该函数反复使用yylex()函数来标记字符串。main()函数只调用yyparse()一次,每次yyparse()函数匹配语法中的规则时,它都会执行您指定的代码片段。现在,您只需打印值,但您可以执行其他操作,如插入哈希表或执行任何您想要的操作

grammar.y文件包含yyparse()定义之前的代码部分和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();
}
%{
#包括
#包括
GHashTable*表;
%}
//符号。
%联合
{
char*sval;
};
%代币价值
%令牌密钥
%象征性种族
%令牌交换
%象征性报价
%标记分号
%开始输入
%%
输入:
/*空*/
|输入项;/*输入为零或多个实体*/
条目:
“@”键“{”键“{printf(===================\n%s:%s\n”,$2,$4);}
KeyVals'}'
;
KeyVals:
/*空*/
|KeyVals KeyVal;/*零个或多个keyvals*/
凯瓦尔:
键“=”VALUE“,”{g_hash_table_insert(table,$1,$3);printf(“%s:%s\n”,$1,$3);};
%%
int yyerror(字符*s){
printf(“YY错误:%s\n”,s);
}
内部主(空){
table=g_hash_table_new(g_str_hash,g_str_equal);
yyparse();
}

您确定不想对数据中的第一个项执行任何操作吗?您似乎没有将它们用于任何用途。

谢谢您的评论。我不知道如何更好地解释它。这是一个尝试。我的代码(野牛)的最新状态是:Hi@UncleO,谢谢你的回复。是的,我将以与第二学期相同的方式使用它们:
g_hash_table_insert(table,“TYPE”,$1)g_hash_table_insert(table,“ID”,$3)
让我看看我能做多少,我将在这个线程中返回。再次感谢。
g_hash_table_insert(table, keys[i],vals[i]);
g_hash_table_insert(table, <$1 from bison>,<$3 from bison>);
%{
#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]);
    }
  }
}
%{
#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();
}