Падение, перенос парсинга

Я вижу множество сообщений в день о том, как "делать X с регулярным выражением". И лучший ответ большинству из них кажется, что это было бы честно: "Почему вы пытаетесь водить винт молотком?" Но regexen повсюду, и синтаксис в основном переносимый, особенно если вы держитесь подальше от причудливых бит.

Есть ли что-то эквивалентное регулярному выражению, но на следующем уровне мощности и конфигурации? "Вы можете использовать его в любом месте", анализируя библиотеку некоторого разнообразия, желательно с великолепно сжатым DSL в качестве интерфейса?

Я использовал Ragel несколько, но из-за шага предварительной обработки я смутился, чтобы рекомендовать его кому-то, "использовать это вместо некоторого волосатого регулярного выражения". Это неудобно использовать из Obj-C, и я ожидаю, что это будет ужасно неудобно с языка, который не имеет компиляции-ссылки в рамках стандартной процедуры работы.

То, что я ищу, является тем, что пройдет тест "inline-online-universal".

  • (inline) Вы можете написать обозначение inline с другим кодом, как с регулярным выражением.

  • (онлайн) Вы можете запустить полученный парсер так же, как и ваш другой код, что означало бы сразу после ввода в REPL в случае чего-то вроде Python.

  • (универсальный) Вы можете перейти на другой язык/платформу и использовать практически тот же код для разбора парсера, по модулю диалектов. На самом деле, я был бы доволен тем, что работает с Python, Ruby, C, Java и Haskell.

Большинство инструментов, которые я знаю, попадают в "онлайн". Они предварительно обрабатывают грамматику в автономном режиме и выплевывают код на целевом языке (C, Python, Java, С++...). Это автономные инструменты, которые сами не интегрированы в языковую среду.

У меня были предложения парсеров PEG и компиляторов lex/yacc. Библиотеки комбинаторов Parser также могут хорошо подходить. Что бы вы ни предложили, я хотел бы продемонстрировать, что он соответствует этим тестам. Ваш ответ должен продемонстрировать, что предлагаемое решение отвечает требованиям inline-online-universal, предоставляя рабочий демонстрационный парсер в Python, C и Haskell. Демо-пример зависит от автора, но он должен быть чем-то болезненным, используя только регулярное выражение, но тривиально, используя правильный парсер.

Ответ 1

https://github.com/leblancmeneses/NPEG

Реализует ПЭГ.

Отвечает всем 3... позвольте мне объяснить.

Он встроен только в С# и отключен от всех остальных. С# также имеет автономную версию.

В настоящее время я поддерживаю автономные версии: C/С++/Javascript (локальный прямо сейчас)/Java передает все модульные тесты - чтобы сделать его универсальным. Для добавления другого языка требуется 25,84 часа (сколько времени понадобилось для создания автономной версии Javascript).

Чтобы сделать его онлайн для каждого языка, было бы много обслуживания (возможно), но мне потребовалось много работы и времени, чтобы поддерживать текущие офлайн-версии. Теперь я могу сосредоточить свою энергию на создании оптимизаторов грамматики и инструментов для правил грамматики unit test, где выигрывают все автономные версии.

Ответ 2

Посмотрите на Lex/Yacc или их коллеги Flex/Bison (или Coco или все остальные генераторы компилятора). Комбинация может использоваться для анализа сложных текстовых данных с (возможно) гораздо более читаемым синтаксисом, чем с regexen.

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