Вода

Как написать рекурсивный парсер?, Разработка на C# под linux
 

зачем вообще используют грамматики:
wide range of stuff in which parsers are useful. Web development. Programming Language Interpreters. Inhouse Tools. Gaming Engines. Map and Tile Editors etc.


There are so very different idiomatic approaches for different languages.
You can't write a parser the same way in Fortran and, say, Haskell.
In C# you can use, say, combinators, just like in the real programming languages, and it can be a sensible approach for some grammars.

http://antlr.org/

Combinators in C#

http://blog.efvincent.com/combinators-in-c/

Сплошной парсинг

The parser’s job is to give semantic structure to the syntactic tokens
ну так вот есть идея, что токены - зло. Надо делать единый сквозной парсер до символов.

BNF grammar

https://ru.wikipedia.org/wiki/Форма_Бэкуса_—_Наура
формальная система описания синтаксиса, в которой одни синтаксические категории последовательно определяются через другие категории.

БНФ-конструкция состоит из нескольких предложений вида
 <определяемый символ> ::= <посл.1> | <посл.2> | . . . | <посл.n>

, описывающих правила. Такое правило означает, что символ <определяемый символ> может заменяться на одну из последовательностей <посл.i>. Знак определения обычно выглядит как ::= или ,

Как обрабатывать концы строк

Файл состоит из строк (это сложно отрицать)
файл : ( строка разделитель-строк ) * строка ? разделитель-строк ? ;

но это правило не потребуется, мы просто будем с этого этапа выдавать символы
строка : символ * ;

обобщенный-разделитель-строк прийдётся тоже выдавать и использовать в правилах высшего порядка, за исключением правила про имена секции, где надо будет использовать <пробелы>

Инкрементальная компиляция

Для обеспечения диагностики
каждый объект будет содержать массив интервалов (начало, длина) - где этот объект располагается в исходном тексте

не будем выкидывать обобщенный-разделитель-строк и пробелы, потом что надо выполнить требование "Section headers cannot span multiple lines"