Разбор: библиотечные функции, FSM, explode () или lex / yacc? - PullRequest
6 голосов
/ 18 апреля 2011

Когда мне нужно разобрать текст (например, файлы конфигурации или другие довольно простые / описательные языки), у меня возникает несколько решений:

  • с использованием библиотечных функций, например strtok(), sscanf()
  • конечный автомат, который обрабатывает один символ за раз, разбивает на токены и разбирает
  • с использованием функции explode(), которую я однажды написал из чистой скуки
  • с использованием lex / yacc (читай: flex / bison) для генерации подходящего синтаксического анализатора

Мне не нравится подход "библиотечные функции". Это кажется неуклюжим и неловким. explode(), хотя он не требует большого количества нового кода, чувствует себя еще более взорванным. И flex / bison часто кажется просто излишним.

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

Отсюда и мой вопрос:

Как лучше всего анализировать относительно простые текстовые файлы?
Это имеет значение вообще?
Есть ли общепринятый подход?

Ответы [ 3 ]

6 голосов
/ 25 мая 2011

Я собираюсь немного нарушить правила и ответить на ваши вопросы не по порядку.

  • Есть ли общепринятый подход?

Абсолютно нет,ИМХО, решение, которое вы выбираете, должно зависеть (если назвать несколько) от вашего текста, ваших временных рамок, вашего опыта, даже вашей личности.Если текст достаточно прост, чтобы сделать flex и bison избыточным, возможно, C сам по себе является избыточным.Важно ли быть быстрым или надежным?Нужно ли его поддерживать или он может начать быстро и грязно?Вы страстный пользователь C, или вас могут заманить правильные языковые функции?& c., & c.

  • Имеет ли это значение вообще?

Опять же, это то, на что только вы можете ответить.Если вы работаете в тесном контакте с командой людей, обладающих особыми навыками и способностями, и анализатор важен и нуждается в поддержке, это, безусловно, имеет значение!Если вы пишете что-то «из чистой скуки», я бы сказал, что это вообще не имеет значения, нет.: -)

  • Как лучше всего анализировать относительно простые текстовые файлы?

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

Нет, действительно, продолжайте.Я подожду.

Ах, ты вернулся и расслабился.Давайте разберёмся с вещами, не так ли?

Никогда не пишите это в 'C', если вы можете сделать это в 'awk';
Никогда не делайте это в 'awk', если 'sed' может обработатьit;
Никогда не используйте «sed», когда «tr» может выполнить работу;
Никогда не вызывайте «tr», когда «cat» достаточно;
Избегайте использования «cat», когда это возможно.
-Законы программирования Тейлора

Если вы пишете это на C, но C чувствует себя как неправильный инструмент ... это действительно может быть неправильный инструмент.awk или perl, скорее всего, сделают то, что вы пытаетесь сделать, без всякого обострения.Вы можете даже сделать это с помощью cut или чего-то подобного.

С другой стороны, если вы пишете это на C, у вас, вероятно, есть веская причина написать это на C.Парсер - это крошечная часть гораздо большей системы, которая, ради аргумента, встроена в холодильник на Луну.Или, может быть, вы любите C. Вы можете даже ненавидеть awk и perl, Небесный защитник.

Если вы не ненавидите awk и perl, возможно, вы захотите вставить их в свой Cпрограмма.В принципе это выполнимо - я никогда не делал это сам.Для awk попробуйте libmawk.Для perl, вероятно, есть несколько способов (TMTOWTDI).Вы можете запустить perl отдельно, используя popen, чтобы запустить его, или вы можете встроить интерпретатор Perl в вашу программу на C - см. man perlembed.

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

Я собираюсь предположить, что в ваших решениях только для C (библиотечные функции и FSM (учитывая, что ваш explode по сути является библиотечной функцией)), вы ужепостарались изолировать соответствующий код, хорошо спроектировать код и файлы и т. д.

Несмотря на это, я рекомендую lex и yacc.

Библиотекафункции кажутся «неуклюжими и неловкими».Конечный автомат кажется неуправляемым.Но вы говорите, что lex и yacc кажутся излишними.

Я думаю, что вы должны подходить к своим жалобам по-другому.Что вы на самом деле делаете, так это указываете на FSM.Тем не менее, вы также нанимаете кого-то, чтобы написать и поддерживать его для вас, тем самым решая большую часть проблемы с ремонтопригодностью.Overkill?Я упоминал, что они будут работать бесплатно?

Я подозреваю, но не знаю, что причина, по которой lex и yacc изначально казались излишними, заключалась в том, что ваши файлы конфигурации / простые файлы казались слишком простыми. Если я прав (большое если), вы можете выполнять большую часть своей работы в лексере. (Даже возможно, что вы можете выполнять всю свою работу в лексере, но я ничего не знаю о вашем вводе.) Если ваш ввод не только прост, но и широко распространен, вы можете найти комбинацию лексер / парсер, свободно доступную для чего-либо. тебе нужно.

Короче говоря: если вы можете сделать это не в C, попробуйте что-нибудь еще. Если вы хотите C, используйте lex и yacc - у них немного накладных расходов, но это очень хорошее решение.

0 голосов
/ 27 мая 2011

Мой краткий ответ - использовать право тоже для решения проблемы.Если у вас есть файлы конфигурации, используйте существующие стандарты и форматы, например, ini Files, и анализируйте их, используя Boost program_options .

Если вы входите в мир «своих» языков, используйте lex/yacc, поскольку они предоставляюту вас есть необходимые функции, но вы должны учитывать стоимость поддержки грамматики и языковой реализации.

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

0 голосов
/ 18 апреля 2011

Если вы можете заставить его работать, я бы пошел с FSM, но с огромной помощью из Perl-совместимых регулярных выражений . Эта библиотека проста для понимания, и вы должны быть в состоянии урезать достаточно посторонних спагетти, чтобы придать вашему монстру тот аэродинамический талант, к которому стремятся все летающие монстры. Это и множество комментариев в хорошо структурированных спагетти должны сделать ваш преемник, поддерживающий код, удобным. (И, как я уверен, вы знаете, этот преемник, поддерживающий код, - вы через шесть месяцев, когда вы перешли к чему-то другому, и подробности этого кода ускользнули от вас.)

...