All Downloads are FREE. Search and download functionalities are using the official Maven repository.

syntax.bsl-parser.0.25.0.source-code.SDBLParser.g4 Maven / Gradle / Ivy

The newest version!
/**
 * This file is a part of BSL Parser.
 *
 * Copyright © 2018-2022
 * Alexey Sosnoviy , Nikita Fedkin , Sergey Batanov 
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 *
 * BSL Parser is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * BSL Parser is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with BSL Parser.
 */
/**
 * @author Maximov Valery 
 */
parser grammar SDBLParser;

options {
    tokenVocab = SDBLLexer;
    contextSuperClass = 'BSLParserRuleContext';
}

// ROOT
// основная структура пакета запросов:
// Пакет состоит из запросов (мин 1) разделенных ; и в конце тоже допустима ;
queryPackage: queries (SEMICOLON queries)* SEMICOLON? EOF;

// QUERY
// описание элемента пакета
// Запрос может состоять из выборки (с или без сохранения во временную) либо удаления временной таблицы
queries: selectQuery | dropTableQuery;

// DROP TABLE
// удаление временной таблицы, где temporaryTableName идентификатор временной таблицы
dropTableQuery: DROP temporaryTableName=identifier;

// SELECT
// запрос на выборку данных
// Состоит из запроса на выборку (пакета) итогового упорядочивания и итогов
selectQuery:
    subquery
    (
          (autoorder=AUTOORDER orders=orderBy totals=totalBy)
        | (orders=orderBy autoorder=AUTOORDER totals=totalBy)
        | (orders=orderBy totals=totalBy autoorder=AUTOORDER)
        | (autoorder=AUTOORDER (orders=orderBy | totals=totalBy)?)
        | (orders=orderBy (autoorder=AUTOORDER | totals=totalBy)?)
        | (totals=totalBy autoorder=AUTOORDER?)
    )?
    ;

// SUBQUERIES
// Основная часть запроса
// Состоит из основного запроса и объединения.
// Основной запрос может быть простым запросом для выборки данных И НЕ МОЖЕТ быть выбокой во временную таблицу
subquery: main=query orderBy? (unions+=union+)?;

// объединение запросов
union: UNION ALL? query orderBy?;

// структура запроса
query:
    SELECT limitations?
    columns=selectedFields
    (INTO temporaryTableName=identifier)?
    (FROM from=dataSources)?
    (WHERE where=logicalExpression)?
    (GROUP (BY_EN | PO_RU) groupBy=groupByItem)?
    (HAVING having=logicalExpression)?
    (FOR UPDATE forUpdate=mdo?)?
    (INDEX (BY_EN | PO_RU) indexes+=indexingItem (COMMA indexes+=indexingItem)*)?
    ;

// различные ограничения выборки, для ускорения анализа развернуты все варианты
limitations:
     ((top | DISTINCT | ALLOWED))
    | (ALLOWED DISTINCT top)
    | (ALLOWED top DISTINCT)
    | (top ALLOWED DISTINCT)
    | (top DISTINCT ALLOWED)
    | (DISTINCT ALLOWED top)
    | (DISTINCT top ALLOWED)
    | (ALLOWED DISTINCT)
    | (ALLOWED top)
    | (DISTINCT ALLOWED)
    | (DISTINCT top)
    | (top ALLOWED)
    | (top DISTINCT)
    ;

// Ограничение количества элементов выборки
top: TOP count=DECIMAL;

// поля выборки
selectedFields: fields+=selectedField (COMMA fields+=selectedField)*;
selectedField:
    (
          asteriskField
        | columnField
        | emptyTableField
        | inlineTableField
        | expressionField
    )
    alias?
    ;

// поле выборки-звездочка, либо имя таблицы.* либо просто *. Алиаса не бывает
asteriskField: (tableName=identifier DOT)* MUL;

// поле выборки-выражение, алиас может быть
expressionField: logicalExpression;

// поле выборки-поле табицы или NULL
columnField: NULL | recordAutoNumberFunction;

// поле выборки-пустая таблица
emptyTableField: emptyTable=EMPTYTABLE DOT LPAREN emptyTableColumns RPAREN;
emptyTableColumns: columns+=alias (COMMA columns+=alias)*;

// поле выборки-табличная часть
inlineTableField: inlineTable=column DOT LPAREN inlineTableFields=selectedFields RPAREN;

// функция автономерзаписи может быть использована только как поле выборки
recordAutoNumberFunction: doCall=RECORDAUTONUMBER LPAREN RPAREN;

groupByItem:
    GROUPING SET LPAREN (LPAREN groupingSet+=expressionList RPAREN (COMMA LPAREN groupingSet+=expressionList RPAREN)*) RPAREN
    | (groupBy+=expression (COMMA groupBy+=expression)*)
    ;

// поле индексирования, может быть колонкой или параметром
indexingItem: parameter | column;

// упорядочивание
orderBy: ORDER (BY_EN | PO_RU) orders+=ordersByExpession (COMMA orders+=ordersByExpession)?;
ordersByExpession: expression (direction=(ASC | DESC) | (hierarchy=HIERARCHY direction=DESC?))?;

// итоги
totalBy: TOTALS selectedFields? (BY_EN | PO_RU) totalsGroups+=totalsGroup (COMMA totalsGroups+=totalsGroup)*;
totalsGroup:
      OVERALL
    | (expression ((ONLY? HIERARCHY) | periodic)? alias?)
    ;
// периодичность группы итогов
periodic: PERIODS
    LPAREN
        periodType=(SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR | TENDAYS | HALFYEAR)
        (COMMA first=expression)? (COMMA second=expression)?
    RPAREN
    ;

// поля-колонки
column:
      mdoName=identifier (DOT columnNames+=identifier)+
    | columnNames+=identifier
    | mdo (DOT columnNames+=identifier)+
    ;

// EXPRESSION
// Выражения
expression:
      primitiveExpression
    | functionCall
    | caseExpression
    | column
    | bracketExpression
    | unaryExpression
    | expression binaryOperation=(MUL | QUOTIENT | PLUS | MINUS) expression
    ;

// Примитивные выражения
primitiveExpression:
      NULL
    | UNDEFINED
    | multiString
    | DECIMAL
    | FLOAT
    | booleanValue=(TRUE | FALSE)
    | (DATETIME LPAREN
            year=datePart COMMA month=datePart COMMA day=datePart
            /* эта часть может быть опущена */ (COMMA
            hour=datePart COMMA minute=datePart COMMA second=datePart)?
       RPAREN)
    | parameter
    | (TYPE LPAREN (mdo | STRING | BOOLEAN | DATE | NUMBER) RPAREN)
    ;

// условные выражения (если...то...иначе)
caseExpression:
      (CASE caseExp=expression caseBranch+ (ELSE elseExp=logicalExpression)? END)
    | (CASE caseBranch+ (ELSE elseExp=logicalExpression)? END)
    | (caseBranch (ELSE elseExp=logicalExpression)? END)
    ;

// ветка со своим условием и результатом
caseBranch: WHEN logicalExpression THEN logicalExpression;

// выражение в скобках
// в скобках может быть либо подзапрос либо другое выражение
bracketExpression: (LPAREN expression RPAREN) | (LPAREN subquery RPAREN);

// выражение с унарной операцией
unaryExpression: sign expression;

// вызов встроенных ф-ий
functionCall:
      aggregateFunctions
    | builtInFunctions
    | (valueFunction (DOT columnNames+=identifier)*)
    | (castFunction (DOT columnNames+=identifier)*)
;

// встроенные функции
builtInFunctions:
      (doCall=SUBSTRING LPAREN string=expression COMMA charNo=expression COMMA count=expression RPAREN)
    | (doCall=(YEAR | QUARTER | MONTH | DAYOFYEAR | DAY | WEEK | WEEKDAY | HOUR | MINUTE | SECOND) LPAREN date=expression RPAREN)
    | (doCall=(BEGINOFPERIOD | ENDOFPERIOD) LPAREN date=expression COMMA periodType=(MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR | TENDAYS | HALFYEAR) RPAREN)
    | (doCall=DATEADD LPAREN date=expression COMMA periodType=(SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR | TENDAYS | HALFYEAR) COMMA count=expression RPAREN)
    | (doCall=DATEDIFF LPAREN firstdate=expression COMMA seconddate=expression COMMA periodType=(SECOND | MINUTE | HOUR | DAY | MONTH | QUARTER | YEAR) RPAREN)
    | (doCall=(VALUETYPE | PRESENTATION | REFPRESENTATION | GROUPEDBY) LPAREN value=expression RPAREN)
    | (doCall=ISNULL LPAREN first=logicalExpression COMMA second=logicalExpression RPAREN)
    | (doCall=(ACOS | ASIN | ATAN | COS | SIN | TAN | LOG | LOG10 | EXP | POW | SQRT | INT) LPAREN decimal=expression RPAREN)
    | (doCall=(LOWER | STRINGLENGTH | TRIMALL | TRIML | TRIMR | UPPER) LPAREN string=expression RPAREN)
    | (doCall=ROUND LPAREN decimal=expression COMMA precise=expression RPAREN)
    | (doCall=(STOREDDATASIZE | UUID) LPAREN value=expression RPAREN)
    | (doCall=STRFIND LPAREN string=expression COMMA substring1=expression RPAREN)
    | (doCall=STRREPLACE LPAREN string=expression COMMA substring1=expression COMMA substring1=expression RPAREN)
;

// агрегатные ф-ии
aggregateFunctions:
      (doCall=(SUM | AVG | MIN | MAX) LPAREN logicalExpression RPAREN)
    | (doCall=COUNT LPAREN (DISTINCT? logicalExpression | MUL) RPAREN)
;

// функция Значение
valueFunction: doCall=VALUE LPAREN
    (
          (type=(BUSINESS_PROCESS_TYPE
                           | CATALOG_TYPE
                           | DOCUMENT_TYPE
                           | FILTER_CRITERION_TYPE
                           | EXCHANGE_PLAN_TYPE
                           | ENUM_TYPE
                           | CHART_OF_CHARACTERISTIC_TYPES_TYPE
                           | CHART_OF_ACCOUNTS_TYPE
                           | CHART_OF_CALCULATION_TYPES_TYPE
                           | TASK_TYPE
                           | EXTERNAL_DATA_SOURCE_TYPE)
                       DOT mdoName=identifier DOT emptyFer=EMPTYREF)
        | (type=(CATALOG_TYPE
                            | ENUM_TYPE
                            | CHART_OF_CHARACTERISTIC_TYPES_TYPE
                            | CHART_OF_ACCOUNTS_TYPE
                            | CHART_OF_CALCULATION_TYPES_TYPE)
                       DOT mdoName=identifier DOT predefinedName=identifier)
                                                                                // для точки маршрута бизнес процесса
        | (type=BUSINESS_PROCESS_TYPE DOT mdoName=identifier DOT ROUTEPOINT_FIELD DOT routePointName=identifier)
        | (systemName=identifier DOT predefinedName=identifier)                 // для системного перечисления
        | (mdo DOT)                                                             // может быть просто точка - аналог пустой ссылки
    ) RPAREN
    ;

castFunction:
    (doCall=CAST LPAREN value=expression AS (
              type=BOOLEAN
            | (type=NUMBER (LPAREN len=DECIMAL (COMMA prec=DECIMAL)? RPAREN)?)
            | (type=STRING (LPAREN len=DECIMAL RPAREN)?)
            | type=DATE
            | mdo
      ) RPAREN)
   ;

// выражения-условия отбора
logicalExpression:
      condidions+=predicate
      ((AND | OR) condidions+=predicate)*
    ;

predicate: NOT* (
      booleanPredicate=expression // булево
    | likePredicate
    | isNullPredicate
    | comparePredicate
    | betweenPredicate
    | inPredicate
    | refsPredicate
    | (LPAREN logicalExpression RPAREN)
    );

likePredicate: expression NOT* LIKE expression (ESCAPE escape=multiString)?;    // выражение подобно выражение [ESC-последовательность]
isNullPredicate: expression IS NOT? NULL;                                       // выражение ЕСТЬ NULL / ЕСТЬ НЕ NULL
// сравнение выражений
comparePredicate: expression compareOperation=(LESS | LESS_OR_EQUAL | GREATER | GREATER_OR_EQUAL | ASSIGN | NOT_EQUAL) expression;
betweenPredicate: expression BETWEEN expression AND expression;                                 // выражение МЕЖДУ выражение1 И выражение2
inPredicate: (expression | (LPAREN expressionList RPAREN)) NOT* IN HIERARCHY_FOR_IN? LPAREN (subquery | expressionList) RPAREN;     // выражение В (подзапрос/список)
refsPredicate: expression REFS mdo;                                             // выражение ССЫЛКА МДО

// список выражений
expressionList: exp+=logicalExpression (COMMA exp+=logicalExpression)*;

// перечень таблиц-источников данных для выборки
dataSources: tables+=dataSource (COMMA tables+=dataSource)*;

// варианты источников данных
dataSource:
      (LPAREN dataSource RPAREN)
    | ((
          ((virtualTable | table | parameterTable | externalDataSourceTable) alias?)
        | (LPAREN (virtualTable | table | parameterTable | subquery) RPAREN alias?)
      ) joins+=joinPart*)
    ;

// источник-физическая таблица либо ВТ
table:
      mdo
    | mdo DOT objectTableName=identifier
    | tableName=identifier
    ;

// источник-виртуальная таблица
virtualTable:
     (mdo DOT virtualTableName=(
              SLICELAST_VT
            | SLICEFIRST_VT
            | BOUNDARIES_VT
            | TURNOVERS_VT
            | BALANCE_VT
            | BALANCE_AND_TURNOVERS_VT
            | EXT_DIMENSIONS_VT
            | RECORDS_WITH_EXT_DIMENSIONS_VT
            | DR_CR_TURNOVERS_VT
            | ACTUAL_ACTION_PERIOD_VT
            | SCHEDULE_DATA_VT
            | TASK_BY_PERFORMER_VT
        ) (LPAREN virtualTableParameters+=virtualTableParameter (COMMA virtualTableParameters+=virtualTableParameter)* RPAREN)?)
    | (type=FILTER_CRITERION_TYPE DOT tableName=identifier LPAREN parameter? RPAREN) // для критерия отбора имя ВТ не указывается
    ;

// параметр виртуальной таблицы может быть опущен
virtualTableParameter: logicalExpression?;

// таблица как параметр, соединяться ни с чем не может
parameterTable: parameter;

externalDataSourceTable:
      mdo DOT EDS_TABLE DOT tableName=identifier
    | mdo DOT EDS_CUBE DOT cubeName=identifier DOT EDS_CUBE_DIMTABLE DOT tableName=identifier;

// соединения таблиц
joinPart:
    (   // тип соединения
          (joinType=RIGHT outerJoin=OUTER? JOIN)
        | (joinType=LEFT outerJoin=OUTER? JOIN)
        | (joinType=FULL outerJoin=OUTER? JOIN)
        | (joinType=INNER JOIN)
        | (joinType=JOIN)
    )
    source=dataSource (ON_EN | PO_RU) condition=logicalExpression          // имя таблицы и соединение
    ;

// алиас для поля, таблицы ...
alias: AS? name=identifier;

// состав даты
datePart: (parameter | DECIMAL) ;

// Строки
multiString: STR+;

// Унарные минус и плюс
sign: MINUS | PLUS;

// возможные идентификаторы
identifier:
      IDENTIFIER // просто идентификатор объекта
    // виртуальные таблицы
    | ACTUAL_ACTION_PERIOD_VT
    | BALANCE_VT
    | BALANCE_AND_TURNOVERS_VT
    | BOUNDARIES_VT
    | DR_CR_TURNOVERS_VT
    | EXT_DIMENSIONS_VT
    | RECORDS_WITH_EXT_DIMENSIONS_VT
    | SCHEDULE_DATA_VT
    | SLICEFIRST_VT
    | SLICELAST_VT
    | TASK_BY_PERFORMER_VT
    | TURNOVERS_VT
    // системные поля
    | ROUTEPOINT_FIELD
    // типы метаданных
    | BUSINESS_PROCESS_TYPE
    | CATALOG_TYPE
    | DOCUMENT_TYPE
    | INFORMATION_REGISTER_TYPE
    | CONSTANT_TYPE
    | FILTER_CRITERION_TYPE
    | EXCHANGE_PLAN_TYPE
    | SEQUENCE_TYPE
    | DOCUMENT_JOURNAL_TYPE
    | ENUM_TYPE
    | CHART_OF_CHARACTERISTIC_TYPES_TYPE
    | CHART_OF_ACCOUNTS_TYPE
    | CHART_OF_CALCULATION_TYPES_TYPE
    | ACCUMULATION_REGISTER_TYPE
    | ACCOUNTING_REGISTER_TYPE
    | CALCULATION_REGISTER_TYPE
    | TASK_TYPE
    | EXTERNAL_DATA_SOURCE_TYPE
    // ключевые слова
    | DROP
    | END
    | ISNULL
    | JOIN
    | SELECT
    | TOTALS
    | UNION
    | UPDATE
    | AVG
    | BEGINOFPERIOD
    | BOOLEAN
    | COUNT
    | DATE
    | DATEADD
    | DATEDIFF
    | DATETIME
    | DAY
    | DAYOFYEAR
    | EMPTYTABLE
    | EMPTYREF
    | ENDOFPERIOD
    | HALFYEAR
    | HOUR
    | MAX
    | MIN
    | MINUTE
    | MONTH
    | NUMBER
    | QUARTER
    | ONLY
    | PERIODS
    | REFS
    | PRESENTATION
    | RECORDAUTONUMBER
    | REFPRESENTATION
    | SECOND
    | STRING
    | SUBSTRING
    | SUM
    | TENDAYS
    | TYPE
    | VALUE
    | VALUETYPE
    | WEEK
    | WEEKDAY
    | YEAR
    | ORDER
    | GROUP
    | INDEX
    | SET
    | RIGHT
    | LEFT
    | INNER
    | FULL
    | JOIN
    | OUTER
    | FOR
    | UPDATE
    | ALL
    | UNION
    | ACOS
    | ASIN
    | ATAN
    | COS
    | SIN
    | TAN
    | LOG
    | LOG10
    | EXP
    | POW
    | SQRT
    | INT
    | LOWER
    | STRINGLENGTH
    | TRIMALL
    | TRIML
    | TRIMR
    | UPPER
    | ROUND
    | STOREDDATASIZE
    | UUID
    | STRFIND
    | STRREPLACE
;

// параметр запроса
parameter: AMPERSAND name=PARAMETER_IDENTIFIER;

// полное имя объекта метаданных, где tableName - имя прикладного объекта
mdo: type=(
          BUSINESS_PROCESS_TYPE
        | CATALOG_TYPE
        | DOCUMENT_TYPE
        | INFORMATION_REGISTER_TYPE
        | CONSTANT_TYPE
        | FILTER_CRITERION_TYPE
        | EXCHANGE_PLAN_TYPE
        | SEQUENCE_TYPE
        | DOCUMENT_JOURNAL_TYPE
        | ENUM_TYPE
        | CHART_OF_CHARACTERISTIC_TYPES_TYPE
        | CHART_OF_ACCOUNTS_TYPE
        | CHART_OF_CALCULATION_TYPES_TYPE
        | ACCUMULATION_REGISTER_TYPE
        | ACCOUNTING_REGISTER_TYPE
        | CALCULATION_REGISTER_TYPE
        | TASK_TYPE
        | EXTERNAL_DATA_SOURCE_TYPE
     ) DOT tableName=identifier
;




© 2015 - 2024 Weber Informatics LLC | Privacy Policy