2016-11-15 17 views
2

Я хотел бы привести пример грамматики ПЭГ для глубоко вложенных булевых выражений Python. Грамматика PEG не может быть «очень рекурсивной», иначе это приведет к переполнению стека. Требуется поддержка '|', '&', '(' и ')'.Требуется: пример (ы) грамматики PEG для глубоко вложенных булевых выражений Python

Пример ввода: (а = 1 | Ь = 1 | с = 1 | д = 1 & е = 2) & (е = 2 & г = 2 & ч = 2 | г = 3 | J = 3 | k = 3)

ответ

1

Чтобы разобрать типичные (особенно булевы логические) выражения, вам вряд ли нужен парсер 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 миллиона линейных программ с каждой странной конструкцией и глубоко вложенным лексическим очерченным трюком, известным человечеству в этом.

+0

Hi Ira. Спасибо за отличный ответ :) Мне нужна грамматика ПЭГ для подачи на генератор парсера. То, что я подразумевал под «вложенным», состояло в том, что грамматика в идеале не должна создавать двоичное дерево - это приводит к очень глубокому дереву, если выражение имеет много OR и AND. Грамматика у меня правильно рекурсивная (я думаю, что это правильный термин) и приводит к переполнению стека для очень длинных выражений (даже без круглых скобок): https://github.com/kschiess/parslet/blob/master/example/boolean_algebra. rb – SoupMonster

+0

Спасибо Ира. Я отказался от использования PEG-грамматического генератора-парсера из-за отсутствия поддержки отладки. Думаю, я пойду за свой письменный подход! :) – SoupMonster