Ваш словарный запас немного странный. Большинство синтаксических анализаторов предназначены для распознавания синтаксиса языка. обычно определение языка определяет некоторое понятие терминалов и явно исключает «пробелы», состоящие из неинтересных последовательностей текста между текстом терминалов, часто включая пробелы, вкладки и различные виды автономных комментариев. Таким образом, слово «терминал», используемое при разборе, обычно означает «те атомы языка, которые не являются пробелами». Вы определили это неявно, чтобы включить пробел, и я думаю, что это вызывает ваше горе.
С этой точки зрения, самый простой способ избежать загромождения определения грамматики, используемого вашим синтаксическим анализатором, с пробелами, - просто заставить лексер не передавать пробел в парсер. Тогда вашей грамматике не нужно указывать, как они обрабатываются (и да, грамматики, которые делают это, действительно грязные), парсеру не нужно беспокоиться о них, и они не отображаются в дереве.
Если вы создаете компилятор или интерпретатор, игнорировать пробелы проще всего.
Если вы создаете парсер реинжиниринга (см. Наш Инструментарий реинжиниринга программного обеспечения DMS ), то сбор комментариев (как минимум) в AST важен, так как в конечном итоге
один хочет регенерировать текст из связанных AST, и это полезно, если регенерированный текст также содержит комментарии. [Вы можете сделать это другими способами, но они не так просты.]
Лексер DMS создает «микро» токены, которые являются вашей внутренней концепцией для маркеров языка, пробелов и комментариев. Он отбрасывает пробельные микро-токены, потому что они просто ничего не добавляют (см. Обсуждение выше). Как и следовало ожидать, он передает обычные токены парсеру. Он приклеивает токены комментариев к предыдущему или следующему языковому токену, в зависимости от типа токена и места, где они встречаются; для C a / * ... * /, видимый до того, как к нему прикреплен токен, и комментарий // ... к предыдущему токену (с некоторыми более тонкими деталями, которые здесь не обсуждаются). Затем анализ все еще видит только языковые токены, поэтому грамматика не является излишне сложной, и если вся информация, прикрепленная к токену, помещается в дерево, комментарии отправляются в путь.
Теперь люди часто хотят «абстрактные» синтаксические деревья; они хотят пропустить такие вещи, как "(" и ")". Схема, которую я описал выше, прикрепляла комментарии даже к таким конкретным токенам, как эти. Теперь есть сложность: если вы оставите токены (..) вне дерева, прикрепленные комментарии исчезнут. К сожалению.
Таким образом, парсеры DMS делают сложную вещь: комментарии, прикрепленные к токенам, которые имеют логическое место в дереве, но на самом деле их там нет («исключенные терминалы»), переносятся в узел родительского дерева с аннотацией о том, что они принадлежат отсутствующему дочернему токену. Да, реализация этого действительно PITA.
Хорошей новостью является то, что нам нужно было сделать это только один раз в общем механизме синтаксического анализа DMS, и это работает для многих, многих языков. Но это означает, что вы должны быть готовы создать необычный («реинжиниринг») парсер, и у нас была коммерческая мотивация для этого.
РЕДАКТИРОВАТЬ: Не ясно, почему ОП хочет этого, но он настаивает на захвате пробелов в дереве. Поскольку он не сказал нам, почему, я собираюсь догадаться: он хочет получить точную информацию о столбцах для узлов токенов / деревьев. Это не сложно сделать: научить лексера отслеживать положение (строка / столбец) и пометить каждый токен (микротокены, например, комментарии) начальной / конечной позицией, и позволить анализу хранить эту информацию в дерево. Этот способ также позволяет избежать пробелов в дереве. (DMS делает это тоже, потому что при сообщении о проблемах точная информация полезна, а при регенерации кода часто желательно возвращать код в исходное положение (по крайней мере, в тот же столбец)).
РЕДАКТИРОВАТЬ2: Если ОП настаивает на захвате пробелов, он мог бы рассмотреть возможность анализа анализа без GLR без сканирования . Это сохраняет каждый символ во входном потоке, включая пробелы.