Чи потрібна мова регулярних виразів для автоматичного розбору?


12

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

Я припускаю, що це повинен бути автоматичний поштовх, оскільки подання дужок означає необхідність підрахунку, а DFA / NFA не може проводити довільний підрахунок. Чи правильне це припущення? Наприклад, вираз a (bc *) d вимагатиме PDA, щоб суб-вираз у дужках оброблявся правильно.


1
Що ви маєте на увазі саме під "розбором"? Ви маєте на увазі перевірити, чи введення дійсно є регулярним виразом, чи маєте на увазі щось складніше, наприклад, машина, яка видає опис відповідного NFA? (якщо ви не впевнені, чи введення дійсно є регулярним виразом, і вам потрібно перевірити його, вам потрібно мати змогу перевірити правильність дужок і що зазвичай означає використання стека.)
Kaveh,

Для практичної відповіді, ви можете подивитися на джерело Plan 9 Grep для grep.y .
Брюс Едігер

Відповіді:


8

Ви праві. Неважко показати, що синтаксис регулярних виразів не є регулярним за допомогою стандартних прийомів .

Однією з можливостей є використання гомоморфізму (який закритий проти), щоб позбутися від усіх символів, крім дужок, що залишає вас мовою Dyck, яка, як відомо, є нерегулярною. Якщо ви сумніваєтесь, скористайтеся леммою накачки на .( p ) pREG(p)p

Однак, напевно, ви не хочете кодувати КПК від руки. Подумайте про використання генератора аналізатора типу ANTLR або byacc . Якщо, з іншого боку, ви хочете самостійно дослідити розбір мов, програмуючи парсери, вам слід продовжити інші алгоритми розбору, такі як CYK , Earley , рекурсивний спад і LR .


Дякую. Написання коду для цих завдань створює краще розуміння, і воно не має бути настільки ефективним, як існуючі утиліти, такі як lex, yacc, bison тощо.
Phil Wright

@PhilWright: Бачу, приємно! Я редагував в інших покажчиках цього випадку.
Рафаель

Я б віддав перевагу ручному кодованому рекурсивному аналізатору спуску для цього.
Дейв Кларк

Якщо писати аналізатор вручну для цього, будь-який рекурсивний спуск (після факторингу та масажування) є варіантом, LCC-аналізатор для C < sites.google.com/site/lccretargetablecompiler > має цікаве значення для обробки багатьох операторів. Але, мабуть, найпростішим для ручного побудови є аналіз пріоритетності.
vonbrand

3

Я пропоную вам прочитати приємну відповідь Юкки на питання " Відповідність регулярних виразів із використанням регулярних виразів " і на cstheory. Уривок:

Наприклад, ми можемо змінити стандартні позначення наступним чином, щоб отримати "стислі" регулярні вирази :

  • Ви можете видалити будь-який префікс, який складається з послідовності ('s
  • Ви можете видалити будь-який суфікс, що складається з послідовності)

Тобто, ((a|b)*c)de(f|g)можна виразити позначення «стиснене», використовуючи, наприклад, будь-яку з наступних форм: a|b)*c)de(f|gабо ((a|b)*c)de(f|gабо (a|b)*c)de(f|g).

[...]

Позначення "стисненого" (регулярного виразу) - це звичайна мова.

Це лише посилання на цікавий (на мою думку) "різний погляд" на мову регулярних виразів; як підкреслено в коментарях нижче, це не корисно для побудови синтаксичного дерева. Якщо ви хочете передати код свого парсера, я запропоную вам цю просту статтю про codeproject " Writing-own-regular-expression-parser ".


Jukka по суті знімає вимогу збалансованості дужок. Я не знаю жодного випадку, де це насправді робиться, але варто зазначити, що, змінивши семантику, можна "спростити" синтаксис.
Рафаель

4
Ви (і Юкка) не розбираєте регулярні вирази, а лише розпізнаєте їх. "Так, це (стислий) регулярний вираз".
Жиль "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.