| /* | |
| 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 "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); | |
| } | |
| } | |
| } | |