Как мне разобрать сложный формат файла в Delphi? (Не CSV, XML и т. Д.) - PullRequest
5 голосов
/ 21 июля 2010

Прошло несколько лет с тех пор, как мне пришлось анализировать любые файлы, которые были сложнее, чем CSV или XML, поэтому я не практикуюсь. Мне было поручено проанализировать формат файла с именем NeXus в приложении Delphi.

Проблема в том, что я просто не знаю, с чего начать, использую ли я токенизатор, регулярные выражения и т. Д.? Может быть, даже учебник может быть то, что мне нужно на данный момент.

Ответы [ 4 ]

7 голосов
/ 21 июля 2010

Взгляните на GOLD Parser .Это система метапарсинга, которая позволяет вам определять формальную грамматику для языка / формата файла.Он создает файл правил синтаксического анализа, который вы передаете в токенизатор, вместе с вашим входным файлом, и создает в памяти синтаксическое дерево.

На веб-сайте имеется реализация токена для Delphi.Это значительно упрощает синтаксический анализ, поскольку о лексизировании и токенизации уже позаботились о вас, и все, о чем вам нужно беспокоиться, - это определить токены в формальной грамматике, а затем интерпретировать их после анализа.

3 голосов
/ 21 июля 2010

Проверьте это, это коммерческий, но выглядит как забавная игрушка:

http://dpg.zenithlab.com/

Но на самом деле: для нексуса вам не нужен сложный парсер.

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

Я бы проанализировал его, используя простой анализатор токенов за раз:

  1. загрузка файла в TStringList.
  2. для каждой строки, захватите один токен за раз, чтобы определить тип линии.
    иметь перечислимый тип для этого типа строки.
  3. первая действительная непустая строка должна быть определена как действительный тег #nexus.
  4. рядом с областью заголовка (пропущено в основном похоже)
  5. begin - это первое и ключевое слово в строке.
  6. следующие строки внутри блока begin выглядят почти как команда DOS и ее параметры командной строки, разделены пробелами и заканчиваются точкой с запятой. очень похоже на паскаль, но в скобках.

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

функция GetToken (var inputString: String; outputToken: String; Разделители const: TStrings; Ключевые слова: TStrings; ParenFlag: Boolean): Boolean;

GetToken вернет true, когда сможет найти и вернуть строку токена из inputString, пропустит любой начальный пробел и завершится, когда найдет разделитель. Разделителями являются такие элементы, как пробел или запятая.
ParenFlag: True будет означать, что следующим полученным токеном должен быть весь список элементов в скобках. Как только я получу весь список в скобках (((a, b), (c, d), (e, f))), я вызову другую функцию, которая распакует содержимое этого списка в некоторую структуру данных для списков / массивы.

Я не рекомендую большой движок парсера, и грамматика BNF поможет вам написать код, если вы сначала напишите грамматику BNF перед тем, как написать парсер. Но здесь нет ничего настолько грубого, что вы не сможете разобрать его.

От вас ожидают выполнения запросов / преобразований по этому вопросу? Как вы думаете, вам нужно преобразовать его в json или xml, чтобы работать с ним дальше?

2 голосов
/ 21 июля 2010

Не найден тестовый формат, но конечный автомат не будет анализироваться. Добавьте в рекурсию, чтобы запустить гнезда на деревьях. Это легко написанный сравнительно быстрый механизм синтаксического анализа, который может быть создан практически для любого текстового файла с шаблоном. Часто проще, чем использовать язык сценариев для загрузки. У меня есть собственные, написанные для HTML, XML, HL7 и различных медицинских форматов EDI.

2 голосов
/ 21 июля 2010

В дополнение к очень хорошему ответу Мейсона. В Delphi есть отличный маленький класс, который часто недооценивают, и тот, на котором вы можете изучить действительно хорошую технику, и это класс PageProducer.

Посмотрите, как он анализирует HTML и отображает события в таких вещах, как поиск тегов, атрибутов и т. Д. Я не говорю, что используйте PageProducer (потому что вы не сможете использовать Nexus), но это очень просто , элегантная и мощная техника.

...