| /* |
| Copyright 2019 Alain Dargelas |
| |
| Licensed 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. |
| */ |
| |
| /* |
| * File: ParseUtils.cpp |
| * Author: alain |
| * |
| * Created on March 16, 2017, 10:23 PM |
| */ |
| |
| #include "antlr4-runtime.h" |
| using namespace antlr4; |
| #include <vector> |
| #include "Utils/ParseUtils.h" |
| |
| using namespace SURELOG; |
| |
| ParseUtils::ParseUtils() {} |
| |
| ParseUtils::ParseUtils(const ParseUtils& orig) {} |
| |
| ParseUtils::~ParseUtils() {} |
| |
| std::pair<int, int> ParseUtils::getLineColumn(tree::TerminalNode* node) { |
| Token* token = node->getSymbol(); |
| int lineNb = token->getLine(); |
| int columnNb = token->getCharPositionInLine(); |
| return std::make_pair(lineNb, columnNb); |
| } |
| |
| std::pair<int, int> ParseUtils::getLineColumn(CommonTokenStream* stream, |
| ParserRuleContext* context) { |
| const misc::Interval sourceInterval = |
| ((ParserRuleContext*)context)->getSourceInterval(); |
| Token* firstToken = stream->get(sourceInterval.a); |
| int lineNb = firstToken->getLine(); |
| int columnNb = firstToken->getCharPositionInLine(); |
| return std::make_pair(lineNb, columnNb); |
| } |
| |
| std::vector<tree::ParseTree*> ParseUtils::getTopTokenList( |
| tree::ParseTree* tree) { |
| std::vector<tree::ParseTree*> tokens; |
| for (unsigned int i = 0; i < tree->children.size(); i++) { |
| // Get the i-th child node of `parent`. |
| tree::ParseTree* child = tree->children[i]; |
| tokens.push_back(child); |
| } |
| return tokens; |
| } |
| |
| void ParseUtils::tokenizeAtComma(std::vector<std::string>& actualArgs, |
| const std::vector<tree::ParseTree*>& tokens) { |
| bool notEmpty = false; |
| std::vector<std::string> tmpArgs; |
| unsigned int topIndex = 0; |
| for (std::vector<tree::ParseTree*>::const_iterator itr = tokens.begin(); |
| itr != tokens.end(); itr++) { |
| std::string s = (*itr)->getText(); |
| if (s == ",") { |
| tmpArgs.push_back(","); |
| topIndex++; |
| } else if (s == " ") { |
| if (topIndex > 0) { |
| if (tmpArgs[topIndex - 1] != ",") tmpArgs[topIndex - 1] += " "; |
| } |
| } else { |
| if ((topIndex == 0) || (tmpArgs[topIndex - 1] == ",")) { |
| tmpArgs.push_back(s); |
| topIndex++; |
| } else |
| tmpArgs[topIndex - 1] += s; |
| } |
| } |
| |
| for (unsigned int j = 0; j < tmpArgs.size(); j++) { |
| std::string s = tmpArgs[j]; |
| if (s != ",") { |
| for (unsigned int i = 0; i < s.size(); i++) { |
| if (s[i] != ' ') { |
| notEmpty = true; |
| break; |
| } |
| } |
| } |
| bool lastToken = (j == (tmpArgs.size() - 1)); |
| if ((s != ",") && notEmpty) { |
| actualArgs.push_back(s); |
| } else if ((s == ",") && (!notEmpty)) { |
| actualArgs.push_back(""); |
| notEmpty = false; |
| if (lastToken) actualArgs.push_back(""); |
| } else if (lastToken) { |
| actualArgs.push_back(""); |
| } else if (s == ",") { |
| notEmpty = false; |
| } |
| } |
| } |
| |
| /** |
| * Retrieves all Tokens from the {@code tree} in an in-order sequence. |
| * |
| * @param tree |
| * the parse tee to get all tokens from. |
| * |
| * @return all Tokens from the {@code tree} in an in-order sequence. |
| */ |
| |
| std::vector<Token*> ParseUtils::getFlatTokenList(tree::ParseTree* tree) { |
| std::vector<Token*> tokens; |
| inOrderTraversal(tokens, tree); |
| return tokens; |
| } |
| |
| /** |
| * Makes an in-order traversal over {@code parent} (recursively) collecting |
| * all Tokens of the terminal nodes it encounters. |
| * |
| * @param tokens |
| * the list of tokens. |
| * @param parent |
| * the current parent node to inspect for terminal nodes. |
| */ |
| |
| void ParseUtils::inOrderTraversal(std::vector<Token*>& tokens, |
| tree::ParseTree* parent) { |
| // Iterate over all child nodes of `parent`. |
| for (unsigned int i = 0; i < parent->children.size(); i++) { |
| // Get the i-th child node of `parent`. |
| tree::ParseTree* child = parent->children[i]; |
| tree::TerminalNode* node = dynamic_cast<tree::TerminalNode*>(child); |
| if (node) { |
| // We found a leaf/terminal, add its Token to our list. |
| tokens.push_back(node->getSymbol()); |
| } else { |
| // No leaf/terminal node, recursively call this method. |
| inOrderTraversal(tokens, child); |
| } |
| } |
| } |