2013-03-09 32 views
1

最近幾周,我試圖用flex和bison爲bibtex(http://www.bibtex.org/Format/)文件編寫解析器。用flex + bison解析bibtex:重溫

$ cat raw.l 
%{ 
#include "raw.tab.h" 
%} 
value [\"\{][a-zA-Z0-9 .\t\{\} \"\\]*[\"\}] 
%% 
[a-zA-Z]*    return(KEY); 
\"       return(QUOTE); 
\{       return(OBRACE); 
\}       return(EBRACE); 
;       return(SEMICOLON); 
[ \t]+     /* ignore whitespace */; 
{value}  { 
    yylval.sval = malloc(strlen(yytext)); 
    strncpy(yylval.sval, yytext, strlen(yytext)); 
    return(VALUE); 
} 

$ cat raw.y 
%{ 
#include <stdio.h> 
%} 

//Symbols. 
%union 
{ 
char *sval; 
}; 
%token <sval> VALUE 
%token KEY 
%token OBRACE 
%token EBRACE 
%token QUOTE 
%token SEMICOLON 

%start Entry 
%% 

Entry: 
    '@'KEY OBRACE VALUE ',' 
    KeyVal 
    EBRACE 
    ; 

KeyVal: 
     /* empty */ 
     | KeyVal '=' VALUE ',' 
     | KeyVal '=' VALUE 
     ; 
%% 

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

int main(void) { 
    yyparse(); 

}

%% 樣本中文提供是:

@Book{a1, 
    author = "a {\"m}ook, Rudra Banerjee", 
    Title="ASR", 
    Publisher="oxf", 
    Year="2010", 
    Add="UK", 
    Edition="1", 
} 
@Article{a2, 
    Author="Rudra Banerjee", 
    Title="Fe{\"Ni}Mo", 
    Publisher={P{\"R}B}, 
    Issue="12", 
    Page="36690", 
    Year="2011", 
    Add="UK", 
    Edition="1", 
} 

當我試圖解析它,它給語法錯誤。與GDB,它表明它希望在重點領域中聲明(可能),

Reading symbols from /home/rudra/Programs/lex/Parsing/a.out...done. 
(gdb) Undefined command: "". Try "help". 
(gdb) Undefined command: "Author". Try "help". 
(gdb) Undefined command: "Editor". Try "help". 
(gdb) Undefined command: "Title". Try "help". 
..... 

我會很感激,如果有人好心幫我在這。

回答

2

很多問題。首先,您的詞法分析器感到困惑,試圖識別引用的字符串並將其作爲一個單獨的VALUE,並試圖識別單個字符,如"{。對於引號,讓詞法分析器識別整個字符串是有意義的,但對於要解析的結構化事物(如支撐列表),您需要返回單個令牌以供解析器解析。其次,爲字符串分配空間時,不會爲NUL-終結符分配空間。最後,你的語法看起來很奇怪,想要將諸如= VALUE = VALUE這樣的東西解析爲KeyValue,它不對應於bibtex文件中的任何東西。

首先,對於詞法分析器。你要承認引用的字符串和標識符,但其他的事情應該是單個字符:

[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); } 

現在,您需要針對這些項目的分析器:

Input: /* empty */ | Input Entry ; /* input is zero or more entires */ 
Entry: '@' KEY '{' KEY ',' KeyVals '}' ; 
KeyVals: /* empty */ | KeyVals KeyVal ; /* zero or more keyvals */ 
KeyVal: KEY '=' VALUE ',' ; 

這應該分析你給的例子。

+0

嗨克里斯, 感謝您的幫助。它的工作,我已經更新了它,即使是一般情況下(儘管如此,不要認爲它是完整的)。 – BaRud 2013-03-10 11:27:26