многоуровневый алгоритм разбора - PullRequest
2 голосов
/ 02 октября 2010

перефразировать ...

Я хотел бы знать, как лучше всего анализировать функции / условия. так что если у вас есть что-то вроде: [if {a} is {12 or 34}][if {b} not {55}] show +c+ [/if][/if], которое является условным внутри условного. Похоже, я не могу сделать это только с помощью регулярных выражений.


оригинальный вопрос

на данный момент у меня есть довольно простой способ парсинга некоторых команд через actioncript.

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

+key_word+  // any text surrounded by +
[ifempty +val_1+]+val_2+[/ifempty]  //simple conditional
[ifisnot={`true,yes`} +ShowTitle+]+val_3+[/ifisnot]  // conditional with operands

мой текущий алгоритм сопоставляет открывающий тег [**] с первым закрывающим тегом [/**], даже если он не совпадает. Это означает, что я не мог сделать что-то вроде [ifempty +val_2+][ifnotempty +val_2]+val_3+[/ifnotempty]+val_4+[/ifempty] - по сути, поместив одно условие в другое.

Я использую встроенный способ разбора, который разбивает строку на массив строк на основе этого регулярного выражения \[[^\/](?:[^\]])*\](?:[^\]])*\[\/(?:[^\]])*\]

Кто-нибудь может предложить более надежный алгоритм с более надежным соглашением / стандартом синтаксического анализа? специально для as3.

1 Ответ

2 голосов
/ 16 ноября 2010

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

Один из способов размышления об этом состоит в том, что все Регулярные языки могут быть представлены конечным автоматом.Вам потребуется состояние для каждого возможного числа «если», но машина должна быть «конечной», так что вы в затруднении.Классический пример:

a{n}b{n}, n >= 0
(meaning n a's, followed by n b's)

Когда вы анализируете каждый a, вам нужно перейти в другое состояние (у FSM нет памяти вне состояния, в котором они находятся, это единственный способ, которым они могут запомнить n, чтобы сопоставить егопотом).Для разбора любого числа n вам понадобится бесконечное число состояний.

Это та же самая ситуация, в которой вы находитесь, регулярное выражение может выражать конечное число ifs (хотя это займет совсем немногокопирования-вставки), но не бесконечное число.Однако обратите внимание, что некоторые реализации регулярных выражений немного обманывают, давая им больше возможностей, чем их математические эквиваленты.

В любом случае, лучше всего использовать более мощный метод синтаксического анализа. парсер рекурсивного спуска особенно интересен в реализации и может легко сделать то, что вам нужно.Вы также можете заглянуть в LR-парсер или создать простой парсер, используя стек.В зависимости от вашего языка, вы можете найти библиотеку синтаксического анализа, такую ​​как pyparse для Python или Boost Spirit для C ++.

...