Будь-який гідний парсер PHP, написаний на PHP? [зачинено]


80

Я роблю багато роботи, маніпулюючи та аналізуючи PHP-код. Зазвичай для цього я просто використовую маркер . Для більшості програм цього достатньо. Але іноді розбір за допомогою лексера просто недостатньо надійний (очевидно).

Таким чином, я шукаю якийсь парсер PHP, написаний на PHP. Я знайшов hnw / PhpParser та kumatch / stagehand-php-parser . Обидва вони створюються шляхом автоматизованого перетворення zend_language_parser.y у файл .y з PHP замість C (а потім компілюється в синтаксичний аналізатор LALR (1)). Але з цим автоматичним перетворенням просто неможливо працювати.

Отже, чи існує якийсь гідний парсер PHP, написаний на PHP? (Мені потрібен один для PHP 5.2 і один для 5.3. Але лише один із них також буде гарною відправною точкою.)


1
Яка ваша мета? Що ви намагаєтесь досягти тут?
Чарльз

3
@Charles: Є багато речей, для яких я б використав це. Будь-що, що потребує вихідного коду PHP у поданні AST;)
NikiC

1
@mario: Цей викидає багато інформації. Він справді призначений лише для того, щоб витягти деяку інформацію про файл. Отже, він зберігає лише такі речі, як оператори класу, оператори методів або оператори return, але ігнорує все, що насправді мене найбільше цікавить: код.
NikiC

2
Я не думаю, що ви знайдете будь-який масштабний, надійний синтаксичний аналізатор, закодований на PHP. До цього просто немає заклику.
Ira Baxter

4
За останній тиждень я сам написав початкову версію синтаксичного аналізатора: github.com/nikic/PHP-Parser Я протестував його на основі своєї кодової бази, і він працював добре. Я буду працювати над вдосконаленням інтерфейсів, щоб він був фактично придатним для використання.
NikiC

Відповіді:


128

Після того, як тут не було знайдено повноцінного та стабільного парсера, я вирішив написати його сам. Ось результат:

PHP-парсер : PHP-аналізатор, написаний на PHP

Проект підтримує синтаксичний аналіз коду, написаного для будь-якої версії PHP між PHP 5.2 та PHP 7.1.

Окрім самого синтаксичного аналізатора, бібліотека містить деякі супутні компоненти:

  • Компіляція AST назад до PHP ("симпатичний друк")
  • Інфраструктура для обходу та зміни AST
  • Серіалізація до та з XML (а також скидання в зручній для читання формі)
  • Вирішення імен з простором імен (псевдоніми тощо)

Для того використання Огляд см «Використання основних компонентів» розділ документації .


2
Це круто! Чи плануєте ви його підтримувати?
MikeSchinkel

1
@NikiC Дякую людино! Це чудова бібліотека :-)
Б.Венгеров

1
Вау, підтримка PHP 7.1 на початку грудня '11!
dotancohen

9

Це не буде чудовим варіантом для вас, оскільки воно порушує обмеження pure-PHP, але:

Деякий час тому люди з php-інтерналів вирішили, що вони перейдуть на Lemon як свою технологію синтаксичного аналізу. У репозиторії svn PHP є гілка, яка містить необхідні зміни.

Вони вирішили не продовжувати з цим , оскільки виявили, що їх лимонний розчин повільніше приблизно на 10-15%. Але, філія все ще є.

Існує старіший парсер Lemon, написаний як розширення PHP. Можливо, ви зможете з цим працювати. Є також цей пакет PEAR . Є також цей інший лимонний пакет (через цю публікацію в блозі про PGN ).

Звичайно, навіть якщо ти змусиш це працювати, я не впевнений, що ти зробив би з даними або як ці дані навіть виглядають.

Ще одним шаленим варіантом було б заглянути в Quercus , реалізацію PHP на Java. Вони мали б написати синтаксичний аналізатор, можливо, варто було б дослідити.


Перш за все: +1 для широкого дослідження. Основна проблема полягає не в тому, що в PHP немає можливості створити парсер. Ви вже згадували про використання граматики Lemon PHP та її компіляцію. Ще простіше було б скористатися "справжньою" граматикою yacc / bison (для цього теж є компілятори). Проблема полягає в тому, що це насправді дуже велика робота по перетворенню коду yacc C для генерації операційних кодів у код PHP yacc для генерації AST. Тож я дивився, чи хтось уже робив цю роботу.
NikiC

@nikic Однією з причин, IMO, що цього ще ніхто не робив, є те, що не існує специфікації того, що насправді є PHP і як його проаналізувати. php-internals раніше відверто відкидав всю концепцію. Як результат, поза самим вихідним кодом PHP немає жодного авторитетного джерела для того, як насправді провести аналіз. Без цього авторитетного джерела для посилання побудова правильного парсера стане справжньою пригодою. На жаль, це означає, що, починаючи з даних yacc або Lemon, може бути найкращим варіантом.
Чарльз,

@nikic, Чарльз: Це була справжня пригода для нашого синтаксичного аналізатора PHP. Підхід: запропонуйте лексер / граматику, спробуйте тисячі файлів, помиліться, налаштуйте, спробуйте ще раз. Щоб отримати надійний синтаксичний аналізатор для погано задокументованої мови, потрібно близько року такого удару. Принаймні це зробило для нас. YMMV, але, ймовірно, не набагато.
Ira Baxter,

7

Інструмент метрики PHP Depend містить код для створення AST із джерела PHP, повністю написаного на PHP. Однак він використовує власний PHP token_get_all для токенізації.

Вихідний код доступний на github: https://github.com/manuelpichler/pdepend/tree/master/src/main/php/PHP/Depend

Реалізація AST для деяких частин, таких як математичні вирази, ще не була завершена останньою, яку я перевірив, але, за словами її автора, це є метою.


Має AST, але не для "математичних операцій" (я припускаю, ви маєте на увазі "вирази"? Це ключова частина мови, особливо, коли ви вважаєте, що "подвійні лапки" (із вбудованими виразами) насправді просто складні рядкові вирази.
Іра Бакстер,

2
Ви отримали нагороду, бо це найближча відповідь на питання. Але очевидно, що він насправді не придатний для використання, оскільки йому бракує, ну, половини граматики PHP ...
NikiC

Зміст цієї публікації застарілий. З тих пір почався активний розвиток, хоча я не знаю, наскільки добре він підтримує граматику PHP.
nhahtdh

4

Ну, це не в PHP, вибачте, але побудувати такий механізм важко, і PHP не особливо підходить для завдання обробки мови.

Наш PHP Front End забезпечує повний розбір PHP 4.x та 5.x (EDIT 9/2016: тепер обробляє PHP 7), синтаксичний аналіз, автоматично створює AST з усіма деталями повної граматики PHP, може генерувати компільований вихідний текст з AST. Це складніше, ніж це може здатися, якщо врахувати всі делікатні деталі, включаючи дивні літеральні рядки, захоплені коментарі, числа з радіусом тощо.

Але AST навряд чи достатньо (ви вже спостерігали, що токенів навіть не вистачає).

Основа, на якій вона побудована, Інструментарій реінжинірингу програмного забезпечення DMS забезпечує підтримку аналізу та довільних перетворень AST. Він також буде читати великі набори файлів одночасно, що дозволяє аналіз і перетворення через PHP файли.


1
Просто як відповідь на перше речення: Уже існують генератори синтаксичного аналізатора, які можуть генерувати синтаксичний аналізатор з граматика yacc (наприклад, kmyacc). Тобто немає великої різниці між побудовою його в PHP та побудовою будь-якою іншою мовою. Все, що вам потрібно зробити, це "просто" (іронія) замінити код C в zend_language_parser.y на деякий PHP-код, який створює дерево вузлів.
NikiC

А щодо решти: я б дуже хотів отримати рішення PHP. Але якщо (і це здається дуже ймовірно) нічого подібного немає, я, мабуть, скористаюся чимось іншим. Я вже кілька разів чув про DMS тут, на SO, я розгляну це.
NikiC

@ninkic: Усі машини Тьюрінга (включаючи PHP) можуть імітувати всі інші машини Тьюрінга, так, звичайно, це можна створити в PHP. Але а) існує лише парсер; Я думаю, що синтаксичний аналізатор PHP не призначений для побудови дерева, а скоріше для подачі генератора p-коду PHP, і я думаю, ви виявите, що потреби різні, і б) люди неодноразово помиляються, вважаючи, що якщо вони мають AST, все інше легко; вони роблять цю помилку здебільшого тому, що не мають досвіду роботи зі складними речами з AST. Я побудував DMS, оскільки це припущення хибне.
Ira Baxter,

1
а) Так, синтаксичний аналізатор PHP не призначений для побудови дерева синтаксичного аналізу, він призначений для побудови потоку операційного коду. Ось чому навряд чи можливо автоматично перетворити парсер мови zend на PHP. б) Я, мабуть, один із тих, хто робить цю помилку;) З того факту, що безліч складних маніпуляцій вже можна робити за допомогою чистого потоку токенів, я зробив висновок (у ваших очах помилково?), що з AST це було б простіше і більш стабільний.
NikiC

@nikic: Уроки 50-річної технології компіляції полягають у тому, що кожне представлення програми полегшує певні речі. Ви можете виконати певну маніпуляцію програмою лише для тексту. Ви можете зробити більше на жетонах. Ви можете зробити ще більше на AST. Ви можете робити по-справжньому цікаві речі, якщо у вас є таблиці символів, елементи керування та інформація про потоки даних (графіки), дані змінних псевдонімів (вказівки на аналіз). Коли ви намагаєтесь зробити вишукане кодування, ви виявляєте, що це все дійсно, дуже корисні речі.
Ira Baxter,

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.