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