Поиск слов в файле не работает правильно - PullRequest
0 голосов
/ 09 января 2019

Я делаю функцию в C, которая читает файл и находит слово, которого нет в комментарии и в строке (например, printf («Hello world»). Мне нужны только printf, «hello» и «world» не должно быть считается) но в некоторых файлах моя программа также считает слова в строке

int isDelimiter(char *delim, char c){
  int i = 0;
  while (delim[i])
  {
    if (delim[i] == c)
        return 1;
    i++;
  }
  return 0;
}

int getIdentifiers(FILE *filePointer){

  char line[256], identifier[100];

  //char delimiters[] = "\n\[]();~`!=><|*/:&% \t\"{},-+#^$'&";
  char delimiters[] = {'\n', '\"', '[', ']', '(', ')', ';', '~', '`', 
    '!', '=', '<','>', '|', '*','/',':','&',
    '%','\t', '{', '}', ',','-','+','#','^','$','&','\0'};

  int cnt=0, inWord=0, isString=0, isSingleLineComment=0, 
     isMultiComment=0, isChar=0;

  rewind(filePointer);

  while(fgets(line, sizeof(line), filePointer)!=NULL){

    int i=0, j=0;

    isSingleLineComment=0;

    while(line[i]){

      //multi line comment check
      if(line[i]=='/' && line[i+1]=='*') isMultiComment=1;

      //single line comment
      if(line[i]=='/' && line[i+1]=='/') isSingleLineComment=1;

      //ending multi line comment
      if(line[i]=='*' && line[i+1]=='/' && isMultiComment==1) isMultiComment=0;

      //checking for string
      if(line[i]=='"' && isString==0) isString=1;

      //check if assignment char is in quote
      if(line[i]=='\'' && isChar==0) isChar =1;
      else if(line[i]=='\'' && isChar==1) isChar=0;

      //splitting textline into words
      if(inWord==0){
        if(!isDelimiter(delimiters, line[i])) {
          inWord = 1;
          identifier[j] = line[i];
          j++;
        } else {
          i++;
          continue;
        }
      } else {
        //ending word
        if(isDelimiter(delimiters, line[i])) {
          if(line[i]=='"' ) isString=1;

          inWord=0;
          identifier[j]= '\0';
          j=0;

          // identifier checking
          if(!isString && !isMultiComment && !isSingleLineComment && 
             !isChar &&
             !isdigit(identifier[0])){
             cnt++;
          }
        } else {
          identifier[j]= line[i];
          j++;
        }
      }

      if(line[i]=='"' && isString){
        isString=0;
      }
      i++;
    }
  }

  return cnt;
}

Файл, который я тестирую, содержит:


int a;
// int c;
/ * int k;
* /
"int i; \" int c; "
int = e;

Ожидаемое возвращаемое значение должно быть 4 (мне нужны слова «int», «a», «int» и «e», но значение равно 2.

1 Ответ

0 голосов
/ 09 января 2019

Расширяя комментарий @ MichaelDorgan, есть несколько других крайних случаев, с которыми вам нужно иметь дело в отношении строк. Оба из них приведут к сбою вашего текущего парсера:

"This string \" contains a double quote"
"This one contains ' a single quote"

Я бы настоятельно рекомендовал изменить основную архитектуру синтаксического анализатора так, чтобы он начинался в состоянии, в котором слова распознаются, но если вы видите какой-либо из /* // " или ', вы переходите в состояние, которое ( A) игнорирует слова, и (B) использует отдельный цикл для использования ввода до тех пор, пока он правильно не распознает действительное завершение для текущего состояния, после чего он возвращается в исходное состояние.

Таким образом, /* будет продолжать читать текст, пока не найдет */, в то время как // просто отбрасывает остаток текущей строки и затем сбрасывается. Аналогичным образом " и ' сканируют вперед, пока не найдут вторую неэкранированную копию, игнорируя все остальное. Вам нужно будет обратить особое внимание на обратную косую черту в этом режиме, чтобы правильно обрабатывать такие вещи, как "\"", "\\" "\\\"" и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...