在一个能说会道的哈希容器柔性+野牛输出 [英] flex+bison output in a glib's hash container

查看:148
本文介绍了在一个能说会道的哈希容器柔性+野牛输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在解析文件围脖管理的长足进展,但下一步是了解我的present水平相当强悍。
我已经创建了野牛和柔性code,上面正确解析围脖文件:

 %{
#包括LT&;&stdio.h中GT;
%}//符号。
%联盟
{
    字符* SVAL;
};
%令牌LT; SVAL>值
%令牌LT; SVAL>键
%令牌OBRACE
%令牌EBRACE
%令牌报价
%令牌SEMICOLON%输入启动
%%
输入:
     / * *空/
     |输入项; / *输入是零个或多个entires * /
条目:
     '@'KEY'{'KEY','{printf的(=========== \\ n%S:%S \\ n,$ 2,$ 4); }
     KeyVals}
     ;
KeyVals:
       / * *空/
       | KeyVals KEYVAL; / *零个或多个keyvals * /
KEYVAL:
      KEY'='值','{printf的(%S:%S \\ n,$ 1,$ 3); };%%INT的yyerror(字符* S){
  的printf(的yyerror:%S \\ N,S);
}诠释主要(无效){
  yyparse();
}

 %{
#包括bib.tab.h
%}%%
[A-ZA-Z] [A-ZA-Z0-9] * {yylval.sval =的strdup(yytext中);返回键; }
\\([^ \\] | \\\\)* \\| \\ {([^ \\] | \\\\)。* \\} {yylval.sval =的strdup(yytext中);返回值; }
[\\ t \\ n]; / *忽略空格* /
[{} @ =,] {返回* yytext中; }
。 {fprintf中(标准错误,无法识别的字符%C,在输入\\ n,* yytext中); }
%%

我想在一个容器这些值。对于过去的几天里,我读了巧舌如簧的巨大文件和散列容器作为最适合我的情况就出来了。
下面是一个基本的哈希code,它有正确的哈希值,一旦值被放入数组键和丘壑。

 的#include< glib.h>
#定义SLEN 1024INT主(gint的argc,gchar **的argv)
{
  字符*键[] = {ID,类型,作者,年,NULL};
  字符*瓦尔斯[] = {一,尚书,RB,2013​​,NULL};
  gint我;
  GHashTable *表= g_hash_table_new(g_str_hash,g_str_equal);
  GHashTableIter ITER;
  g_hash_table_iter_init(安培; ITER,表);
  对于(i = 0; I< = 3;我++)
  {
    g_hash_table_insert(表,按键[I]中,瓦尔斯[I]);
    g_printf(%D =>%S:%S \\ n,我,钥匙[I],g_hash_table_lookup(表​​,钥匙由[i]));
  }
}

问题是,我该如何整合这两code,即:使用解析数据在C code。
任何一种帮助AP preciated。

编辑:作为解释@UncleO的回应:
@UncleO,

感谢您的评论。我不就没怎么解释好。这是一个尝试。
最近我的code(野牛)的现状是:

 %{
#包括LT&;&stdio.h中GT;
#包括LT&;&glib.h GT;
%}//符号。
%联盟
{
    字符* SVAL;
};
%令牌LT; SVAL>值
%令牌LT; SVAL>键
%令牌OBRACE
%令牌EBRACE
%令牌报价
%令牌SEMICOLON%输入启动
%%
输入:
     / * *空/
     |输入项; / *输入是零个或多个entires * /
条目:
     '@'KEY'{'KEY','{printf的(=========== \\ n%S:%S \\ n,$ 2,$ 4); }
     KeyVals}
     ;
KeyVals:
       / * *空/
       | KeyVals KEYVAL; / *零个或多个keyvals * /
KEYVAL:
      KEY'='值','{printf的(%S:%S \\ n,$ 1,$ 3); };%%INT的yyerror(字符* S){
  的printf(的yyerror:%S \\ N,S);
}诠释主要(无效){
 GHashTable *表= g_hash_table_new(g_str_hash,g_str_equal);
  字符*键[] = {ID,类型,作者,年,NULL};
  字符*瓦尔斯[] = {一,尚书,RB,2013​​,NULL};
  gint我;
  yyparse();
  GHashTableIter ITER;
  g_hash_table_iter_init(安培; ITER,表);
  对于(i = 0; I< = 3;我++)
  {
    g_hash_table_insert(表,按键[I]中,瓦尔斯[I]);
    g_printf(%D =>%S:%S \\ n,我,钥匙[I],g_hash_table_lookup(表​​,钥匙由[i]));
  }
}

与法文件不变。数组键和丘壑的元素是用于测试目的。
输入文件的一个例子是

  @Booklet {ab19,
    作者=楼陀罗班纳吉和A. Mookerjee
    编辑=SM1
    标题=SM2
    出版商=SM3
    体积=SM4
    发行=SM5
    页=SM6
    月=SM8
    注=SM9
    重点=SM10
    一年=1980年,
    添加=OSM1
    版=osm2
}

因此​​,在解析时,code正确分析的价值。我想用这些值从解析输入在哈希表中要插入,这将是为每个输入不同。
所以,我的最终目标是消除从code数组键和丘壑;而行

  g_hash_table_insert(表,钥匙[I],丘壑[I]);

应该是这样来代替:

  g_hash_table_insert(表< $ 1从野牛>,< $ 3从野牛>);

这是否有道理?

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

@ Uncle0:这里是更新code;可能是我的意图是这一个清楚的。我想了很多解决这一问题,但同时从野牛行式打印是打印的东西如预期,其并非如此,而从哈希表打印(在code的最后一行)

 %{
#包括LT&;&stdio.h中GT;
#包括LT&;&glib.h GT;
#定义SLEN 1024
GHashTable *表;
%}//符号。
%联盟
{
    字符* SVAL;
};
%令牌LT; SVAL>值
%令牌LT; SVAL>键
%令牌OBRACE
%令牌EBRACE
%令牌报价
%令牌SEMICOLON%输入启动
%%
输入:
     / * *空/
     |输入项; / *输入是零个或多个entires * /
条目:
     @KEY{KEY,{g_hash_table_insert(表中,类型,$ 2);
                  g_hash_table_insert(表中,ID,$ 4);
              g_printf(%S:%S \\ n,$ 2,$ 4);
              }
     KeyVals}
     ;
KeyVals:
       / * *空/
       | KeyVals KEYVAL; / *零个或多个keyvals * /
KEYVAL:
      KEY'='值','{g_hash_table_insert(表,$ 30,$ 90);
                          g_printf(%S:%S \\ n,$ 1,$ 3); };%%INT的yyerror(字符* S){
  的printf(的yyerror:%S \\ N,S);
}诠释主要(无效){
  表= g_hash_table_new(g_str_hash,g_str_equal);
gint我;
做{
   g_hash_table_remove_all(表);
   yyparse();
   parse_entry(表);
// g_printf(%S:%S \\ n,作者=>中,g_hash_table_lookup(表​​中,作者));
// g_printf(%S:%S \\ n,KEY =>中,g_hash_table_lookup(表​​中,KEY));
  }
  而(EOF!);
}
无效parse_entry(GHashTable *表)
{
  GHashTableIter ITER;
  gchar *键,* VAL;
  字符*键[] = {ID,类型,作者,年,称号,发行人,编辑,
    卷,号码,网页,月,注意,地址,编辑,日记,
    系列,书,章,组织,NULL};
  字符*瓦尔斯[] = {NULL,NULL,NULL,NULL,NULL,
    NULL,NULL,NULL,NULL,NULL,
    NULL,NULL,NULL,NULL,NULL,
    NULL,NULL,NULL,NULL,NULL};  gchar ** kiter;
  gint我;
  g_hash_table_iter_init(安培; ITER,表);
  而(g_hash_table_iter_next(安培;国际热核实验堆(无效**)及键,(无效**)放大器; VAL))
  {
    对于(kiter =键,I = 0; * kiter; kiter ++,我++)
    {
      如果(!g_ascii_strcasecmp(* kiter,键))
      {
    瓦尔斯[I] = g_strndup(VAL,SLEN);
    打破;
      }
    g_printf(%D =>%S:%S \\ n,我,钥匙[I],丘壑[I]);
    }
  }
}


解决方案

您还没有你想要的输入做什么明​​确的,但这里是一个解释,让你开始。

柔性是要采取常规的前pressions的文件并生成一个函数调用函数yylex()。

野牛是要带你的语法文件并生成一个函数调用yyparse()使用该函数yylex()函数的反复来标记字符串。在main()函数将只调用yyparse()一次,并且每个yyparse()函数的语法与规则相匹配时,将执行您指定的code片段。现在,你仅仅是打印值,但你可以做其他事情一样插入到任何你想要的哈希表或

该grammar.y文件具有yyparse的定义之前自带自带之后,code()和code部分。如果你想这是好把main()函数在这个文件的末尾,但只有更好把它在另一个文件中的两个环节。通常情况下,在main()函数做的事情就像打开输入阅读等,然后调用yyparse()来执行大部分工作。 yyparse()返回后,主要可以清理。

编辑:你好楼陀罗,

我看你想保留的main()的语法文件。这没关系。

所有你现在需要做的是改变在片段中的printf语句插入到表中,变量将不得不宣布的main()之外yyparse()来看看吧。

 %{
#包括LT&;&stdio.h中GT;
#包括LT&;&glib.h GT;GHashTable *表;%}//符号。
%联盟
{
    字符* SVAL;
};
%令牌LT; SVAL>值
%令牌LT; SVAL>键
%令牌OBRACE
%令牌EBRACE
%令牌报价
%令牌SEMICOLON%输入启动
%%
输入:
     / * *空/
     |输入项; / *输入是零个或多个entires * /
条目:
     '@'KEY'{'KEY','{printf的(=========== \\ n%S:%S \\ n,$ 2,$ 4); }
     KeyVals}
     ;
KeyVals:
       / * *空/
       | KeyVals KEYVAL; / *零个或多个keyvals * /
KEYVAL:
      KEY'='值','{g_hash_table_insert(表,$ 30,$ 90);的printf(%S:%S \\ n,$ 1,$ 3); };%%INT的yyerror(字符* S){
  的printf(的yyerror:%S \\ N,S);
}诠释主要(无效){
  表= g_hash_table_new(g_str_hash,g_str_equal);  yyparse();
}

你确定你不想做与数据的第一项什么?看来你不使用他们的任何东西等。

I have managed considerable progress in parsing the bib file, but the next step is quite tough for my present level of understanding. I have created bison and flex code, that parses the bib file above correctly:

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

and

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

I want to have those values in a container. For last few days, I read the vast documentation of glib and came out with hash container as most suitable for my case. Below is a basic hash code, where it have the hashes correctly, once the values are put in the array keys and vals.

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

The problem is, how I integrate this two code, i.e., use the parsed data in the C code. Any kind help is appreciated.

Edit: as to explain @UncleO 's response: @UncleO,

Thanks for your comment. I don't no how to explain it better. Here is a try. The recent status of my code(bison) is:

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

with the lex file unchanged. The elements of array keys and vals are for testing purpose. A example of input file is

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

So, while parsing, the code parses the value correctly. I want to use those values from the parsed input to be inserted in the hash table, which will be different for each input. So, my final goal is to remove the arrays keys and vals from the code; and the line

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

should be replaced by something like:

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

Does this makes sense?

Edit:=====================================

@Uncle0: Here is the updated code; probably my intention is clear with this one. I am trying a lot to fix this up, but while print from bison line is printing things as expected, its not the case while printing from the hash table (last line of the code)

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

解决方案

You haven't been clear on what you want to do with the input, but here is an explanation to get you started.

flex is going to take your file of regular expressions and produce a function called yylex().

bison is going to take your grammar file and produce a function called yyparse() that uses the yylex() function repeatedly to tokenize strings. The main() function will only call yyparse() once, and each time the yyparse() function matches a rule in the grammar, it will execute the code fragments you have specified. Right now, you are merely printing the values, but you can do other things like insert into the hash table or whatever you want.

The grammar.y file has sections for code that comes before the definition of yyparse() and code that comes after. It is okay to put the main() function at the end of this file if you want to, but it is only better to put it in another file an link the two. Usually, the main() function does things like open the input for reading, etc., then calls yyparse() to perform the bulk of the work. After yyparse() returns, main can clean up.

EDIT: Hi Rudra,

I see you want to keep main() in the grammar file. That's okay.

All you need to do now is change the printf statements in the snippets to insert into the table, The table variable will have to be declared outside of main() for yyparse() to see it.

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

Are you sure you don't want to do anything with the first terms in the data? It seems like you are not using them for anything.

这篇关于在一个能说会道的哈希容器柔性+野牛输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆