Exemple #1
0
void Checker::process_tokens()
{
    int line_index = -1;
    for(token = tokens.begin(); token != tokens.end(); ++token)
    {
        if(token->type == TT_WHITESPACE)
        {
            whitespace_sequence_check();
            continue;
        }

        if(token->line_index != line_index)
        {
            nesting_depth_check();
            line_index = token->line_index;
            env.line_closed = false;
        }

        if(env.line_closed && token->type != TT_COMMENT && !is_blockbracket())
        {
            add_result("two or more expressions at one line");
            env.line_closed = false;
        }

        switch(token->type)
        {
            case TT_CBRACKET_OPEN:
            case TT_CBRACKET_CLOSE:
            case TT_BRACE:
            case TT_BRACKET:
                unibracket_check();
        }

        switch(token->type)
        {
            case TT_CBRACKET_OPEN:
            case TT_PASBRACKET_OPEN:
            case TT_KEYWORD_DECLARING_VARBLOCK:
                blockbracket_check();
                break;

            case TT_CLASSNAME:
            case TT_FUNCTION:
            case TT_IDENTIFIER:
            {
                NameType name_type = (
                    token->type == TT_CLASSNAME ? NT_CLASS :
                    token->type == TT_FUNCTION ? NT_FUNCTION :
                        NT_VARIABLE);

                auto name_in_list = env.list_of_names.find(token->line);
                if(name_in_list == env.list_of_names.end())
                {
                    env.list_of_names[token->line] = name_type;
                    name_style_check(name_type);
                }
                else
                {
                    if(name_type == NT_VARIABLE)
                        //TODO: store checked names
                        name_style_check(name_in_list->second);
                    else if(name_in_list->second != name_type)
                    {
                        //constructors in C++ are exceptions
                        //assume C++ function with name == classname is a constructor or destructor
                        //TODO: do check?
                    }
                }
                break;
            }

            case TT_KEYWORD_WITH_FOLLOWING_OPERATION:
            {
                if(keyword_equal("else"))
                {
                    if(previous_is_blockbracket())
                    {
                        else_check();
                    }
                    else if(
                        settings.ext_bool_options["forbid_multiple_expressions_per_line"] == EB_TRUE &&
                        file_language.first == L_PASCAL &&
                        token->start != lines[token->line_index].depth_by_fact)
                    {
                        add_result("two or more expressions at one line");
                        env.line_closed = false;
                    }
                }
                if(settings.ext_bool_options["forbid_multiple_expressions_per_line"] == EB_TRUE)
                    env.line_closed = true;
                env.indented_operation_expected = true;
                break;
            }

            case TT_KEYWORD_WITH_FOLLOWING_OPERATION_AFTER_BRACE:
                keyword_and_brace_check();
                env.indented_operation_expected_after_braces = true; //required for multiple ops
                break;

            case TT_SEMICOLON:
                if(env.braces_opened == 0)
                    if(settings.ext_bool_options["forbid_multiple_expressions_per_line"] == EB_TRUE)
                        env.line_closed = true;
                break;

            case TT_BRACE:
                brace_check();
                break;
        }

        if(env.indented_operation_expected && settings.ext_bool_options["compulsory_block_braces"] == EB_TRUE)
        {
            if(!next_is_blockbracket(false))
                add_result("block brace expected: { or begin");

            env.indented_operation_expected = false;
        }
    }
}
Exemple #2
0
bool colvarparse::key_lookup(std::string const &conf,
                             char const *key_in,
                             std::string &data,
                             size_t &save_pos)
{
  // add this keyword to the register (in its camelCase version)
  add_keyword(key_in);

  // use the lowercase version from now on
  std::string const key(to_lower_cppstr(key_in));

  // "conf_lower" is only used to lookup the keyword, but its value
  // will be read from "conf", in order not to mess up file names
  std::string const conf_lower(to_lower_cppstr(conf));

  // by default, there is no value, unless we found one
  data = "";

  // when the function is invoked without save_pos, ensure that we
  // start from zero
  colvarparse::dummy_pos = 0;

  // start from the first occurrence of key
  size_t pos = conf_lower.find(key, save_pos);

  // iterate over all instances until it finds the isolated keyword
  while (true) {

    if (pos == std::string::npos) {
      // no valid instance of the keyword has been found
      return false;
    }

    bool b_isolated_left = true, b_isolated_right = true;

    if (pos > 0) {
      if ( std::string("\n"+white_space+
                       "}").find(conf[pos-1]) ==
           std::string::npos ) {
        // none of the valid delimiting characters is on the left of key
        b_isolated_left = false;
      }
    }

    if (pos < conf.size()-key.size()-1) {
      if ( std::string("\n"+white_space+
                       "{").find(conf[pos+key.size()]) ==
           std::string::npos ) {
        // none of the valid delimiting characters is on the right of key
        b_isolated_right = false;
      }
    }

    // check that there are matching braces between here and the end of conf
    bool const b_not_within_block = brace_check(conf, pos);

    bool const b_isolated = (b_isolated_left && b_isolated_right &&
                             b_not_within_block);

    if (b_isolated) {
      // found it
      break;
    } else {
      // try the next occurrence of key
      pos = conf_lower.find(key, pos+key.size());
    }
  }

  // save the pointer for a future call (when iterating over multiple
  // valid instances of the same keyword)
  save_pos = pos + key.size();

  // get the remainder of the line
  size_t pl = conf.rfind("\n", pos);
  size_t line_begin = (pl == std::string::npos) ? 0 : pos;
  size_t nl = conf.find("\n", pos);
  size_t line_end = (nl == std::string::npos) ? conf.size() : nl;
  std::string line(conf, line_begin, (line_end-line_begin));

  size_t data_begin = (to_lower_cppstr(line)).find(key) + key.size();
  data_begin = line.find_first_not_of(white_space, data_begin+1);

  //   size_t data_begin_absolute = data_begin + line_begin;
  //   size_t data_end_absolute   = data_begin;

  if (data_begin != std::string::npos) {

    size_t data_end = line.find_last_not_of(white_space) + 1;
    data_end = (data_end == std::string::npos) ? line.size() : data_end;
    //     data_end_absolute = data_end + line_begin;

    if (line.find('{', data_begin) != std::string::npos) {

      size_t brace_count = 1;
      size_t brace = line.find('{', data_begin);  // start from the first opening brace

      while (brace_count > 0) {

        // find the matching closing brace
        brace = line.find_first_of("{}", brace+1);
        while (brace == std::string::npos) {
          // add a new line
          if (line_end >= conf.size()) {
            cvm::fatal_error("Parse error: reached the end while "
                             "looking for closing brace; until now "
                             "the following was parsed: \"\n"+
                             line+"\".\n");
            return false;
          }
          size_t const old_end = line.size();
          //           data_end_absolute += old_end+1;

          line_begin = line_end;
          nl = conf.find('\n', line_begin+1);
          if (nl == std::string::npos)
            line_end = conf.size();
          else
            line_end = nl;
          line.append(conf, line_begin, (line_end-line_begin));

          brace = line.find_first_of("{}", old_end);
        }

        if (line[brace] == '{') brace_count++;
        if (line[brace] == '}') brace_count--;
      }

      // set data_begin after the opening brace
      data_begin = line.find_first_of('{', data_begin) + 1;
      data_begin = line.find_first_not_of(white_space,
                                          data_begin);
      // set data_end before the closing brace
      data_end = brace;
      data_end = line.find_last_not_of(white_space+"}",
                                       data_end) + 1;
      //       data_end_absolute = line_end;

      if (data_end > line.size())
        data_end = line.size();
    }

    data.append(line, data_begin, (data_end-data_begin));

    if (data.size() && save_delimiters) {
      data_begin_pos.push_back(conf.find(data, pos+key.size()));
      data_end_pos.push_back(data_begin_pos.back()+data.size());
      //       std::cerr << "key = " << key << ", data = \""
      //                 << data << "\", data_begin, data_end = "
      //                 << data_begin_pos.back() << ", " << data_end_pos.back()
      //                 << "\n";
    }
  }

  save_pos = line_end;

  return true;
}