проблема с чувствительностью к регистру antlr4 TSqlParser.g4 / TSqlLexer.g4

#sql-server #tsql #antlr4

#sql-сервер #tsql #antlr4

Вопрос:

Я использую эти грамматики / лексеры TSql для анализа хранимых процедур в целевом объекте c #.

Я обнаружил, что следующий метод имеет проблемы.

 public override void EnterProcedure_param(Procedure_paramContext context)
{
    string txt = context.GetText();

    string datatype = context.data_type().GetText();

    if (IsUserDefinedType(datatype)) // not shown
        DoSomething(datatype);
}
  

Он будет правильно извлекать тип данных (и txt) при определении хранимой процедуры :

 CREATE PROCEDURE [dbo].[PROC_SomeProc]
    @APPINSTID BIGINT
AS ...
  

но НЕ

 CREATE PROCEDURE [dbo].[PROC_SomeProc]
    @AppInstId BIGINT
AS ...
  

В последнем случае txt — это ‘@AI’, а тип данных — ‘I’.

Кроме того, если параметр определен @appinstid , метод никогда не посещается.

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

Комментарии:

1. Я предлагаю вам открыть проблему в проекте github . У меня был хороший успех при разборе T-SQL с Microsoft.SQLServer. Transactsql.ScriptDom на C # и PowerShell, доступный в пакете DacFx NuGet .

2. В примечании на главной странице четко указано: «Поскольку грамматика SQL обычно не чувствительна к регистру, но эта реализация грамматики …»

3. @SMor — так и есть. Я пропустил это при обновлении с более ранней грамматики non_cs.

Ответ №1:

Используйте CaseChangingCharStream вместо стандартного потока токенов. Смотрите подробности здесь:https://github.com/antlr/antlr4/blob/master/doc/case-insensitive-lexing.md

Комментарии:

1. В реализации C # CaseChangingCharStream обнаружена ошибка — строки 71 и 73 ‘LA’ должны быть ‘La’. Спасибо за вашу помощь.

2. Это не ошибка — это зависит от времени выполнения C #: стандартное или оптимизированное.