<commit_before>#include "parser.h"

#include <string>

#include "resyntax/resyntax.h"

namespace tinygrep {

resyntax::RegExp parse(std::string s) {
  // TODO: Implement the parsing function based on the pseudocode.

  //  init UNION-list
  //  init CONCAT-list
  //  while charstream is nonempty:
  //    c <- next char
  //    if c == ( :
  //      subexpr <- find subexpr
  //      CONCAT.append: recurse(subexpr)
  //    if c == . :
  //      CONCAT.append: DOT
  //    if c == literal :
  //      CONCAT.append: LITERAL(c)
  //    if c in {+,?,*} :
  //      CONCAT.top.modifywith(c)
  //    if c == | :
  //      cct <- CONCAT.CONCATENATEALL
  //      UNION.append: cct
  //      init CONCAT-list anew
  //    else
  //      throw a_fit
  //  cct <- CONCAT.CONCATENATEALL
  //  UNION.append: cct
  //  regexp <- UNION.UNITEALL
  //  return regexp

  // This is a temporary placeholder construction for verifying that testing is functional.
  resyntax::RegExp a = resyntax::createLiteral('a');
  resyntax::RegExp b = resyntax::createLiteral('b');
  resyntax::RegExp c = resyntax::createLiteral('c');
  resyntax::RegExp a_or_b = resyntax::createUnion(a, b);
  resyntax::RegExp a_or_b_star = resyntax::createClosure(a_or_b);
  resyntax::RegExp tree = resyntax::createConcatenation(a_or_b_star, c);
  return tree;
}

}  // namespace tinygrep
<commit_msg>Add function for finding matching a given parenthesis in a string.<commit_after>#include "parser.h"

#include <cstddef>
#include <stdexcept>
#include <string>

#include "resyntax/resyntax.h"

namespace tinygrep {

// Find end of parenthesis subexpr in string:
// returns index s.t. [start_index, index) includes both parenthesis.
std::size_t find_matching_parenthesis(const std::string& s, std::size_t start_index) {
  std::size_t index = start_index + 1;
  int unmatched_left_parens = 1;
  for (auto it = s.begin() + index; it < s.end() && unmatched_left_parens > 0; ++it, ++index) {
    if (*it == '(') {
      ++unmatched_left_parens;
    } else if (*it == ')') {
      --unmatched_left_parens;
    }
  }
  if (unmatched_left_parens != 0) {
    throw std::domain_error("String is not in the supported grammar: unmatched parenthesis.");
  }
  return index;
}

resyntax::RegExp parse(const std::string s) {
  // TODO: Validate s: check if it belongs to the grammar.
  // TODO: Implement the parsing function based on the pseudocode.

  //  init UNION-list
  //  init CONCAT-list
  //  while charstream is nonempty:
  //    c <- next char
  //    if c == ( :
  //      subexpr <- find subexpr
  //      CONCAT.append: recurse(subexpr)
  //    if c == . :
  //      CONCAT.append: DOT
  //    if c == literal :
  //      CONCAT.append: LITERAL(c)
  //    if c in {+,?,*} :
  //      CONCAT.top.modifywith(c)
  //    if c == | :
  //      cct <- CONCAT.CONCATENATEALL
  //      UNION.append: cct
  //      init CONCAT-list anew
  //    else
  //      throw a_fit
  //  cct <- CONCAT.CONCATENATEALL
  //  UNION.append: cct
  //  regexp <- UNION.UNITEALL
  //  return regexp

  // This is a temporary placeholder construction for verifying that testing is functional.
  resyntax::RegExp a = resyntax::createLiteral('a');
  resyntax::RegExp b = resyntax::createLiteral('b');
  resyntax::RegExp c = resyntax::createLiteral('c');
  resyntax::RegExp a_or_b = resyntax::createUnion(a, b);
  resyntax::RegExp a_or_b_star = resyntax::createClosure(a_or_b);
  resyntax::RegExp tree = resyntax::createConcatenation(a_or_b_star, c);
  return tree;
}

}  // namespace tinygrep

{'fraction_non_alphanumeric': 0.14127345082433201, 'fraction_numerical': 0.0011370096645821489, 'mean_word_length': 2.751599147121535, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5781682', 'n_tokens_mistral': 1315, 'n_tokens_neox': 1268, 'n_words': 300}