умный токенизатор в с - PullRequest
       313

умный токенизатор в с

0 голосов
/ 05 января 2012

Мне нужно написать токенайзер на c / c ++, чтобы мне нужно было проанализировать строку вида

char pSignature[] = "work.\\top =>\\p1 =:5:p2=:10:=>interface_ports:=dut";

и заполните пару \ p1 5 и p2 10 и т. Д. Кто-то может предложить мне какой-нибудь хороший метод. Проблема с использованием strtok заключается в том, как завершить его до того, как => interface_ports. Ниже приведен код, который я написал:

int main() {
  char pSignature[] = "work.\\top =>\\p1 =:5:p2=:10:=>interface_ports:=dut";
  char* mParamName = NULL;
  char* mParamVal = NULL;
  char* sTemp = pSignature;
  bool bIsLibState = true;
  bool bIsModState = false;
  bool bIsEscaped = false;
  while (*sTemp != '\0') {
    // Extract library ..
    if (bIsLibState) {
      if (*sTemp == '.') {
        bIsLibState = false;
        bIsModState = true;
      }
      sTemp++;
    }
    else if (bIsModState) {
    // Extract moduleName..
      if (*sTemp == '\\') {
        bIsEscaped = true;
      }
      if (bIsEscaped) {
        if (*sTemp == ' ') {
          bIsModState = false;
          bIsEscaped = false;
          sTemp++;
          sTemp += 2;
          break;
        }
        else 
          sTemp++;
      }
      else {
        if (*(sTemp+1) == '=' && *(sTemp+2) == '>') {
          bIsModState = false;
          sTemp++;
          sTemp += 2;
          break;
        }
        else
          sTemp++;
      }
    }
  }

  char* tmp = sTemp;
  char* mStr = sTemp;
  bool bEscaped = false;
  while(tmp != NULL)
  {
    if (*tmp == '\\') {
      tmp = strtok(mStr, " ");
        bEscaped  = true;
    }
    else
      tmp = strtok(mStr, "=:");
    if (!strcmp(tmp,">interface_ports"))
      break;
    mStr = NULL;
    mParamName = tmp;

    tmp = strtok(mStr, "=:");
    if (!strcmp(tmp,">interface_ports"))
      break;
    mParamVal = tmp;
    cout << mParamName <<"  " << mParamVal << endl;
    //if (mParamName && mParamVal) {
    //  symCharPair* paramPair = new symCharPair(VeIntern(mParamName), mParamVal);
    //  pParamValueList->AddTail(paramPair);
    //}
  }
return 0;
}

Ответы [ 2 ]

1 голос
/ 05 января 2012

Если ваша входная строка всегда имеет такую ​​форму

work.\\top =>\\p1 =:5:p2=:10:=>interface_ports:=dut

Тогда вы можете сделать что-то попроще:

 #include <string.h>

 const char *input = "work.\\top =>\\p1 =:5:p2=:10:=>interface_ports:=dut";

 // find first occurrence of "=>"
 const char *start = strstr(input, "=>");

 // find first occurrence of ":=>"
 const char *end= strstr(input, ":=>");

 if (start == NULL || end == NULL)
     exit(-1);

 int length = end - start - 2 ; // the -2 is to skip the "=>"
 char *pairs = malloc(length + 1); // +1 for the terminating \0
 strncpy(pairs, start + 2, length);

Теперь pairs должно содержать \p1 =:5:p2=:10, что вы могли былегче справиться.

0 голосов
/ 05 января 2012

Чтение книг о синтаксическом анализе и lexing методов, особенно используемых при компиляции.

Узнайте, как создавать парсеры рекурсивного спуска, и, возможно,используйте генераторы, такие как ANTLR , bison (или yacc), flex

...