Comments 17
… простите: лучшей, вероятно, будет эта ссылка: www.haskell.org/haskellwiki/Parsec
0
Почитайте «Книгу дракона» Ахо, Сети и Ульмана.
Да и мануал по функции token_get_all() думаю не повредит.
Да и мануал по функции token_get_all() думаю не повредит.
+1
За совет насчёт книги — спасибо, я обязательно прочитаю.
А вот по поводу token_get_all — я про неё знаю, и она прекрасно подойдёт для грамматического разбора выражения — если оно записано на PHP. Не уверен, что синтаксис PHP подойдёт в 100% случаев.
А вот по поводу token_get_all — я про неё знаю, и она прекрасно подойдёт для грамматического разбора выражения — если оно записано на PHP. Не уверен, что синтаксис PHP подойдёт в 100% случаев.
0
В книге рассматриваются, кроме всего прочего, существующие генераторы синтаксических анализаторов. А в конце книги приводится синтаксис языков С, Java и, если память не изменяет, C#. Думаю с учетом ваших интересов, стоит уделить на это особое внимание, чтобы не изобретать велосипед.
Кроме того, рассматривая разбор граматики математических выражений, не стоит забывать о функциях. Применяя простые грамматики типа LL(1) вполне можно реализовать ваши пожелания :)
Кроме того, рассматривая разбор граматики математических выражений, не стоит забывать о функциях. Применяя простые грамматики типа LL(1) вполне можно реализовать ваши пожелания :)
+1
Благодарю ещё раз за полезную ссылку — я действительно собирался в ближайшее время заниматься подобными разработками (правда, не на PHP, и данный парсер не имеет к ним никакого отношения :^), так что с этой литературой так же ознакомлюсь.
0
не смотрел код, но прочитал бегло статью. Сам удивлялся почему ничего подобного пока еще никто не описал. Хотя реально нужно как правило «маленький» парсер, а он пишется за пару часиков.
0
не говорю конкретно про Вас, но обычно когда говорят «пару часиков» то дело сводится к пару дням… парсер — не регулярное выражение которое бьет строку на части, и это надо изначально учитывать
0
парсер именно выражения даже проще может быть — например рекурсивный спуск
Вообще гугль по «parser generator php» выдает ненулевой результат
Вообще гугль по «parser generator php» выдает ненулевой результат
0
Во-первых, я хочу поблагодарить всех за ссылки на полезный материал по этой теме. Многое из этого полезно было вспомнить, а что-то — узнать. И всё это наверняка будет полезно тем, кто данный топик читает как " ещё один источник по теме".
Теперь о простоте. ОПЗ по своей сути тоже не самая сложная процедура для разбора простого математического выражения — я её и выбрал за её простоту. Но в её алгоритм изначально не заложены возможности
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, и уж тем более тех, кто собирается для подобных целей изобретать свой парсер «с блэкджеком и шлюхами» (с) Бендер. Если бы я, на момент написания этого «шедевра» имел уже готовую альтернативу для реализации собственного языка описания данных, я бы воспользовался ей.
Благодарю за внимание тех, кто до сюда дочитал — я люблю изъясняться развёрнуто. :^)
Теперь о простоте. ОПЗ по своей сути тоже не самая сложная процедура для разбора простого математического выражения — я её и выбрал за её простоту. Но в её алгоритм изначально не заложены возможности
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, и уж тем более тех, кто собирается для подобных целей изобретать свой парсер «с блэкджеком и шлюхами» (с) Бендер. Если бы я, на момент написания этого «шедевра» имел уже готовую альтернативу для реализации собственного языка описания данных, я бы воспользовался ей.
Благодарю за внимание тех, кто до сюда дочитал — я люблю изъясняться развёрнуто. :^)
0
я о сроках, я писал простенький парсер, который парсил банальные условия вида if( {field} = value and|or {field2} != value2… ) и это не выглядит очень прям сложным, но заняло далеко не пара часов
0
это вместе с лексером? В проуессе вы что нибудь учили или вы помнили курс конструирования компиляторов?
0
мои потуги тут: habrahabr.ru/blogs/php/73665/
0
Sign up to leave a comment.
Отвёртка для выражений