1) для того, чтобы описать какой-нибудь язык формально, нужно описать его грамматику.

Причём сделать это не так, как делали инженеры СССР ("для общего понимания"), а чтобы компьютер тоже мог этим пользоваться.

2) если мы рассматриваем подход "с раскруткой", то в начале нет ничего,
и парсер грамматики БНФ придётся писать вручную (но всё равно по грамматике).

3) работу можно упростить, приняв предположения:
3.1) что сначала мы обходимся без лексера (грамматика идёт прямо от символов)
3.2) что мы не обрабатываем комментарии (они усложняют грамматику, а этап первый)
3.3) с пробелами не ясно - можно добавить, можно не добавлять (они же "для читаемости")

4) Я думаю, что первая грамматика должна быть без пробелов.
Используя её можно будет описать первый язык для регулярных выражений,
и затем сделать двухэтапный парсинг (регулярки-бнф), который как раз будет вырезать ПРОБЕЛЫ.
При наличии лексера будет обоснование почему пробелы можно (и пора́, и своевре́менно) вводить в синтаксис языков следующего уровня..

Написать парсер БНФ методом рекурсивного спуска нужно для того, чтобы
в памяти получить описание грамматики, и применить к нему различные алгоритмы
(выявления неоднозначностей, левой рекурсии, и т.п.).

А ты прямо кодом языка программирования (в его синтаксисе) объекты в памяти создай, и всё проверь, скажут они.
Создавайте. Я бы выбрал JavaScript - он объектный, всемирно доступный, хорошо подходит для демонстрации результатов.

Наличие такого инструмента позволит создавать уже более сложные грамматики, например с комментариями.
Вручную это пока как-то не получается...

Код:
анализируемый_файл
	| ε
	| непустой_файл
	
непустой_файл
	| содержательная_часть_файла
	| непустой_файл_начинающийся_с_пробелов

непустой_файл_начинающийся_с_пробелов
	| череда_пробелов_и_разделителей_строк
	| череда_пробелов_и_разделителей_строк содержательная_часть_файла

содержательная_часть_файла
	| возможно_предкомментированная_грамматика_бнф
	| возможно_предкомментированная_грамматика_бнф финальные_комментарии_или_белое_место
	
финальные_комментарии_или_белое_место
	| череда_пробелов_и_разделителей_строк
	| череда_комментариев_с_однострочным_в_конце
	| череда_пробелов_и_разделителей_строк череда_комментариев_с_однострочным_в_конце
	| череда_комментариев_вцп
	| череда_пробелов_и_разделителей_строк череда_комментариев_вцп

возможно_предкомментированная_грамматика_бнф
	| череда_комментариев цепочка_пустых_строк_вцп грамматика_бнф
	| грамматика_бнф

грамматика_бнф
	| вереница_правил
	
вереница_правил
	| возможно_предкомментированное_правило
	| возможно_предкомментированное_правило_вцп цепочка_пустых_строк_вцп вереница_правил

возможно_предкомментированное_правило_вцп
	| возможно_предкомментированное_правило
	| возможно_предкомментированное_правило цп

возможно_предкомментированное_правило
	| многострочный_комментарий_вцп правило
	| многострочный_комментарий_вцп рс_вцп правило
	| правило
	
правило
	| нетерминал_вцп правая_часть_правила
	| нетерминал_вцп многострочный_комментарий_вцп правая_часть_правила
	| нетерминал_вцп рс_вцп правая_часть_правила
	| нетерминал_вцп многострочный_комментарий_вцп рс_вцп правая_часть_правила
	| нетерминал_вцп однострочный_комментарий рс_вцп правая_часть_правила
	
правая_часть_правила
	| цепочка_разделитель_частей_правила_вцп череда_альтернатив
	
череда_альтернатив
	| возможно_предкомментированная_альтернатива
	| возможно_предкомментированная_альтернатива цепочка_альтернатив_продолжение
	| возможно_предкомментированная_альтернатива_вцп рс_вцп цепочка_альтернатив_продолжение
	| возможно_предкомментированная_альтернатива_вцп однострочный_комментарий рс_вцп цепочка_альтернатив_продолжение
	| возможно_предкомментированная_альтернатива_вцп многострочный_комментарий_вцп цепочка_альтернатив_продолжение
	| возможно_предкомментированная_альтернатива_вцп многострочный_комментарий_вцп рс_вцп цепочка_альтернатив_продолжение
	
цепочка_альтернатив_продолжение
	| цепочка_разделитель_альтернатив череда_альтернатив
	| цепочка_разделитель_альтернатив_вцп череда_альтернатив
	| цепочка_разделитель_альтернатив_вцп многострочный_комментарий_вцп череда_альтернатив
	| цепочка_разделитель_альтернатив_вцп однострочный_комментарий рс_вцп череда_альтернатив

возможно_предкомментированная_альтернатива_вцп
	| возможно_предкомментированная_альтернатива
	| возможно_предкомментированная_альтернатива цп
	
возможно_предкомментированная_альтернатива
	| альтернатива
	| многострочный_комментарий_вцп альтернатива

альтернатива
	| вереница_терминалов_или_нетерминалов

вереница_терминалов_или_нетерминалов
	| терминал_или_нетерминал
	| терминал_или_нетерминал_вцп вереница_терминалов_или_нетерминалов

терминал_или_нетерминал_вцп
	| терминал_или_нетерминал
	| терминал_или_нетерминал цп

терминал_или_нетерминал
	| цепочка_обозначающая_ничто
	| терминал
	| нетерминал

терминал
	| цепочка_маркирующая_начало_терминала цепочка_элементов_терминала цепочка_маркирующая_конец_терминала

цепочка_элементов_терминала
	| элемент_терминала
	| элемент_терминала цепочка_элементов_терминала

элемент_терминала
	| символ_как_есть_кроме_начала_цепочки_маркирующей_выход
	| символ_в_виде_шестнадцатеричного_кода

символ_в_виде_шестнадцатеричного_кода
	| цепочка_различитель_шестнадцатеричного_кода цепочка_шестнадцатеричных_цифр

цепочка_шестнадцатеричных_цифр
	| символ_шестнадцатеричный_цифровой
	| символ_шестнадцатеричный_цифровой цепочка_шестнадцатеричных_цифр

нетерминал_вцп
	| нетерминал
	| нетерминал цп

нетерминал
	| символ_подчёркивание
	| символ_подчёркивание символ_подчёркивание
	| символ_подчёркивание нетерминал_без_начального_подчёркивания
	
нетерминал_без_начального_подчёркивания
	| слово_или_словосочетание
	| слово_или_словосочетание символ_подчёркивание 

слово_или_словосочетание
	| слово
	| словосочетание
	
слово
	| первый_элемент_слова
	| первый_элемент_слова вереница_элементов_слова

вереница_элементов_слова
	| последующий_элемент_слова
	| последующий_элемент_слова вереница_элементов_слова

первый_элемент_слова
	| символ_кириллический

последующий_элемент_слова
	| символ_кириллический
	| символ_арабский_цифровой

словосочетание
	| первое_слово_словосочетания
	| первое_слово_словосочетания цепочка_разделитель_слов_в_словосочетании череда_слов_словосочетания

череда_слов_словосочетания
	| элемент_череды_слов_словосочетания
	| элемент_череды_слов_словосочетания цепочка_разделитель_слов_в_словосочетании череда_слов_словосочетания

элемент_череды_слов_словосочетания
	| последующее_слово_словосочетания

первое_слово_словосочетания
	| слово

последующее_слово_словосочетания
	| вереница_элементов_слова



череда_комментариев_с_однострочным_в_конце
	| череда_однострочных_комментариев
	| череда_комментариев череда_однострочных_комментариев

череда_комментариев_вцп
	| череда_комментариев
	| череда_комментариев цп

череда_комментариев
	| элемент_череды_комментариев
	| элемент_череды_комментариев череда_комментариев
	
элемент_череды_комментариев
	| череда_однострочных_комментариев  рс_вцп
	| череда_многострочных_комментариев

череда_однострочных_комментариев 
	| однострочный_комментарий
	| однострочный_комментарий рс_вцп череда_однострочных_комментариев
	
череда_многострочных_комментариев
	| многострочный_комментарий
	| многострочный_комментарий_вцп череда_многострочных_комментариев
	| многострочный_комментарий_вцп череда_пробелов_и_разделителей_строк череда_многострочных_комментариев
	
однострочный_комментарий
	| символ_правая_наклонная_черта символ_правая_наклонная_черта
	| символ_правая_наклонная_черта символ_правая_наклонная_черта цепочка_символов_кроме_перевода_строки

многострочный_комментарий_вцп
	| многострочный_комментарий
	| многострочный_комментарий цп

многострочный_комментарий
	| символ_открывающая_круглая_скобка символ_звёздочка продолжение_комментария_документационного_многострочного
	| символ_правая_наклонная_черта символ_звёздочка продолжение_комментария_отладочного_многострочного

продолжение_комментария_документационного_многострочного
        | цепочка_конец_документационного_комментария
        | тело_комментария_документационного_многострочного цепочка_конец_документационного_комментария
        
тело_комментария_документационного_многострочного 
	| элемент_комментария_документационного_многострочного
	| элемент_комментария_документационного_многострочного тело_комментария_документационного_многострочного 

элемент_комментария_документационного_многострочного
	| символ_как_есть_кроме_звёздочки
	| символ_звёздочка символ_как_есть_кроме_закрывающей_круглой_скобки
	

цепочка_конец_документационного_комментария
	| символ_звёздочка символ_закрывающая_круглая_скобка 


продолжение_комментария_отладочного_многострочного
        | цепочка_конец_отладочного_комментария
        | тело_комментария_отладочного_многострочного цепочка_конец_отладочного_комментария

тело_комментария_отладочного_многострочного 
	| элемент_комментария_отладочного_многострочного 
	| элемент_комментария_отладочного_многострочного тело_комментария_отладочного_многострочного
	
элемент_комментария_отладочного_многострочного
	| символ_как_есть_кроме_звёздочки
	| символ_звёздочка символ_как_есть_кроме_правой_наклонной_черты
	
цепочка_конец_отладочного_комментария
	| символ_звёздочка символ_правая_наклонная_черта


цепочка_символов_кроме_перевода_строки
	| символ_как_есть_кроме_начала_разделителя_строк
	| символ_как_есть_кроме_начала_разделителя_строк цепочка_символов_кроме_перевода_строки
	
	
	
	
	
	
	

цепочка_пустых_строк_вцп
	| цепочка_пустых_строк
	| цепочка_пустых_строк цп
	
цепочка_пустых_строк
	| пустая_строка
	| пустая_строка продолжение_череды_разделителей_строк
	
пустая_строка
	| начальный_элемент_череды_разделителей_строк начальный_разделитель_череды_разделителей_строк продолжающий_элемент_череды_разделителей_строк
	
продолжение_череды_разделителей_строк
	| продолжающий_элемент_череды_разделителей_строк
	| продолжающий_элемент_череды_разделителей_строк продолжение_череды_разделителей_строк
	| продолжающий_элемент_череды_разделителей_строк продолжающий_разделитель_череды_разделителей_строк продолжение_череды_разделителей_строк

начальный_элемент_череды_разделителей_строк
	| цепочка_разделитель_строк

продолжающий_элемент_череды_разделителей_строк
	| цепочка_разделитель_строк

начальный_разделитель_череды_разделителей_строк
	| цп

продолжающий_разделитель_череды_разделителей_строк
	| цп
	
череда_пробелов_и_разделителей_строк
	| цепочка_пробельный_символ_или_разделитель_строк
	| цепочка_пробельный_символ_или_разделитель_строк череда_пробелов_и_разделителей_строк

рс_вцп
	| цепочка_разделитель_строк
	| цепочка_разделитель_строк цп

цп
	| цепочка_пробельных_символов

цепочка_пробельных_символов
	| цепочка_пробельный_символ
	| цепочка_пробельный_символ цепочка_пробельных_символов


цепочка_пробельный_символ_или_разделитель_строк
	| цепочка_пробельный_символ
	| цепочка_разделитель_строк

цепочка_пробельный_символ
	| символ_пробел
	| символ_табуляция


цепочка_разделитель_строк
	| цепочка_разделитель_строк_линукс
	| цепочка_странный_разделитель_строк

цепочка_разделитель_строк_линукс
	| символ_перевода_строки

цепочка_странный_разделитель_строк
	| символ_возврата_каретки
	| символ_возврата_каретки символ_перевода_строки


цепочка_обозначающая_ничто
	| символ_ничто
	
	
цепочка_разделитель_частей_правила_вцп
	| цепочка_разделитель_частей_правила
	| цепочка_разделитель_частей_правила цп

цепочка_разделитель_частей_правила
	| символ_вертикальная_черта

цепочка_разделитель_альтернатив_вцп
	| цепочка_разделитель_альтернатив
	| цепочка_разделитель_альтернатив цп
	
цепочка_разделитель_альтернатив
	| символ_вертикальная_черта

цепочка_разделитель_слов_в_словосочетании
	| символ_подчёркивание

цепочка_маркирующая_начало_терминала
	| символ_передние_лапки

цепочка_маркирующая_конец_терминала
	| символ_задние_лапки

цепочка_различитель_шестнадцатеричного_кода
	| символ_левая_наклонная_черта символ_кодепоинта_юникода



символ_как_есть_кроме_начала_разделителя_строк
	| символ_как_есть_кроме_особых
 	| символ_звёздочка
	| символ_задние_лапки
	| символ_правая_наклонная_черта
	| символ_закрывающая_круглая_скобка

символ_как_есть_кроме_звёздочки
	| символ_как_есть_кроме_особых
	| символ_задние_лапки
	| символ_правая_наклонная_черта
	| символ_закрывающая_круглая_скобка
	
символ_как_есть_кроме_правой_наклонной_черты
	| символ_как_есть_кроме_особых
 	| символ_звёздочка
	| символ_задние_лапки
	| символ_закрывающая_круглая_скобка
	
символ_как_есть_кроме_закрывающей_круглой_скобки
	| символ_как_есть_кроме_особых
 	| символ_звёздочка
	| символ_задние_лапки
	| символ_правая_наклонная_черта

символ_как_есть_кроме_начала_цепочки_маркирующей_выход
	| символ_как_есть_кроме_особых
 	| символ_звёздочка
	
символ_как_есть_кроме_особых
	| символ_кириллический
	| символ_арабский_цифровой
	| символ_вертикальная_черта
	| символ_подчёркивание
	| символ_левая_наклонная_черта
	| символ_открывающая_круглая_скобка
	| символ_передние_лапки
	
символ_шестнадцатеричный_цифровой
	| символ_арабский_цифровой
	| символ_английский_эй
	| символ_английский_би
	| символ_английский_си
	| символ_английский_ди
	| символ_английский_и
	| символ_английский_эф

символ_арабский_цифровой
	| символ_арабский_ноль
	| символ_арабский_единица
	| символ_арабский_двойка 
	| символ_арабский_тройка
	| символ_арабский_четвёрка
	| символ_арабский_пятёрка
	| символ_арабский_шестёрка
	| символ_арабский_семёрка
	| символ_арабский_восьмёрка
	| символ_арабский_девятка

символ_кириллический
	| символ_кириллический_заглавный
	| символ_кириллический_строчный


символ_открывающая_круглая_скобка
	| «(»

символ_закрывающая_круглая_скобка
	| «)»
    
символ_звёздочка
	| «*»
    
символ_правая_наклонная_черта
	| «/»

символ_возврата_каретки
	| «\u000D»

символ_перевода_строки
	| «\u000A»

символ_табуляция
	| «\u0009»

символ_пробел
	| «\u0020»


символ_ничто
	| «\u03B5»

символ_подчёркивание
	| «_»

символ_передние_лапки
	| «\u00AB»

символ_задние_лапки
	| «\u00BB»

символ_вертикальная_черта
	| «|»

символ_левая_наклонная_черта
	| «\u005C»

символ_кодепоинта_юникода
	| «u»


символ_английский_эй
	| «A»
	| «a»

символ_английский_би
	| «B»
	| «b»

символ_английский_си
	| «C»
	| «c»

символ_английский_ди
	| «D»
	| «d»

символ_английский_и
	| «E»
	| «e»

символ_английский_эф
	| «F»
	| «f»


символ_арабский_ноль
	| «0»

символ_арабский_единица
	| «1»

символ_арабский_двойка
	| «2»

символ_арабский_тройка
	| «3»

символ_арабский_четвёрка
	| «4»

символ_арабский_пятёрка
	| «5»

символ_арабский_шестёрка
	| «6»

символ_арабский_семёрка
	| «7»

символ_арабский_восьмёрка
	| «8»

символ_арабский_девятка
	| «9»


символ_кириллический_заглавный
	| «А»
	| «Б»
	| «В»
	| «Г»
	| «Д»
	| «Е»
	| «Ё»
	| «Ж»
	| «З»
	| «И»
	| «Й»
	| «К»
	| «Л»
	| «М»
	| «Н»
	| «О»
	| «П»
	| «Р»
	| «С»
	| «Т»
	| «У»
	| «Ф»
	| «Х»
	| «Ц»
	| «Ч»
	| «Ш»
	| «Щ»
	| «Ъ»
	| «Ы»
	| «Ь»
	| «Э»
	| «Ю»
	| «Я»

символ_кириллический_строчный
	| «а»
	| «б»
	| «в»
	| «г»
	| «д»
	| «е»
	| «ё»
	| «ж»
	| «з»
	| «и»
	| «й»
	| «к»
	| «л»
	| «м»
	| «н»
	| «о»
	| «п»
	| «р»
	| «с»
	| «т»
	| «у»
	| «ф»
	| «х»
	| «ц»
	| «ч»
	| «ш»
	| «щ»
	| «ъ»
	| «ы»
	| «ь»
	| «э»
	| «ю»
	| «я»

См. также
Как обрабатывать комментарии?

Отредактировано Лис (2024-11-19 13:19:35)