Как реализовать форму Backus-Naur в Python

Я знаю, что есть несколько смутно похожих вопросов, уже относящихся к грамматикам BNF (Backus-Naur Form) в Python, но ни один из них не помогает мне с точки зрения моего приложения.

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

Первый BNF, с которым я работаю, для всех действительных чисел в Python. Это выглядит так:

<real number>    ::= <sign><natural number> |
                     <sign><natural number>'.'<digit sequence> |
                     <sign>'.'<digit><digit sequence> |
                     <sign><real number>'e'<natural number>
<sign>           ::= ‘’ | ‘+’ | ‘-‘
<natural number> ::= ‘0’ | <nonzero digit><digit sequence>
<nonzero digit>  ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<digit sequence> ::= ‘’ | <digit><digit sequence>
<digit>          ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Любые синтаксические анализаторы BNF, которые я нашел для Python, кажутся необычайно сложными или используют внешние библиотеки. Есть ли более простой способ проверки и генерации с использованием BNF-грамматики в Python?

Ответ 1

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

Я не знаю, связаны ли ваши приложения с лексическим сканированием, но если нет, ply - довольно простой в использовании парсер (учитывая, что вам нужно знать, как работают парсеры).


Изменить: резервная копия указанной страницы находится на archive.org:

Ответ 2

посмотрите https://github.com/erikrose/parsimonious

Parsimonious стремится стать самым быстрым произвольным анализатором, написанным на чистом Python, и наиболее пригодным для использования. Он основан на анализе грамматических выражений выражения (PEG), что означает, что вы подаете им упрощенную нотацию EBNF.

Ответ 3

У меня были хорошие впечатления от grako.

Я использовал его для parseWKT.

В качестве входа берет EBNF и генерирует парсер PEG.

Я думаю, было бы разумно просто написать BNF для анализатора EBNF в grako, который затем сгенерировал парсер из EBNF