Подтвердить что ты не робот

Есть ли лучший (более современный) инструмент, чем lex/flex для создания токенизатора для С++?

Недавно я добавил синтаксический анализ исходного файла к существующему инструменту, который генерировал выходные файлы из сложных аргументов командной строки.

Аргументы командной строки оказались настолько сложными, что мы начали предоставлять их в качестве файла, который был проанализирован, как если бы он был очень большой командной строкой, но синтаксис все еще был неудобным. Поэтому я добавил возможность анализировать исходный файл с использованием более разумного синтаксиса.

Я использовал flex 2.5.4 для Windows, чтобы генерировать токенизатор для этого формата пользовательского исходного файла, и он сработал. Но я ненавидел код. глобальные переменные, wierd соглашение о присвоении имен и код С++, который он сгенерировал, были ужасными. Существующий код генерации кода был приклеен к выходу flex - я не использую yacc или bison.

Я собираюсь вернуться в этот код, и я бы хотел использовать лучший/более современный инструмент. Кто-нибудь знает что-то, что.

  • Запускается в командной строке Windows (интеграция с Visual Studio в порядке, но я использую make файлы для сборки)
  • Создает правильный инкапсулированный С++-токенизатор. (Нет глобальных переменных)
  • Использует регулярные выражения для описания правил токенизации (совместимых с синтаксисом lex a плюс)
  • Не заставляет меня использовать c-runtime (или подделку) для чтения файла. (проанализировать из памяти)
  • Предупреждает меня, когда мои правила вынуждают токенизатор возвращаться (или исправляет его автоматически)
  • Дает мне полный контроль над именами переменных и методов (поэтому я могу соответствовать существующему соглашению об именах)
  • Позволяет мне связать несколько парсеров с одним .exe без коллизий имен.
  • Может генерировать парсер UNICODE (16 бит UCS-2), если я хочу, чтобы он
  • НЕ является интегрированным токенизатором + парсером-генератором (я хочу заменить lex, а не замену lex + yacc)

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

4b9b3361

Ответ 1

Ragel: http://www.complang.org/ragel/ Он соответствует большинству ваших требований.

  • Он работает в Windows
  • Он не объявляет переменные, поэтому вы можете поместить их внутри класса или внутри функции по своему усмотрению.
  • У этого есть хорошие инструменты для анализа регулярных выражений, чтобы видеть, когда они возвратятся. (Я не знаю об этом очень сильно, так как я никогда не использую синтаксис в Ragel, который создавал бы анализатор обратного отслеживания.)
  • Измененные имена не могут быть изменены.
  • Названия таблиц имеют префикс имени машины, и они объявляются "const static", поэтому вы можете поместить более одного в один и тот же файл и иметь более одного с тем же именем в одной программе (до тех пор, пока они находятся в разных файлах).
  • Вы можете объявить переменные как любой целочисленный тип, включая UChar (или любой другой тип UTF-16, который вы предпочитаете). Однако он автоматически не обрабатывает суррогатные пары. У него нет специальных классов символов для Юникода (я думаю).
  • Только регулярные выражения... не имеют функций bison/yacc.

Созданный код очень мало мешает программе. Код также невероятно быстрый, а синтаксис Ragel более гибкий и читабельный, чем все, что я когда-либо видел. Это скалистая часть программного обеспечения. Он может генерировать синтаксический анализатор, управляемый таблицей, или парсинг, управляемый goto.

Ответ 2

Boost.Spirit.Qi(парсер-токенизатор) или Boost.Spirit.Lex(только токенизатор). Я абсолютно люблю Ци, и Лекс тоже неплохой, но я просто склоняюсь к Qi для моих потребностей синтаксического анализа...

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

http://www.boost.org/doc/libs/1_41_0/libs/spirit/doc/html/index.html

Ответ 3

Есть два инструмента, которые приходят на ум, хотя вам нужно будет найти для себя, что было бы подходящим, Antlr и GoldParser. Существуют языковые привязки, доступные в обоих инструментах, в которых он может быть подключен к среде выполнения С++.

Ответ 4

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

Просто добавьте следующее в голову файла lex:

%option C++
%option yyclass="Lexer"

Тогда в вашем источнике это:

std::fstream  file("config");
Lexer         lexer(&file)
while(int token = lexer.yylex())
{
}

Ответ 5

boost.spirit и Парсер партитуры на мой взгляд. Обратите внимание, что подход с использованием генераторов lexer несколько заменяется внутренним DSL С++ (доменным языком) для указания токенов. Просто потому, что это часть вашего кода без использования внешней утилиты, просто следуя ряду правил, чтобы указать вашу грамматику.