【问题标题】:parse bibtex with flex+bison: revisited使用 flex+bison 解析 bibtex:重新访问
【发布时间】:2013-03-09 00:43:32
【问题描述】:

最近几周,我正在尝试使用 flex 和 bison 为 bibtex (http://www.bibtex.org/Format/) 文件编写解析器。

$ 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();

}

%% 一个示例 bibtex 是:

@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,它显示它希望声明 KEY 中的字段(可能),

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".
.....

如果有人在这方面帮助我,我将不胜感激。

【问题讨论】:

    标签: parsing bison flex-lexer bibtex


    【解决方案1】:

    很多问题。首先,您的词法分析器很困惑,试图将带引号的字符串和大括号的东西识​​别为单个 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 ',' ;
    

    那应该解析你给出的例子。

    【讨论】:

    • 嗨,克里斯,感谢您的帮助。它的工作原理,我已经更新了它,即使是在很多一般情况下(虽然不认为它是完整的)。
    猜你喜欢
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多