Что такое хороший генератор парсера для php?

Мне нужно разобрать небольшой «мини-язык», который пользователи могут набирать на моем сайте. Мне было интересно, что аналоги из lex и jacc или antlr для мира php.

Несколько лет назад я использовал генератор LIME Parser для PHP , и он был уже зрелым и стабильным.

Сам генератор синтаксиса написан на PHP, что не имеет никакого значения в каком-либо техническом смысле – поскольку нам требуется только, чтобы сгенерированный синтаксический анализатор был в PHP, но тем не менее мне нравится эта деталь. Это заставляет меня чувствовать себя менее извиняющимся в написании программного обеспечения на PHP 😉

РЕДАКТИРОВАТЬ:

Я должен добавить:

  1. Где я писал «использовал», было бы более точно сказать, что я «играл». Я еще не написал никакого производственного кода, используя известь. Но я не вижу причин не делать этого.

  2. В «примере калькулятора», снабженном лаймом, используется метод tokenize (), который очень далек от реальной замены мощности lex. Но если вам нужен реальный токенизатор, следует использовать lex на «переднем конце» для подачи токенов на извести на «конец».

Я портировал Jison, клон Bison в javascript, к php. Результатом является синтаксический анализатор, способный обрабатывать очень простой и очень сложный лексинг / синтаксический анализ. Теперь это часть Jison, но в моей вилке есть несколько обновлений – https://github.com/robertleeplummerjr/jison . Файлы находятся здесь – https://github.com/robertleeplummerjr/jison/tree/master/ports/php

См. Readme на этой странице, вы одновременно создаете парсер javascript и php, способный делать то же или разные вещи. КРУТО!

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

Самый простой способ сделать это – это, на мой взгляд, создать один класс для каждого типа синтаксиса (выражение, тест, цикл и т. Д.).

Затем в каждом классе введите следующие методы:

  • один метод для определения из строки, если строка имеет заданный тип ( a+b имеет тип «выражение», if(b) не является)
  • один метод «запустить» этот тип ( a+b вернет a->run() + b->run() , а a->run() вернет значение)