Чтобы разобрать типичные (особенно булевы логические) выражения, вам вряд ли нужен парсер Peg; никогда не нужно возвращаться. Выберите любой синтаксический анализатор и используйте его (включая двигатель Peg, если вы настаиваете).
Вот грамматика, которая будет работать на ваш пример:
EXPRESSION = DISJUNCTION ;
DISJUNCTION = CONJUNCTION ('|' CONJUNCTION)*;
CONJUNCTION = TERM ('&' TERM);
TERM = '~' TERM | '(' EXPRESSION ')' | CONDITION ;
CONDITION = VARIABLE '=' CONSTANT ;
Если вы хотите реализовать эту грамматику с помощью рукописного, рекурсивного спуска парсера, который легко коды, см моего SO ответа о том, как сделайте это: Is there an alternative for flex/bison that is usable on 8-bit embedded systems?
Что касается переполнения стека: если ваше выражение вложено в сотни уровней («круглых скобок») в большинстве окон или систем Linux, доступный стек намного больше, чем требования стека к парсеру, применяемому к выражения, которые люди пишут на практике. С огромными выражениями, многие люди не могут их прочитать, так что они не происходят. Для выражения примера OP требуется вложение всего нескольких записей в стек.
Если вы пишете грамматику для полноценного языка программирования, а кто-то пишет большую сложную программу в этом langauge, вы можете рискнуть переполнением стека. Я могу рассказать вам по опыту с компилятором, который я построил, что вложение из 256 (стековых фреймов) легко вписывается в стек стека Windows 1Mb, и этого достаточно, чтобы скомпилировать 2 миллиона линейных программ с каждой странной конструкцией и глубоко вложенным лексическим очерченным трюком, известным человечеству в этом.
Hi Ira. Спасибо за отличный ответ :) Мне нужна грамматика ПЭГ для подачи на генератор парсера. То, что я подразумевал под «вложенным», состояло в том, что грамматика в идеале не должна создавать двоичное дерево - это приводит к очень глубокому дереву, если выражение имеет много OR и AND. Грамматика у меня правильно рекурсивная (я думаю, что это правильный термин) и приводит к переполнению стека для очень длинных выражений (даже без круглых скобок): https://github.com/kschiess/parslet/blob/master/example/boolean_algebra. rb – SoupMonster
Спасибо Ира. Я отказался от использования PEG-грамматического генератора-парсера из-за отсутствия поддержки отладки. Думаю, я пойду за свой письменный подход! :) – SoupMonster