1

次のようなファイルを解析しようとしています: (実際の目的には単純すぎますが、最初はこれで問題ありません)

@Book{key2,
 Author="Some2VALUE" ,
 Title="VALUE2" 
}

レクサーは次のとおりです。

[A-Za-z"][^\\\"  \n\(\),=\{\}#~_]*      { yylval.sval = strdup(yytext); return KEY; }
@[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); }

そして、これを次のように解析します。

%union
{
    char    *sval;
};

%token <sval> ENTRYTYPE
%type <sval> VALUE
%token <sval> KEY

%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 */ 
      | KeyVals KeyVal ; /* zero or more keyvals */

VALUE:
      /*empty*/
      | KEY 
      | VALUE KEY 
      ;
KeyVal: 
      /*empty*/
      KEY '=' VALUE ',' { g_hash_table_replace(b_entry.table, $1, $3); }
      | KEY '=' VALUE  { g_hash_table_replace(b_entry.table, $1, $3); }
      | error '\n' {yyerrok;}
      ;

問題はほとんどないので、レクサーとパーサーの両方を一般化する必要があります: 1) 文を読むことができません。 2) RHS を "" ではなく {} で囲むと、構文エラーが発生します。この 2 状況のヘルプを探しています。

4

1 に答える 1

1

主な問題は、トークンが適切でないことです。次のように、例のトークンを認識してみてください。

@Book        ENTRYTYPE
{            '{'
key2         KEY
,            ','
Author       KEY
=            '='
"Some2VALUE" VALUE
,            ','
Title        KEY
=            '='
"VALUE2"     VALUE
}            '}'

VALUE トークンは、たとえば次のように定義できます。

%x value
%%
"\""           {BEGIN(value);}
<value>"\""    {BEGIN{INITIAL); return VALUE;}
<value>"\\\""  { /* escaped " */ }
<value>[^"]    { /* Non-escaped char */ }

または単一の式で

"\""([^"]|("\\\""))*"\""

"これは、 でエスケープするだけでよいことを前提としてい\ます。"可能であれば、BibTeX が a をエスケープする方法をどのように定義しているかはわかりません。

于 2013-05-03T06:58:36.237 に答える