work line by line from source code

20 views
Skip to first unread message

Pavlov

unread,
May 25, 2018, 6:16:28 PM5/25/18
to antlr-discussion
Is it possible to find variables, operators, function calls from a certain single line in the source code ? From each line of source code I need to find what variable is modified,and what variable is accessed and what function call is made.Sorry if this question is too basic, I am novice on this topic.

Mike Lischke

unread,
May 26, 2018, 6:17:55 AM5/26/18
to antlr-di...@googlegroups.com
Is it possible to find variables, operators, function calls from a certain single line in the source code ? From each line of source code I need to find what variable is modified,and what variable is accessed and what function call is made.Sorry if this question is too basic, I am novice on this topic.

Yes, that easy to accomplish. The generated parse tree contains a node for every found symbol which comes with the character position in the input stream and line/column informations. Do a simple iteration over the tree to find a context or terminal at a given position, which you then can use the check for certain types you wanna handle (like variables etc.). That depends on your grammar. Here’s a C++ snippet for getting a tree from a specific character index in the input. It can easily be changed to use row/column pairs instead.

static bool treeContainsPosition(ParseTree *node, size_t position) {
  auto terminal = dynamic_cast<TerminalNode *>(node);
  if (terminal != nullptr) {
    return terminal->getSymbol()->getStartIndex() <= position && position <= terminal->getSymbol()->getStopIndex();
  }

  auto context = dynamic_cast<ParserRuleContext *>(node);
  if (context == nullptr)
    return false;

  return context->start->getStartIndex() <= position && position <= context->stop->getStopIndex();
}

//----------------------------------------------------------------------------------------------------------------------

/**
 * Returns the parse tree at the given character index position or nullptr if there's none.
 */
ParseTree* MySQLRecognizerCommon::contextFromPosition(ParseTree *root, size_t position) {
  if (!treeContainsPosition(root, position))
    return nullptr;

  for (auto child : root->children) {
    auto result = contextFromPosition(child, position);
    if (result != nullptr)
      return result;
  }

  // No child contains the given position, so it must be in whitespaces between them. Return the root for that case.
  return root;
}

Mike

Reply all
Reply to author
Forward
0 new messages