diff options
| author | vvvv <[email protected]> | 2024-11-03 01:25:03 +0300 |
|---|---|---|
| committer | vvvv <[email protected]> | 2024-11-03 01:34:36 +0300 |
| commit | 91ad4d5672563da0f1a92c648414adb27905dafe (patch) | |
| tree | 81bf246c784cd7a02075a8837d18bf73253ae6ae /yql/essentials/parser/lexer_common/parse_hints_impl.cpp | |
| parent | c2859fd279d6f460881911637b04622f7b76b1c2 (diff) | |
Moved yql/parser (w/o pg_wrapper) & yql/protos YQL-19206
init
commit_hash:71603ddfc208bf4ab1691d886ac35f22c107e3ee
Diffstat (limited to 'yql/essentials/parser/lexer_common/parse_hints_impl.cpp')
| -rw-r--r-- | yql/essentials/parser/lexer_common/parse_hints_impl.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/yql/essentials/parser/lexer_common/parse_hints_impl.cpp b/yql/essentials/parser/lexer_common/parse_hints_impl.cpp new file mode 100644 index 00000000000..10a0257e5df --- /dev/null +++ b/yql/essentials/parser/lexer_common/parse_hints_impl.cpp @@ -0,0 +1,105 @@ +#include "parse_hints_impl.h" + +#include <yql/essentials/utils/yql_panic.h> + +namespace NSQLTranslation { + +namespace NDetail { + +enum EParseState { + INITIAL, + NAME, + IN_PARENS, + IN_QUOTED_VALUE, + IN_VALUE, + WANT_WS, +}; + +TVector<TSQLHint> ParseSqlHints(NYql::TPosition commentPos, const TStringBuf& comment, bool utf8Aware) { + TVector<TSQLHint> result; + if (!comment.StartsWith("/*+") && !comment.StartsWith("--+")) { + return result; + } + TSQLHint hint; + NYql::TTextWalker commentWalker(commentPos, utf8Aware); + const size_t len = comment.size(); + EParseState state = EParseState::INITIAL; + for (size_t i = 0; i < len; ++i) { + auto c = comment[i]; + switch (state) { + case EParseState::INITIAL: { + if (std::isalpha(c)) { + hint.Pos = commentPos; + hint.Name.push_back(c); + state = EParseState::NAME; + } + break; + } + case EParseState::NAME: { + if (std::isalnum(c)) { + hint.Name.push_back(c); + } else if (c == '(') { + state = EParseState::IN_PARENS; + } else { + hint = {}; + state = std::isspace(c) ? EParseState::INITIAL : EParseState::WANT_WS; + } + break; + } + case EParseState::IN_PARENS: { + if (c == ')') { + result.emplace_back(); + std::swap(hint, result.back()); + state = EParseState::WANT_WS; + } else if (c == '\'') { + hint.Values.emplace_back(); + state = EParseState::IN_QUOTED_VALUE; + } else if (!std::isspace(c)) { + hint.Values.emplace_back(); + hint.Values.back().push_back(c); + state = EParseState::IN_VALUE; + } + break; + } + case EParseState::IN_QUOTED_VALUE: { + YQL_ENSURE(!hint.Values.empty()); + if (c == '\'') { + if (i + 1 < len && comment[i + 1] == '\'') { + ++i; + commentWalker.Advance(c); + hint.Values.back().push_back(c); + } else { + state = EParseState::IN_PARENS; + } + } else { + hint.Values.back().push_back(c); + } + break; + } + case EParseState::IN_VALUE: { + if (std::isspace(c)) { + state = EParseState::IN_PARENS; + } else if (c == ')') { + result.emplace_back(); + std::swap(hint, result.back()); + state = EParseState::WANT_WS; + } else { + hint.Values.back().push_back(c); + } + break; + } + case EParseState::WANT_WS: { + if (std::isspace(c)) { + state = EParseState::INITIAL; + } + break; + } + } + commentWalker.Advance(c); + } + return result; +} + +} + +} |
