В некоторых генераторах нисходящего(LL) синтаксического анализа с увеличением объема текста исходного кода время парсинга увеличивается в более чем арифметической прогрессии.

Часть проблем связанных с производительностью ANTLR описана в статье Вредные советы при работе с ANTLR.

Идея состоит в том, чтобы ввести в самом парсере понятие препарсинга — разбиение текста исходной программы на блоки для отдельного парсинга.

Тексты программ имеют блочную структуру.
к примеру
1 уровень — namespace
2 уровень — классы
3 уровень — методы и свойства
и т.д.

Для Си-подобных языков блоки это просто {}

В языке же Clipper, например,
1 уровень — процедуры/функции/методы, классы, директивы

Правило начала процедуры/функции:

funcProc
: funScope? (FUNCTION | PROCEDURE) identName ('(' params? ')')? crlfStmnt
;

funScope
: STATIC
| INIT
| EXIT
;

Окончанием процедуры/функции может быть

RETURN ( expression )? crlfStmnt

но RETURN для процедур может и отсутствовать, тогда окончанием будет EOF или начало блока первого уровня.

В генераторе парсеров ANTLR для грамматики можно устанавливать опции.

Т.е. мы можем определить:

options { PreParse=ON; }

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

[PreParseLevel = 1]
funcProcSection
    : funcProcHead
      statements
    ;

Также некоторые конструкции такие как лямбды/анонимные функции могут быть тоже выделены для отдельного парсинга. Для них можно установить PreParseLevel = 0.

Целью синтаксического анализа является построение дерева синтаксического разбора(abstract syntax tree (AST)). В процессе парсинга мы будем получать для каждого блока свое дерево, которое потом можно прицепить к основному дереву.

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

Хотелось бы увидеть комментарии о данной концепции.

Разумно ли все это?
Применялось ли где?
Применяли ли вы в своей работе?
Стоит ли выносить это на обсуждение в англоязычном сообществе?

With best regards