Как написать собственный Configformat - PullRequest
1 голос
/ 10 июня 2009

Я разработал собственный формат файлов для файлов конфигурации (открытый текст и строка -> EOL = одна конфигурация) для приложения. В этом формате нет ничего особенного, и единственная причина, по которой я это делаю, - это чему-то научиться! Функции чтения и записи будут реализованы на C (с GLib, потому что это должен быть файл в кодировке UTF8).

Итак, теперь я думаю о том, как я реализую этот формат в C-коде. Какие шаги мне нужно сделать, чтобы получить как можно более качественные сообщения об ошибках. Я слышал кое-что о Лексере, Парсере, но никогда не зацикливался на этом. У меня есть только очень абстрактное представление о них. Итак, какие шаги мне нужно сделать, чтобы получить чистый читатель, написанный на C для этого формата, который также поддерживается для будущих изменений? Какие темы изучать / думать?

И да, я знаю: C - это боль, есть много разных "сексуальных" форматов для этого предложения и так далее. Я хочу чему-то научиться!

Cheers, Грегор


Дополнительная информация

  • Читатель / писатель / парсер (или как он там называется) должен как можно меньше зависеть от сторонних программ / компонентов. Приложение вокруг этой части конфигурации уже использует GLib, поэтому GLib также используется для UTF8

Ответы [ 3 ]

5 голосов
/ 10 июня 2009

Один классный способ создания формата конфигурации - это внедрение языка сценариев.

Это дает вам парсер бесплатно и дает возможность генерировать данные на лету или определять переменные, которые используются повторно:

Рассмотрим примеры xml против уродливого языка псевдо-сценариев:

<InputPoints>
  <Point>
    <x>1.0</x>
    <y>1.0</y>
  </Point>
  <Point>
    <x>1.0</x>
    <y>2.0</y>
  </Point>
  <Point>
    <x>1.0</x>
    <y>3.0</y>
  </Point>
  <Point>
    <x>1.0</x>
    <y>4.0</y>
  </Point>
<InputPoint>

против

for(i = 1; i <= 4; ++i) {
  InputPoint(1, i);
}

или, возможно,

<Username>allanballan</Username>
<Accountname>allanballan</Accountname>
<HomeDirectory>/home/allanballan</HomeDirectory>

против

user = "allanballan";
Username = user;
Accountname = user;
HomeDirectory = "/home/"+user;

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

Популярным языком для подобных ситуаций является Lua . Как сопоставить язык сценариев с конфигурацией, зависит от интегратора, но он действительно мощный и предоставляет бесплатный анализ и проверку типов.

1 голос
/ 10 июня 2009

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

Хорошо, что есть много инструментов, которые позволяют вам генерировать эти вещи из высокоуровневого описания вашего ввода и его структуры. Стандартными инструментами * nix для этого являются Lex и Yacc (или их потомки Flex и Bison), но я бы хотел указать вам на ANTLR (* 1004. *). Одна из приятных особенностей заключается в том, что он предоставляет бэкенды для много разных языков (C / C ++, а также Java, Python, Ruby, C #, ...), поэтому изучение работы с ним также поможет вам, если вы захотите переключить языки на более позднем этапе.

1 голос
/ 10 июня 2009

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

Хотя, если вы действительно хотите узнать о синтаксических анализаторах и лексерах, вероятно, было бы лучше реализовать простой компилятор. Есть курс MIT , на который вы могли бы пойти.

...