解析 – 用flex bison解析bibtex:重新访问

在过去的几周里,我正在尝试使用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",}

当我试图解析它时,它给出了语法错误.使用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".
.....

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

解决方法

很多问题.首先,你的词法分析器很困惑,试图将引用的字符串和支撑的东西识别为单个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 ',' ;

这应该解析你给出的例子.

相关文章

一:display:flex布局display:flex是一种布局方式。它即可以...
1. flex设置元素垂直居中对齐在之前的一篇文章中记载过如何...
移动端开发知识点pc端软件和移动端apppc端软件是什么,有哪些...
最近挺忙的,准备考试,还有其他的事,没时间研究东西,快周...
display:flex;把容器设置为弹性盒模型(设置为弹性盒模型之后...
我在网页上运行了一个Flex应用程序,我想使用Command←组合键...