blob: 6c7968410b0c6ba8f50b38b124886d81041d1ead [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* License); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "path_visitor.h"
namespace storage {
antlrcpp::Any PathVisitor::visitPath(PathParser::PathContext* ctx) {
if (ctx->prefixPath() != nullptr) {
return visitPrefixPath(ctx->prefixPath());
} else {
return visitSuffixPath(ctx->suffixPath());
}
}
antlrcpp::Any PathVisitor::visitPrefixPath(PathParser::PrefixPathContext* ctx) {
std::vector<PathParser::NodeNameContext*> node_names = ctx->nodeName();
std::vector<std::string> path;
path.reserve(node_names.size() + 1);
path.push_back(ctx->ROOT()->getText());
for (uint64_t i = 0; i < node_names.size(); i++) {
path.push_back(parse_node_name(node_names[i]));
}
return path;
}
antlrcpp::Any PathVisitor::visitSuffixPath(PathParser::SuffixPathContext* ctx) {
std::vector<PathParser::NodeNameContext*> node_names = ctx->nodeName();
std::vector<std::string> path;
path.reserve(node_names.size());
for (uint64_t i = 0; i < node_names.size(); i++) {
path.emplace_back(parse_node_name(node_names[i]));
}
return path;
}
std::string PathVisitor::parse_node_name(PathParser::NodeNameContext* ctx) {
std::string node_name = ctx->getText();
if (starts_with(node_name, BACK_QUOTE_STRING) &&
ends_with(node_name, BACK_QUOTE_STRING)) {
std::string unWrapped = node_name.substr(1, node_name.length() - 2);
if (is_real_number(unWrapped) ||
!std::regex_match(unWrapped, IDENTIFIER_PATTERN)) {
return node_name;
}
return unWrapped;
}
return node_name;
}
bool PathVisitor::is_real_number(const std::string& str) {
std::string s = str;
if (starts_with(s, "+") || starts_with(s, "-")) {
std::string removeSign = s.substr(1);
if (starts_with(removeSign, "+") || starts_with(removeSign, "-")) {
return false;
} else {
s = removeSign;
}
}
size_t index = 0;
auto it = std::find_if(s.begin(), s.end(),
[](const char& c) { return c != '0'; });
if (it != s.end()) {
index = it - s.begin();
}
if (index > 0 && (s[index] == 'e' || s[index] == 'E')) {
return is_creatable(s.substr(index - 1));
} else {
return is_creatable(s.substr(index));
}
}
bool PathVisitor::starts_with(const std::string& str,
const std::string& prefix) {
if (prefix.size() > str.size()) {
return false;
}
return str.substr(0, prefix.size()) == prefix;
}
bool PathVisitor::ends_with(const std::string& str, const std::string& suffix) {
if (suffix.size() > str.size()) {
return false;
}
return str.substr(str.size() - suffix.size()) == suffix;
}
bool PathVisitor::is_creatable(const std::string& str) {
try {
std::stod(str);
return true;
} catch (const std::invalid_argument& e) {
return false;
} catch (const std::out_of_range& e) {
return false;
}
}
} // namespace storage