Pull to refresh

Comments 17

А вы не хотите вместо написания yet another parser перенести на php комбинатор парсеров parsec?
Спасибо, уже нашёл эту же ссылку же через Google. :^)

Да, идея интересная, благодарю. Не сталкивался с этой штукой раньше. Будет время — обязательно разберусь и займусь (если никто ещё не перенёс, конечно :^)
Осторожно, и придерживайте мозг свободной рукой, когда будете читать :)
Почитайте «Книгу дракона» Ахо, Сети и Ульмана.
Да и мануал по функции token_get_all() думаю не повредит.
За совет насчёт книги — спасибо, я обязательно прочитаю.

А вот по поводу token_get_all — я про неё знаю, и она прекрасно подойдёт для грамматического разбора выражения — если оно записано на PHP. Не уверен, что синтаксис PHP подойдёт в 100% случаев.
В книге рассматриваются, кроме всего прочего, существующие генераторы синтаксических анализаторов. А в конце книги приводится синтаксис языков С, Java и, если память не изменяет, C#. Думаю с учетом ваших интересов, стоит уделить на это особое внимание, чтобы не изобретать велосипед.
Кроме того, рассматривая разбор граматики математических выражений, не стоит забывать о функциях. Применяя простые грамматики типа LL(1) вполне можно реализовать ваши пожелания :)
Благодарю ещё раз за полезную ссылку — я действительно собирался в ближайшее время заниматься подобными разработками (правда, не на PHP, и данный парсер не имеет к ним никакого отношения :^), так что с этой литературой так же ознакомлюсь.
Не за что. Единственный момент: «книг дракона» 3 части. Первая — практически на одной теории, вторая со множеством примеров на C и Pascal. Третья — с примерами на Java. Выбирайте ту, что наиболее вам подходит.
не смотрел код, но прочитал бегло статью. Сам удивлялся почему ничего подобного пока еще никто не описал. Хотя реально нужно как правило «маленький» парсер, а он пишется за пару часиков.
не говорю конкретно про Вас, но обычно когда говорят «пару часиков» то дело сводится к пару дням… парсер — не регулярное выражение которое бьет строку на части, и это надо изначально учитывать
парсер именно выражения даже проще может быть — например рекурсивный спуск

Вообще гугль по «parser generator php» выдает ненулевой результат
Во-первых, я хочу поблагодарить всех за ссылки на полезный материал по этой теме. Многое из этого полезно было вспомнить, а что-то — узнать. И всё это наверняка будет полезно тем, кто данный топик читает как " ещё один источник по теме".

Теперь о простоте. ОПЗ по своей сути тоже не самая сложная процедура для разбора простого математического выражения — я её и выбрал за её простоту. Но в её алгоритм изначально не заложены возможности

1) Использования сложных операторов и инструкций.
2) Вызова функций (настоящего, а не в форме sin(x), который превращается в вызов оператора sin).

Таким образом алгоритм ОПЗ в данной библиотеке был расширен, во-первых, тем что в базовый алгоритм были внесены дополнительные понятия, и, во-вторых, тем что возможности по определению команд и грамматических классов оставлены на откуп пользователю, благодаря чему вы сможете парсить как выражения а-ля
(A * B? sin: cos)(10)
так и
Если A умножить на B тогда sin иначе cos аминъ вызвать с аргументами 10 аминъ
или чуть посерьёзнее, типа
IF(A MUL B, CONCAT(user.lastname, ' ', user.firstname), 'Unknown user')

Но я соглашусь с тем, что

1. Универсальность полученного парсера — это его недостаток. Если «вернуться к истокам» ОПЗ и жёстко определить грамматические классы, код сократится раз в десть точно. Но тогда не получится парсить такие замечательные выражения, как «Давай 10 прибавь-ка к 12, вот.» (ассоциативность правая, вроде :^) А если серьёзно — невозможно заранее предугадать цели, с которыми данный парсер будет использоваться. Поэтому я бы порекомендовал использовать данный парсер (если кто-то, конечно, будет это делать) не наследованием класса CIpr, как это «предусмотрено стандартом» библиотеки, а отстриганием от библиотеки всего ненужного для решения конкретной задачи и жёстким определением всего, что отдано на откуп пользователю — производительность возрастёт в разы, равно как и уменьшится объём кода.

2. «Простой» парсер в PHP — это то же самое, что шоколадка с шоколадной начинкой. PHP сам по себе уже является неплохим «парсером», т.е. во многих случаях, когда встаёт вопрос о необходимости парсера математики или даже более сложных конструкций, достаточно использовать eval для получения нужного результата. Причём eval, по понятным причинам, сработает заведомо быстрее любого, даже самого оптимального алгоритма, реализованного на PHP. Построение любого парсера либо преследует чисто академическую цель, либо нужно для решения задач, которые значительно сложнее простых математических выражений (как в данном случае).

Это я всё к тому, что я хотел предостеречь тех, кто собирается использовать данное решения для вычисления выражений типа 1 + 2 / 3, и уж тем более тех, кто собирается для подобных целей изобретать свой парсер «с блэкджеком и шлюхами» (с) Бендер. Если бы я, на момент написания этого «шедевра» имел уже готовую альтернативу для реализации собственного языка описания данных, я бы воспользовался ей.

Благодарю за внимание тех, кто до сюда дочитал — я люблю изъясняться развёрнуто. :^)
я о сроках, я писал простенький парсер, который парсил банальные условия вида if( {field} = value and|or {field2} != value2… ) и это не выглядит очень прям сложным, но заняло далеко не пара часов
это вместе с лексером? В проуессе вы что нибудь учили или вы помнили курс конструирования компиляторов?
нет, я ничего не учил, работал императивным методом, я вкурсе что это замедлило процесс, но задача изначально казалась проще, надо было просто чекнуть галочки по условию на JS, и я тоже подумал что справлюсь за «пару часов»
Sign up to leave a comment.

Articles