Comments 16
Обнимаю, коллега. SQL — отвратительный язык (у меня парсер DDL и выражений, это какой-то кошмар)
Прикладываю иногда кусочек воли к переходу на rider. Нравится еще больше, но перейти не могу. За что себя и ругаю.
Согласен — у PL/SQL очень большая грамматика, и лично у меня из-за этого очень медленно работает рефакторинг в Rider :) Но мы (Positive Technologies) работаем над уменьшением размера этой грамматики. Дело в том в PL/SQL очень много контекстных ключевых слов, таких, которые имеются смысл только в определенных правилах, а не везде. Но ANTLR пока что не поддерживает такое, поэтому приходится эмулировать их с помощью настоящих токенов и использовать следующий костыль:
AUTONOMOUS_TRANSACTION: 'AUTONOMOUS_TRANSACTION';
id
: ID
| ...
| AUTONOMOUS_TRANSACTION
... ;
Количество токенов влияет на размер генерируемого парсера, а сейчас их очень много. Даже issue на GitHub завели. Пока что не дошли руки закончить эту задачу, но размер сгенерированных файлов уже удалось уменьшить в несколько раз.
Меня дико впечетляло как ANTLR разруливал различные сложные граничные кейсы, которые реально встречались в наших грамматиках. Вырастить свой генератор парсеров для обработки их всех потребовало бы несравнимо больше усилий. Хотя, будь я проклят, думаю у меня бы аж глаза искрили вдохновением от такой задачи первые несколько недель!
А можете какой-нибудь сложный кейс описать с конкретными примерами?
Например когда одно правило равно начальной части другого, как в ANTLR метки для выражений. Название правила имеет вид [A-Za-z]+
, выражение с меткой имеет вид [A-Za-z]+ '=' '(' ... ')'
. После [A-Za-z]+
надо прочитать следующий символ, и если это =
, то продолжить разбор одного варианта, если нет, то вернуться на один символ обратно (или на исходную позицию, если начало не вынесено в отдельное правило), вернуть успешный результат разбора другого варианта, и начать парсинг следующего правила.
Дополняя SQL. Часть 1. Сложности парсинга. Истории о доработке ANTLR напильником