RudraB |
05-23-2013 08:53 AM |
Hi Ntubski and all,
sorry to open an solved thread once again, but its probably best thing for sake of completeness.
I have adopted the code as Ntubski provided, just put it in a gtk treeview and hashtable.
now it looks like:
the lexer:
Code:
%{
#include "bib.h"
int line;
%}
%option noyywrap
%x braceV
%%
<braceV>[^{}]* { yylval.sval = strdup(yytext); return VALUE; }
<braceV>[{}] { return *yytext; }
[A-Za-z][A-Za-z0-9_":]* { yylval.sval = strdup(yytext); return KEY; }
\".*\" { yylval.sval = strndup(yytext+1, yyleng-2); return VALUE; }
[0-9]+ { yylval.sval = strdup(yytext); return VALUE; }
@[A-Za-z][A-Za-z]+ { yylval.sval = strdup(yytext+1); return ENTRYTYPE; }
[ \t\n] ; /* ignore whitespace */
[{}=,] { return *yytext; }
. { fprintf(stderr, "Unrecognized character %c in input\n", *yytext); }
\n {line++;printf("%d",line);}
%%
void lex_brace() {
BEGIN(braceV);
}
void lex_normal() {
BEGIN(0);
}
The parser
Code:
%{
#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} ;
char* concat(char* str1, char* str2);
void lex_brace();
void lex_normal();
#define slen 1064
int yylex(void);
/*enum
{
COL_BIB_KEY=0,
COL_BIB_TYPE, COL_BIB_AUTHOR, COL_BIB_YEAR,
NUM_COLS} ;
*/
typedef struct {
char *type;
char *id;
GHashTable *table;
} BibEntry;
BibEntry b_entry;
GtkTreeIter siter;
GtkListStore *store;
void yyerror(char *s)
{
printf("YYERROR : %s\n", s);
}
void parse_entry(BibEntry *bib_entry);
%}
// Symbols.
%union
{
char *sval;
};
%token <sval> ENTRYTYPE
%token <sval> VALUE
%token <sval> KEY
%token OBRACE
%token EBRACE
%token QUOTE
%token SEMICOLON
%type <sval> Value
%type <sval> BraceV
%type <sval> BraceVs
%start Input
%%
Input: Entry
| Input Entry ; /* input is zero or more entires */
Entry:
ENTRYTYPE '{' KEY ','{
b_entry.type = $1;
b_entry.id = $3;
b_entry.table = g_hash_table_new_full(g_str_hash, g_str_equal, free, free);}
KeyVals '}' {
parse_entry(&b_entry);
g_hash_table_destroy(b_entry.table);
free(b_entry.type); free(b_entry.id);
b_entry.table = NULL;
b_entry.type = b_entry.id = NULL;}
;
KeyVals : /* empty */
| KeyVal
| KeyVal ',' KeyVals
;
KeyVal : KEY '=' Value { g_hash_table_replace(b_entry.table, $1, $3);
printf("%s\n",$3);
}
;
Value : '{' { lex_brace(); } BraceVs { lex_normal(); } '}' { $$ = $3; }
| VALUE
;
BraceVs : /* empty */ { $$ = ""; }
| BraceV BraceVs { $$ = concat($1, $2); }
;
BraceV : VALUE
| '{' BraceVs '}' { $$ = concat(concat("{", $2), "}"); }
;
%%
void parse_entry(BibEntry *bib_entry)
{
char *author = "", *year = "";
GHashTableIter iter;
gpointer key, val;
char **kiter;
int i;
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};
g_hash_table_iter_init(&iter, bib_entry->table);
while (g_hash_table_iter_next(&iter, &key, &val)) {
for (kiter = keys, i = 0; *kiter; kiter++, i++)
{
if (!g_ascii_strcasecmp(*kiter, key)) {
vals[i] = g_strndup(val,slen);
break;
}
}
}
gtk_list_store_append (store, &siter);
gtk_list_store_set (store, &siter,
COL_BIB_AUTHOR, vals[COL_BIB_AUTHOR],
COL_BIB_TYPE, bib_entry->type,
COL_BIB_KEY, bib_entry->id,
COL_BIB_YEAR, vals[COL_BIB_YEAR],
-1);
}
void setup_tree(GtkWidget *tree)
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
renderer = gtk_cell_renderer_text_new ();
/********************************************/
g_object_set(G_OBJECT(renderer), "wrap-mode", PANGO_WRAP_WORD,
"wrap-width",300, NULL);
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);
/********************************************/
column = gtk_tree_view_column_new_with_attributes
("KEY", renderer, "text",COL_BIB_KEY, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
/********************************************/
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);
/********************************************/
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);
}
char* concat(char* str1, char* str2) {
char* ret = malloc(strlen(str1) + strlen(str2) + 1);
strcat(ret, str1);
strcat(ret, str2);
return ret;
}
and the C routine:
Code:
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gstdio.h>
#include <fcntl.h>
char* buffer;
gsize length;
GError* error=NULL;
enum
{
COL_BIB_KEY=0,
COL_BIB_TYPE, COL_BIB_AUTHOR, COL_BIB_YEAR,
NUM_COLS} ;
#define slen 102
GtkTreeIter siter;
GtkListStore *store;
typedef struct {
char *type;
char *id;
GHashTable *table;
} BibEntry;
BibEntry b_entry;
void parse_entry (BibEntry *bib_entry);
void setup_tree(GtkWidget *tree);
int main(int argc, char** argv)
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
GtkWidget *tree = gtk_tree_view_new();
GtkWidget *scrolledw = gtk_scrolled_window_new(NULL, NULL);
extern FILE *yyin;
extern int yyparse (void);
extern yy_create_buffer;
setup_tree(tree);
gtk_container_add(GTK_CONTAINER(window), scrolledw);
gtk_container_add(GTK_CONTAINER(scrolledw), tree);
store = gtk_list_store_new(NUM_COLS,
G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
//FILE *fin=fopen("u2.bib","r");
//yyin=fin;
g_file_get_contents("/home/rudra/Desktop/u2.bib", &buffer, &length , &error);
yyin=fmemopen(buffer,strlen(buffer),"r");
yyparse();
g_file_get_contents("/home/rudra/Desktop/u2.bib", &buffer, &length , &error);
yyin=fmemopen(buffer,strlen(buffer),"r");
yyparse();
gtk_tree_view_set_model (GTK_TREE_VIEW (tree), GTK_TREE_MODEL (store));
g_object_unref (store);
gtk_widget_show_all (window);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
This is an minimal example
The problem is, even when we ignore any gtk things, just the printf statement (line #86 of parser) prints garbage value for Key={Value}; neither for Key="Value" nor Key="{Value}".
Also, the garbage comes only when I read the file 2nd time, not for the first.(This resembles the case when I open the file using a gtkwidget, thats why I have added the 2nd yyparse).
The output of printf looks like:
��b<Rudra } when the actual thing is {Rudra}
and emits warning:
Quote:
Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text()
|
Please help.
|