int isWhileStructure() { char token[TOKEN_SIZE]; strcpy(token, nextToken()); upper(token); if (hasNextToken() && strcmp(token, "NOT") != 0) { reportError(1, "expected NOT"); return 0; } strcpy(token, nextToken()); upper(token); if (strcmp(token, "DETECTMARKER") != 0) { reportError(2, "expected DETECTMARKER"); return 0; } strcpy(token, nextToken()); upper(token); if (strcmp(token, "DO") != 0) { reportError(3, "expected DO"); return 0; } int errorIndex = isCommaSeperatedCommands(); if (!errorIndex) return 1; if (errorIndex < 0) reportError(3-errorIndex, "command list must terminate with END command"); reportError(errorIndex+3, "not a valid comma seperated list of commands"); return 0; }
void reportError(int errorIndex, char *error) { myRewind(); for (int i=0; i<errorIndex; i++) { printf("%s ", nextToken()); } if (hasNextToken()) { printf("***%s ", nextToken()); } else { printf("*** "); } while(hasNextToken()) { printf("%s ", nextToken()); } printf("\nError: %s, ", error); }
int isString() { char token[TOKEN_SIZE]; strcpy(token, nextToken()); if (token[0] != '\"') { reportError(1, "expected a string beginning with \""); return 0; } while (hasNextToken()) { strcpy(token, nextToken()); } if (token[strlen(token)-1] != '\"') { reportError(1, "expected a string ending with \""); return 0; } return 1; }
std::string StringTokenizer::nextToken(){ if(!hasNextToken()){ return ""; } if(pos==str.length()){ pos++; return ""; } size_t nextPos = str.find_first_of(delims, pos); if(nextPos==std::string::npos){ std::string res = str.substr(pos); pos = str.length()+1; return res; } std::string res = str.substr(pos,nextPos-(pos)); pos = nextPos+1; return res; }
int isValidExpression(char *expression) { initBuffer(expression); char token[TOKEN_SIZE]; if (hasNextToken()) { strcpy(token, nextToken()); } else return 0; upper(token); if (strcmp(token, "REPEAT") == 0) return isRepeatStructure(); if (strcmp(token, "WHILE") == 0) return isWhileStructure(); if (strcmp(token, "SAY") == 0) return isString(); if (isValidCommand(token)) return 1; reportError(0, "not a valid expression"); return 0; }
/** "Returns 1 if the expression agrees with one of the legal robot expressions, otherwise it returns 0." <p> "Expression" is a line, not in individal token. It checks the individual tokens, and then it checks the syntax of the line. If it returns false, it's guaranteed to set synax.error. <p> It uses parse.c to tokenise, so it will destroy any temp data that you have. */ int isValidExpression(const char *const expression) { const struct Token *token; int shift; char avatar[512] = "", *a, *b; /* check the arguments */ if(!expression) { snprintf(syntax.error, sizeof syntax.error, "null expression"); syntax.index = -1; return 0; } /* parse expression into Tokens and put them into the avatar (expression buffer or whatever) */ initBuffer(expression); a = avatar; while(hasNextToken()) { if(!(token = match_token(nextToken()))) return 0; /* danger! (undefined behaviour) snprintf(avatar, sizeof avatar, "%s%c", avatar, token->avatar) */ if(a >= avatar + sizeof avatar / sizeof(char) - 1 /*null*/) { snprintf(syntax.error, sizeof syntax.error, "line too long; %u tokens", (int)sizeof avatar); /* index is set in parse.c */ return 0; } *(a++) = token->avatar; *a = '\0'; } if(debug) fprintf(stderr, "isValidExp avatar before <%s>\n", avatar); /* group tokens together; it could have been combined with the previous step for greater effecacity, but more confusion */ while((b = strrchr(avatar, 'E'))) { for(a = b - 1; a >= avatar && *a == '$'; a--); a++; for(shift = b - a, *(a++) = '%'; (*a = *(a + shift)); a++); } if(debug) fprintf(stderr, "isValidExp avatar grouping <%s>\n", avatar); return match_expression(avatar) ? 1 : 0; }
int isCommaSeperatedCommands() { while (hasNextToken()) { char token[80]; int i=0; strcpy(token, nextToken()); upper(token); if (token[strlen(token)-1] == ',') { char command_token[80]; strncpy(command_token, token, strlen(token)-1); command_token[strlen(token)-1] = '\0'; if (!isValidCommand(command_token)) return i; i++; } else { if (!isValidCommand(token)) return i; char *end_token = nextToken(); upper(end_token); if (strcmp(end_token, "END") != 0) return -i; break; } } return 0; }