Регулярное выражение для строк в Bibtex

Я пытаюсь разобрать файлы Bibtex, используя lex/yacc. Строки в базе данных bibtex могут быть заключены в кавычки "..." или фигурные скобки - {...}

Но каждая запись также заключена в фигурные скобки. Как отличить запись от строки, заключенной в фигурные скобки?

@Book{sweig42,
  Author =   { Stefan Sweig },
  title =    { The impossible book },
  publisher =    { Dead Poet Society},
  year =     1942,
  month =        mar
}

person Utkarsh Sinha    schedule 16.04.2011    source источник
comment
Не думайте так. Но это нельзя использовать, чтобы отличить внешний {} от строкового {}. В определении @book может не быть разрывов строк.   -  person Utkarsh Sinha    schedule 17.04.2011
comment
Привет, Поскольку вы все равно используете yacc, вы можете отложить устранение неоднозначности до этапа синтаксического анализа. В этом случае вы не ограничены регулярным выражением. Есть ли особые требования для выполнения работы лексером? С уважением Карстен Полезно Бесполезно   -  person collapsar    schedule 01.06.2011


Ответы (1)


у вас есть различные варианты:

  • условия запуска lexer (из учебника по Lex)

    основываясь на идеях greg ward, улучшите свои правила lex с начальными условиями («режимы», как они называются в указанном источнике).

в частности, у вас будут начальные условия BASIC ENTRY STRING и следующие правила (пример взят и немного улучшен из здесь):

%START BASIC ENTRY STRING
%%

/* Lexical grammar, mode 1: top-level */
<BASIC>AT           @ { BEGIN ENTRY; }
<BASIC>NEWLINE      \n
<BASIC>COMMENT      \%[^\n]*\n
<BASIC>WHITESPACE.  [\ \r\t]+
<BASIC>JUNK         [^@\n\ \r\t]+

/* Lexical grammar, mode 2: in-entry */
<ENTRY>NEWLINE      \n
<ENTRY>COMMENT      \%[^\n]*\n
<ENTRY>WHITESPACE   [\ \r\t]+
<ENTRY>NUMBER       [0-9]+
<ENTRY>NAME         [a-z0-9\!\$\&\*\+\-\.\/\:\;\<\>\?\[\]\^\_\`\|]+ { if (stricmp(yytext, "comment")==0) { BEGIN STRING; } }
<ENTRY>LBRACE       \{ { if (delim == '\0') { delim='}'; } else { blevel=1; BEGIN STRING; } }
<ENTRY>RBRACE       \} { BEGIN BASIC; }
<ENTRY>LPAREN       \( { BEGIN STRING; delim=')'; plevel=1; }
<ENTRY>RPAREN       \)
<ENTRY>EQUALS       =
<ENTRY>HASH         \#
<ENTRY>COMMA        ,
<ENTRY>QUOTE        \" { BEGIN STRING; bleveL=0; plevel=0; }

/* Lexical grammar, mode 3: strings */
<STRING>LBRACE       \{ { if (blevel>0) {blevel++;} }
<STRING>RBRACE       \} { if (blevel>0) { blevel--; if (blevel == 0) { BEGIN ENTRY; } } }
<STRING>LPAREN       \( { if (plevel>0) { plevel++;} }
<STRING>RPAREN       \} { if (plevel>0) { plevel--; if (plevel == 0) { BEGIN ENTRY; } } }
<STRING>QUOTE        \" { BEGIN ENTRY; }

обратите внимание, что набор правил ни в коем случае не является полным, но должен помочь вам начать работу. более подробную информацию можно найти здесь.

  • btparse

    Эти документы достаточно подробно объясняют тонкости разбора bibtex и поставляется с парсером python.

  • библикс

    вас также может заинтересовать использование цепочки инструментов unix из biblex и bibparse. эти инструменты генерируют и анализируют поток токенов bibtex соответственно.

    дополнительную информацию можно найти здесь.

С уважением, Карстен

person collapsar    schedule 01.06.2011
comment
Большой! Но задание нужно было сдать месяц назад, так что я разобрался с вашим кодом. Множественные состояния и отслеживание скобок/круглых скобок. - person Utkarsh Sinha; 01.06.2011