Parsing 使用flex+解析bibtex;野牛:重游

Parsing 使用flex+解析bibtex;野牛:重游,parsing,bison,flex-lexer,bibtex,Parsing,Bison,Flex Lexer,Bibtex,在过去的几周里,我试图使用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

在过去的几周里,我试图使用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();
当我试图解析它时,它给出了语法错误。对于GDB,它显示它期望在键中声明字段(可能)


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

很多问题。首先,您的lexer很混乱,试图将带引号的字符串和大括号的内容识别为单个
,以及试图识别单个字符,如
{
。对于引号,让lexer识别整个字符串是有意义的,但是对于要解析的结构内容(如大括号列表),您需要返回单个标记,以便解析器进行解析。其次,在为字符串分配空间时,您没有为NUL terminiator分配空间。最后,您的语法看起来很奇怪,希望将
=VALUE=VALUE
之类的内容解析为KeyValue,这与bibtex文件中的任何内容都不对应

首先,对于lexer,您希望识别带引号的字符串和标识符,但其他内容应该是单个字符:

[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 ',' ;

这应该可以解析您给出的示例。

嗨,克里斯,谢谢您的帮助。它很有效,即使是在一般情况下,我也对它进行了更新(但不认为它是完整的)。
[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 ',' ;