⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 worldfile.cc

📁 一个机器人平台
💻 CC
📖 第 1 页 / 共 3 页
字号:
  int ch;  int len;  char token[256];    len = 0;  memset(token, 0, sizeof(token));  ch = fgetc(file);        while (true)  {    ch = fgetc(file);    if (ch == EOF || ch == '\n')    {      TOKEN_ERR("unterminated string constant", *line);      return false;    }    else if (ch == '"')    {      AddToken(TokenString, token, include);      return true;    }    else    {      token[len++] = ch;    }  }  assert(false);  return false;}///////////////////////////////////////////////////////////////////////////// Read in a whitespace tokenbool CWorldFile::LoadTokenSpace(FILE *file, int *line, int include){  int ch;  int len;  char token[256];    len = 0;  memset(token, 0, sizeof(token));    while (true)  {    ch = fgetc(file);    if (ch == EOF)    {      AddToken(TokenSpace, token, include);      return true;    }    else if (isblank(ch))    {      token[len++] = ch;    }    else    {      AddToken(TokenSpace, token, include);      ungetc(ch, file);      return true;    }  }  assert(false);  return false;}///////////////////////////////////////////////////////////////////////////// Save tokens to a file.bool CWorldFile::SaveTokens(FILE *file){  int i;  CToken *token;    for (i = 0; i < this->token_count; i++)  {    token = this->tokens + i;    if (token->include > 0)      continue;    if (token->type == TokenString)      fprintf(file, "\"%s\"", token->value);      else      fprintf(file, "%s", token->value);  }  return true;}///////////////////////////////////////////////////////////////////////////// Clear the token listvoid CWorldFile::ClearTokens(){  int i;  CToken *token;  for (i = 0; i < this->token_count; i++)  {    token = this->tokens + i;    free(token->value);  }  free(this->tokens);  this->tokens = 0;  this->token_size = 0;  this->token_count = 0;}///////////////////////////////////////////////////////////////////////////// Add a token to the token listbool CWorldFile::AddToken(int type, const char *value, int include){  if (this->token_count >= this->token_size)  {    this->token_size += 1000;    this->tokens = (CToken*) realloc(this->tokens, this->token_size * sizeof(this->tokens[0]));  }  this->tokens[this->token_count].include = include;    this->tokens[this->token_count].type = type;  this->tokens[this->token_count].value = strdup(value);  this->token_count++;    return true;}///////////////////////////////////////////////////////////////////////////// Set a token value in the token listbool CWorldFile::SetTokenValue(int index, const char *value){  assert(index >= 0 && index < this->token_count);  free(this->tokens[index].value);  this->tokens[index].value = strdup(value);    return true;}///////////////////////////////////////////////////////////////////////////// Get the value of a tokenconst char *CWorldFile::GetTokenValue(int index){  assert(index >= 0 && index < this->token_count);  return this->tokens[index].value;}///////////////////////////////////////////////////////////////////////////// Dump the token list (for debugging).void CWorldFile::DumpTokens(){  int line;  line = 1;  printf("\n## begin tokens\n");  printf("## %4d : ", line);  for (int i = 0; i < this->token_count; i++)  {    if (this->tokens[i].value[0] == '\n')      printf("[\\n]\n## %4d : %02d ", ++line, this->tokens[i].include);    else      printf("[%s] ", this->tokens[i].value);  }  printf("\n");  printf("## end tokens\n");}///////////////////////////////////////////////////////////////////////////// Parse tokens into entities and properties.bool CWorldFile::ParseTokens(){  int i;  int entity;  int line;  CToken *token;  ClearEntities();  ClearProperties();    // Add in the "global" entity.  entity = AddEntity(-1, "");  line = 1;    for (i = 0; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenWord:        if (strcmp(token->value, "include") == 0)        {          if (!ParseTokenInclude(&i, &line))            return false;        }        else if (strcmp(token->value, "define") == 0)        {          if (!ParseTokenDefine(&i, &line))            return false;        }        else        {          if (!ParseTokenWord(entity, &i, &line))            return false;        }        break;      case TokenComment:        break;      case TokenSpace:        break;      case TokenEOL:        line++;        break;      default:        PARSE_ERR("syntax error 1", line);        return false;    }  }  return true;}///////////////////////////////////////////////////////////////////////////// Parse an include statementbool CWorldFile::ParseTokenInclude(int *index, int *line){  int i;  CToken *token;  for (i = *index + 1; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenString:        break;      case TokenSpace:        break;      case TokenEOL:        *index = i;        (*line)++;        return true;      default:        PARSE_ERR("syntax error in include statement", *line);        return false;    }  }  PARSE_ERR("incomplete include statement", *line);  return false;}///////////////////////////////////////////////////////////////////////////// Parse a macro definitionbool CWorldFile::ParseTokenDefine(int *index, int *line){  int i;  int count;  const char *macroname, *entityname;  int starttoken;  CToken *token;  count = 0;  macroname = NULL;  entityname = NULL;  starttoken = -1;  for (i = *index + 1; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenWord:        if (count == 0)        {          if (macroname == NULL)            macroname = GetTokenValue(i);          else if (entityname == NULL)          {            entityname = GetTokenValue(i);            starttoken = i;          }          else          {            PARSE_ERR("extra tokens in macro definition", *line);            return false;          }        }        else        {          if (macroname == NULL)          {            PARSE_ERR("missing name in macro definition", *line);            return false;          }          if (entityname == NULL)          {            PARSE_ERR("missing name in macro definition", *line);            return false;          }        }        break;      case TokenOpenEntity:        count++;        break;      case TokenCloseEntity:        count--;        if (count == 0)        {          AddMacro(macroname, entityname, *line, starttoken, i);          *index = i;          return true;        }        if (count < 0)        {          PARSE_ERR("misplaced ')'", *line);          return false;        }        break;      default:        break;    }  }  PARSE_ERR("missing ')'", *line);  return false;}///////////////////////////////////////////////////////////////////////////// Parse something starting with a word; could be a entity or an property.bool CWorldFile::ParseTokenWord(int entity, int *index, int *line){  int i;  CToken *token;  for (i = *index + 1; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenComment:        break;      case TokenSpace:        break;      case TokenEOL:        (*line)++;        break;      case TokenOpenEntity:        return ParseTokenEntity(entity, index, line);      case TokenNum:      case TokenString:      case TokenOpenTuple:        return ParseTokenProperty(entity, index, line);      default:        PARSE_ERR("syntax error 2", *line);        return false;    }  }    return false;}///////////////////////////////////////////////////////////////////////////// Parse a entity from the token list.bool CWorldFile::ParseTokenEntity(int entity, int *index, int *line){  int i;  int macro;  int name;  CToken *token;  name = *index;  macro = LookupMacro(GetTokenValue(name));    // If the entity name is a macro...  if (macro >= 0)  {    // This is a bit of a hack    int nentity = this->entity_count;    int mindex = this->macros[macro].starttoken;    int mline = this->macros[macro].line;    if (!ParseTokenEntity(entity, &mindex, &mline))      return false;    entity = nentity;    for (i = *index + 1; i < this->token_count; i++)    {      token = this->tokens + i;      switch (token->type)      {        case TokenOpenEntity:          break;        case TokenWord:          if (!ParseTokenWord(entity, &i, line))            return false;          break;        case TokenCloseEntity:          *index = i;          return true;        case TokenComment:          break;        case TokenSpace:          break;        case TokenEOL:          (*line)++;          break;        default:          PARSE_ERR("syntax error 3", *line);          return false;      }    }    PARSE_ERR("missing ')'", *line);  }    // If the entity name is not a macro...  else  {    for (i = *index + 1; i < this->token_count; i++)    {      token = this->tokens + i;      switch (token->type)      {        case TokenOpenEntity:          entity = AddEntity(entity, GetTokenValue(name));          break;        case TokenWord:          if (!ParseTokenWord(entity, &i, line))            return false;          break;        case TokenCloseEntity:          *index = i;          return true;        case TokenComment:          break;        case TokenSpace:          break;        case TokenEOL:          (*line)++;          break;        default:          PARSE_ERR("syntax error 3", *line);          return false;      }    }    PARSE_ERR("missing ')'", *line);  }  return false;}///////////////////////////////////////////////////////////////////////////// Parse an property from the token list.bool CWorldFile::ParseTokenProperty(int entity, int *index, int *line){  int i, property;  int name, value, count;  CToken *token;  name = *index;  value = -1;  count = 0;    for (i = *index + 1; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenNum:        property = AddProperty(entity, GetTokenValue(name), *line);        AddPropertyValue(property, 0, i);        *index = i;        return true;      case TokenString:        property = AddProperty(entity, GetTokenValue(name), *line);        AddPropertyValue(property, 0, i);        *index = i;        return true;      case TokenOpenTuple:        property = AddProperty(entity, GetTokenValue(name), *line);        if (!ParseTokenTuple(entity, property, &i, line))          return false;        *index = i;        return true;      case TokenSpace:        break;      default:        PARSE_ERR("syntax error 4", *line);        return false;    }  }  return true;}///////////////////////////////////////////////////////////////////////////// Parse a tuple.bool CWorldFile::ParseTokenTuple(int entity, int property, int *index, int *line){  int i, count;  CToken *token;  count = 0;    for (i = *index + 1; i < this->token_count; i++)  {    token = this->tokens + i;    switch (token->type)    {      case TokenNum:        AddPropertyValue(property, count++, i);        *index = i;        break;      case TokenString:        AddPropertyValue(property, count++, i);        *index = i;        break;      case TokenCloseTuple:        *index = i;        return true;      case TokenSpace:        break;      default:        PARSE_ERR("syntax error 5", *line);        return false;    }  }  return true;}///////////////////////////////////////////////////////////////////////////// Clear the macro listvoid CWorldFile::ClearMacros(){  free(this->macros);  this->macros = NULL;  this->macro_size = 0;  this->macro_count = 0;}///////////////////////////////////////////////////////////////////////////// Add a macroint CWorldFile::AddMacro(const char *macroname, const char *entityname,                         int line, int starttoken, int endtoken){  if (this->macro_count >= this->macro_size)  {    this->macro_size += 100;    this->macros = (CMacro*)      realloc(this->macros, this->macro_size * sizeof(this->macros[0]));  }  int macro = this->macro_count;  this->macros[macro].macroname = macroname;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -