#include "grammar.h" #include #include #include #include namespace NSQLComplete { class TSqlGrammar: public ISqlGrammar { public: explicit TSqlGrammar(const NSQLReflect::TLexerGrammar& grammar) : Parser_(MakeDummyParser()) , AllTokens_(ComputeAllTokens()) , KeywordTokens_(ComputeKeywordTokens(grammar)) , PunctuationTokens_(ComputePunctuationTokens(grammar)) , IdPlainRegex_(ComputeIdPlainRegex(grammar)) { } const antlr4::dfa::Vocabulary& GetVocabulary() const override { return Parser_->getVocabulary(); } const std::unordered_set& GetAllTokens() const override { return AllTokens_; } const std::unordered_set& GetKeywordTokens() const override { return KeywordTokens_; } const std::unordered_set& GetPunctuationTokens() const override { return PunctuationTokens_; } const std::string& SymbolizedRule(TRuleId rule) const override { return Parser_->getRuleNames().at(rule); } TTokenId GetTokenId(std::string_view symbolized) const override { TTokenId type = Parser_->getTokenType(symbolized); Y_ENSURE(type != antlr4::Token::INVALID_TYPE, "Not found " << symbolized); return type; } TRuleId GetRuleId(std::string_view symbolized) const override { TRuleId index = Parser_->getRuleIndex(std::string(symbolized)); if (index == INVALID_INDEX) { ythrow yexception() << "Rule \"" << symbolized << "\" not found"; } return index; } const std::vector& GetAllRules() const override { return Parser_->getRuleNames(); } bool IsPlainIdentifier(TStringBuf content) const override { return RE2::FullMatch(content, IdPlainRegex_); } private: static THolder MakeDummyParser() { return MakeHolder(nullptr); } std::unordered_set ComputeAllTokens() { const auto& vocabulary = GetVocabulary(); std::unordered_set allTokens; for (size_t type = 1; type <= vocabulary.getMaxTokenType(); ++type) { allTokens.emplace(type); } return allTokens; } std::unordered_set ComputeKeywordTokens( const NSQLReflect::TLexerGrammar& grammar) { const auto& vocabulary = GetVocabulary(); auto keywordTokens = GetAllTokens(); std::erase_if(keywordTokens, [&](TTokenId token) { return !grammar.KeywordNames.contains(vocabulary.getSymbolicName(token)); }); keywordTokens.erase(TOKEN_EOF); return keywordTokens; } std::unordered_set ComputePunctuationTokens( const NSQLReflect::TLexerGrammar& grammar) { const auto& vocabulary = GetVocabulary(); auto punctuationTokens = GetAllTokens(); std::erase_if(punctuationTokens, [&](TTokenId token) { return !grammar.PunctuationNames.contains(vocabulary.getSymbolicName(token)); }); return punctuationTokens; } static TString ComputeIdPlainRegex(const NSQLReflect::TLexerGrammar& grammar) { TVector> regexes = NSQLTranslationV1::MakeRegexByOtherName(grammar, /* ansi = */ false); std::tuple* regex = FindIfPtr(regexes, [&](const auto& x) { return std::get<0>(x) == "ID_PLAIN"; }); Y_ENSURE(regex, "ID_PLAIN regex not found"); return std::get<1>(*regex); } const THolder Parser_; const std::unordered_set AllTokens_; const std::unordered_set KeywordTokens_; const std::unordered_set PunctuationTokens_; const RE2 IdPlainRegex_; }; const ISqlGrammar& GetSqlGrammar() { const static TSqlGrammar DefaultSqlGrammar(NSQLReflect::LoadLexerGrammar()); return DefaultSqlGrammar; } } // namespace NSQLComplete