int tablePutDef(tableT *tableP, cardT *cardP, int beatPos) { // check validity of defense assignment // exit with error if pushing not possible for some reason if(cardP == NULL || beatPos < 0 || beatPos >= stackSize(tableP->att) || stackPush(tableP->def,cardP) == EXIT_FAILURE) { /* some debugging printf("FIAL\n"); if(cardP == NULL) { printf("CardPointer NULL!\n"); } if(beatPos < 0 || beatPos >= stackSize(tableP->att)) { printf("beatPos off range (%d/%d)!\n",beatPos,stackSize(tableP->att)-1); } */ return(EXIT_FAILURE); } // mark the position in `beats` array // which corresponds to the position of cardDef on the def stack (topmost) // with the position of the card to beat on the att stack (given) tableP->beats[stackSize(tableP->def)-1] = beatPos; return(EXIT_SUCCESS); }
int LuaInterface::safeCall(int numArgs, int numRets) { assert(hasIndex(-numArgs-1)); // saves the current stack size for calculating the number of results later int previousStackSize = stackSize(); // pushes error function int errorFuncIndex = previousStackSize - numArgs; pushCFunction(&LuaInterface::luaErrorHandler); insert(errorFuncIndex); // calls the function in protected mode (means errors will be caught) int ret = pcall(numArgs, LUA_MULTRET, errorFuncIndex); remove(errorFuncIndex); // remove error func // if there was an error throw an exception if(ret != 0) throw LuaException(popString()); int rets = (stackSize() + numArgs + 1) - previousStackSize; while(numRets != -1 && rets != numRets) { if(rets < numRets) { pushNil(); rets++; } else { pop(); rets--; } } // returns the number of results return rets; }
void test_Vector() { struct stack* alist = (struct stack*)malloc(sizeof(struct stack)); stackInitialize(alist,1024); int i = 0; for (i = 0; i < 15; i++) { char* tmp = (char*)malloc(sizeof(char)* 512); memset(tmp, 0, sizeof(char)* 512); sprintf(tmp, "hehe%d", i); printf("%s\n", tmp); stackPush(alist, tmp); } printf("\n\n"); int len = stackSize(alist); for (i = 0; i < len; i++) { char* tmp; //tmp=stackGet(alist, i); tmp=stackPop(alist); printf("%s\n", tmp); } stackFree(alist); }
void populateSTable(funcArg* a){ //printf("populateSTable\n"); char tmp[5]; sprintf(tmp, "_%d", getOccurence(a->funcName)); char key[55]; strcpy(key,a->vname); strcat(key,tmp); if(a->isConstant == 1){ add_entryToSTable(key,"Constant",a->val,a->val,a->type); printf("%s Constant\n", key); } else{ char* sym; void* val; if(symStack == NULL || stackSize(symStack) == 0){ sym = find_symVal(a->apname); val = find_conVal(a->apname); } else{ sym = find_symVal(get_vnameHash(a->apname)); val = find_conVal(get_vnameHash(a->apname)); } add_entryToSTable(key,sym,val,val,a->type); //add_vnameHash(a->vname, key); printf("%s %s\n", key, sym); } add_vnameHash(a->vname, key); }
void funcExit(){ int* execFlag = (int *)malloc(sizeof(int)); stackPop(didFuncEntryExecute, (&execFlag)); printf("execFlag of funcEntry : %d\n", *execFlag); if(*execFlag == 1){ printf("funcEntry executed\n"); printf("retSymVal : %s\n",ret_SymValue); if(ret_ConValue == NULL){ printf("no return concrete value\n"); } else{ printf("retConVal \"%d\"\n",*((int *)(ret_ConValue))); } funcVars* fv = (funcVars*) malloc (sizeof(funcVars)); stackPop(symStack, (&fv)); int j; for(j=0; j < fv->noOfVars; j++){ deleteEntryUsingVar(fv->vars[j]); deleteEntryUsingVar(get_vnameHash(fv->vars[j])); del_vnameHash(fv->vars[j]); } int k; for(k=0; k < fv->noOfLocals; k++){ deleteEntryUsingVar(get_vnameHash(fv->locals[k])); del_vnameHash(fv->locals[k]); } //free(fv); printf("Stack depth %d\n", stackSize(symStack)); } else printf("funcEntry did not execute.....must be concolic\n"); }
// main int main(){ // top is a pointer to a node struct // holds null struct node* top = NULL; // size is 0 int size=0; printf("in main"); // prints "size = 0, top = [something that indicates it's null]" printf("\nsize = %d, *top = %p",size,top); // sends top (currently null) to printStack() printStack(top); printf("\nThe size of the stack is %d.\n", stackSize(top)); pop(top); // sends the location of top (bc of the &) // to push() w the value 4 push(4,&top); pop(top); printf("\nThe size of the stack is %d.\n", stackSize(top)); // size is the size of the stack, top is the address of the node // top -> data is the value for data held in the node's address // top -> is the value for the next node held in the current node's address printf("\nsize = %d, *top = %p, top data = %d, top next = %p",size,top,top->data,top->next); printStack(top); //printf("\nsize = %d, *top = %p, top data = %d, top next = %p",size,top,top->data,top->next); push(5,&top); printf("\nThe size of the stack is %d.\n", stackSize(top)); //printf("\nsize = %d, *top = %p, top data = %d, top next = %p",size,top,top->data,top->next); printStack(top); push(6,&top); printf("\nThe size of the stack is %d.\n", stackSize(top)); printStack(top); return (0); }
void StackFrame::gcMark( uint32 mark ) { uint32 sl = stackSize(); memPool->markItem( m_self ); memPool->markItem( m_binding ); for( uint32 pos = 0; pos < sl; pos++ ) { memPool->markItem( stackItems()[ pos ] ); } }
bool stackPush (arraystack_t *stack, void *element) { if (stackSize (stack) == stack->capacity) { return false; } stack->top += 1; memcpy (stack->data + stack->top, element, sizeof (element)); return true; }
MalStkPtr newGlobalStack(int size) { MalStkPtr s; s = (MalStkPtr) GDKzalloc(stackSize(size) + offsetof(MalStack, stk)); if (s == NULL) GDKfatal("newGlobalStack:can not obtain memory\n"); s->stksize = size; return s; }
MalStkPtr newGlobalStack(int size) { MalStkPtr s; s = (MalStkPtr) GDKzalloc(stackSize(size) + offsetof(MalStack, stk)); if (!s) return NULL; s->stksize = size; return s; }
void botDefend(playerT *botP, tableT *tableP, int trumpSuit) { // sort cards by value playerSortHand(botP,trumpSuit); // for each card to beat, look for the lowest possible solution for (int k = 0; k < stackSize(botP->hand); ++k) { // beat with the first card possible for (int i = 0; i < stackSize(tableP->att); ++i) { if (cardBeats(&botP->hand->cards[k],tableP,i,trumpSuit)) { tablePutDef(tableP,playCard(botP,k),i); return; } } } // if no card could beat any attacking cards, mark that bot will take cards playerEndRound(botP); }
void funcExit(char* AssignLval){ printf("AssignLval: \"%s\" \n",AssignLval); symAssignFunctionReturn(AssignLval); funcVars* fv = (funcVars*) malloc (sizeof(funcVars)); stackPop(symStack, (&fv)); int j; for(j=0; j < fv->noOfVars; j++){ deleteEntryUsingVar(fv->vars[j]); del_vnameHash(fv->vars[j]); } //free(fv); printf("Stack depth %d\n", stackSize(symStack)); }
void botAttack(playerT *botP, partyT *partyP, tableT *tableP, int trumpSuit) { // sort cards by value playerSortHand(botP,trumpSuit); // look for the first card that would fit on the table for (int i = 0; i < stackSize(botP->hand); ++i) { // when found, put it on the table and exit if (stackSize(partyP->defender->hand) > (stackSize(tableP->att)-stackSize(tableP->def)) && cardFits(&botP->hand->cards[i],tableP)) { tablePutAtt(tableP,playCard(botP,i)); // don't attack any more if no cards left if (stackSize(botP->hand) == 0) { playerEndRound(botP); } return; } } // if no card found, stop attacking playerEndRound(botP); return; }
MalStkPtr reallocGlobalStack(MalStkPtr old, int cnt) { int k; MalStkPtr s; if (old->stksize > cnt) return old; k = ((cnt / STACKINCR) + 1) * STACKINCR; s = newGlobalStack(k); memcpy(s, old, stackSize(old->stksize)); s->stksize = k; GDKfree(old); return s; }
bool makeFastArrayFromStack (variable & to, const stackHandler * stacky) { int size = stackSize (stacky); if (! makeFastArraySize (to, size)) return false; // Now let's fill up the new array variableStack * allV = stacky -> first; size = 0; while (allV) { copyMain (allV -> thisVar, to.varData.fastArray -> fastVariables[size]); size ++; allV = allV -> next; } return true; }
Output::Output(QObject* parent) : QThread(parent) , recycler_(stackSize()) { handler_ = 0; frequency_ = 0; channels_ = 0; kbps_ = 0; total_written_ = 0; current_milliseconds_ = -1; bytes_per_millisecond_ = 0; user_stop_ = false; pause_ = false; finish_ = false; is_seeking_ = false; }
void MethodCall::eval() { if (_mode == RToSmoke) _stack = new Smoke::StackItem[length(_args) + 1]; else if (_mode == SmokeToR) PROTECT(_args = allocVector(VECSXP, stackSize() - 1)); if (_mode != Identity) { marshal(); _called = false; } else invokeMethod(); if (_mode == RToSmoke) { delete[] _stack; _stack = NULL; } else if (_mode == SmokeToR) { UNPROTECT(1); _args = NULL; } }
void evalStackPush(Stack *s, token val) { if(prefs.display.postfix) printf("\t%s\n", val); switch(tokenType(val)) { case function: { //token res; //operand = (token)stackPop(s); if (doFunc(s, val) < 0) return; //stackPush(s, res); } break; case expop: case multop: case addop: { if(stackSize(s) >= 2) { // Pop two operands // Evaluate if (doOp(s, val) < 0) return; // Push result //stackPush(s, res); } else { stackPush(s, val); } } break; case value: { stackPush(s, val); } break; default: break; } }
void funcEntry(char* format, char* args, char* funcName) { printf("funcEntry: %s \"%s\" \n", funcName, args); int size=0; varNames = (char**) malloc(10 * sizeof(char*)); char s[] = " "; char *token; char *copy = strdup(args); char* tmp = copy; int count = 1; while (*tmp != '\0') { if (*tmp++ == ' ') count++; } char** tokens = (char**) malloc(sizeof(char*) * count); token = strtok(copy, s); int i = 0; while (token != NULL) { *(tokens + i) = token; token = strtok(NULL, s); i++; } for (i = 0; i < count; i++) { funcArg *a = getArgument(*(tokens + i), funcName); varNames[size++] = a->vname; populateSTable(a); } funcVars* fv = (funcVars*) malloc (sizeof(funcVars)); fv->vars = varNames; fv->noOfVars = size; strcpy(fv->funcName,funcName); fv->occurence = getOccurence(funcName)+1; if(stackInitFlag){ stackPush(symStack, (&fv)); } else{ symStack = stackNew(sizeof(funcVars*)); stackPush(symStack, (&fv)); stackInitFlag=1; } size=0; i=0; free(copy); printf("Stack depth %d\n", stackSize(symStack)); }
char* infixToPostfix(char const* str) { generic_stack* infixStack = stackAllocate(1); generic_stack* output = stackAllocate(1); char peek; for (; *str; ++str) { stackPeek(infixStack, &peek); if (*str == '(') { peek = '('; stackPush(infixStack, &peek); } else if (*str == ')') { while (peek != '(') { stackPop(infixStack, &peek); stackPush(output, &peek); stackPeek(infixStack, &peek); } //Discard the '(' stackPop(infixStack, &peek); } else { while (!stackEmpty(infixStack) && precidence(peek) >= precidence(*str)) { stackPop(infixStack, &peek); stackPush(output, &peek); //Update the peeked stackPeek(infixStack, &peek); } stackPush(infixStack, str); } } while (!stackEmpty(infixStack)) { stackPop(infixStack, &peek); stackPush(output, &peek); } peek = '\0'; stackPush(output, &peek); char* result = malloc(stackSize(output)); memcpy(result, output->data, output->current); stackFree(infixStack); stackFree(output); return result; }
void MethodCall::marshal() { int oldcur = _cur; _cur++; // handle arguments while(!_called && _cur < stackSize()) { marshalItem(); _cur++; } if (!_called) { _called = true; _cur = 0; invokeMethod(); if (_method->lastError() == Method::NoError) { flip(); marshalItem(); flip(); } } _cur = oldcur; }
int tableClean(tableT *tableP, stackT *destP) { // clean attack stack if (stackClean(tableP->att,destP) == EXIT_FAILURE) { return(EXIT_FAILURE); } // clean defend stack if (stackClean(tableP->def,destP) == EXIT_FAILURE) { return(EXIT_FAILURE); } // reset `beats` array int size = stackSize(tableP->att); for (int i = 0; i < size; ++i) { tableP->beats[i] = -1; } return(EXIT_SUCCESS); }
int cliStackInfo(const char ** argv) { int tid = 0; if (toInt(argv, 1, &tid) > 0) { int available = 0; int total = 0; switch(tid) { case MENU_TASK_INDEX: total = menusStack.size(); available = menusStack.available(); break; case MIXER_TASK_INDEX: total = mixerStack.size(); available = mixerStack.available(); break; case AUDIO_TASK_INDEX: total = audioStack.size(); available = audioStack.available(); break; case CLI_TASK_INDEX: total = cliStack.size(); available = cliStack.available(); break; case MAIN_TASK_INDEX: total = stackSize() * 4; available = stackAvailable(); break; default: break; } serialPrint("%d available (%d total)", available, total); } else { serialPrint("%s: Invalid argument \"%s\"", argv[0], argv[1]); } return 0; }
int MethodCall::numArgs() const { return _args ? length(_args) : (stackSize() - 1); }
/* * This method will initialize the JVM. If there is already an active JVM * running, it will just attach to it. If there isn't an active JVM, it will * create and start a new one */ void Runtime::initializeJVM() throw( HLA::RTIinternalError ) { logger->debug( "Initialize the JVM" ); /////////////////////////////////////////// // 1. get the classpath and library path // /////////////////////////////////////////// pair<string,string> paths = this->generatePaths(); logger->debug( "Using Classpath : %s", paths.first.c_str() ); logger->debug( "Using Library Path: %s", paths.second.c_str() ); ///////////////////////////////////////////// // 2. check to see if a JVM already exists // ///////////////////////////////////////////// // other jvm options - remember to increment the option array size // if you are going to add more string stackSize( "-Xss8m" ); string mode = getMode(); string compiler = getCompiler(); string hlaVersion = getHlaVersion(); string architecture = getArch(); // before we can create or connect to the JVM, we need to specify its environment JavaVMInitArgs vmargs; JavaVMOption options[7]; options[0].optionString = const_cast<char*>(paths.first.c_str()); options[1].optionString = const_cast<char*>(paths.second.c_str()); options[2].optionString = const_cast<char*>(mode.c_str()); // build mode options[3].optionString = const_cast<char*>(compiler.c_str()); // compiler version options[4].optionString = const_cast<char*>(hlaVersion.c_str()); // hla interface version options[5].optionString = const_cast<char*>(architecture.c_str()); // architecture options[6].optionString = const_cast<char*>(stackSize.c_str()); vmargs.nOptions = 7; vmargs.version = JNI_VERSION_1_6; vmargs.options = options; vmargs.ignoreUnrecognized = JNI_TRUE; // Before we create the JVM, we will check to see if one already exists or // not. If there is an existing one, we will just attach to it rather than // creating a separate one. jint result; jsize jvmCount = 0; result = JNI_GetCreatedJavaVMs( &jvm, 1, &jvmCount ); if( this->jvm != NULL && jvmCount > 0 && result == JNI_OK ) { /////////////////////////////////////////////////////////////// // JVM already exists, just attach to the existing reference // /////////////////////////////////////////////////////////////// logger->debug( "[check] JVM already exists, attaching to it" ); result = jvm->AttachCurrentThread( (void**)&jvmenv, &vmargs ); // check the result if( result < 0 ) { logger->fatal( "*** JVM already existed, but we failed to attach ***" ); logger->fatal( " result=%d", result ); throw HLA::RTIinternalError( "*** JVM already existed, but we failed to attach ***" ); } // we're all attached just fine, so let's get out of here this->attached = true; return; } ////////////////////////////////// // 3. create a new JVM instance // ////////////////////////////////// // JVM doesn't exist yet, create a new one to work with logger->debug( "[check] JVM doesn't exist, creating a new one" ); result = JNI_CreateJavaVM( &jvm, (void**)&jvmenv, &vmargs ); if( result < 0 ) { logger->fatal( "*** Couldn't create a new JVM! *** result=%d", result ); throw HLA::RTIinternalError( "*** Couldn't create a new JVM! ***" ); } logger->info( "New JVM has been created" ); }
token doFunc(Stack *s, token function) { if (stackSize(s) == 0) { raise(inputMissing); return "NaN"; } else if (stackSize(s) == 1 && strcmp(stackTop(s), FUNCTIONSEPARATOR) == 0) { stackPop(s); raise(inputMissing); return "NaN"; } token input = (token)stackPop(s); number num = buildNumber(input); number result = num; number counter = 0; if(strncmp(function, "abs", 3) == 0) result = fabs(num); else if(strncmp(function, "floor", 5) == 0) result = floor(num); else if(strncmp(function, "ceil", 4) == 0) result = ceil(num); else if(strncmp(function, "sin", 3) == 0) result = !prefs.mode.degrees ? sin(num) : sin(toRadians(num)); else if(strncmp(function, "cos", 3) == 0) result = !prefs.mode.degrees ? cos(num) : cos(toRadians(num)); else if(strncmp(function, "tan", 3) == 0) result = !prefs.mode.degrees ? tan(num) : tan(toRadians(num)); else if(strncmp(function, "arcsin", 6) == 0 || strncmp(function, "asin", 4) == 0) result = !prefs.mode.degrees ? asin(num) : toDegrees(asin(num)); else if(strncmp(function, "arccos", 6) == 0 || strncmp(function, "acos", 4) == 0) result = !prefs.mode.degrees ? acos(num) : toDegrees(acos(num)); else if(strncmp(function, "arctan", 6) == 0 || strncmp(function, "atan", 4) == 0) result = !prefs.mode.degrees ? atan(num) : toDegrees(atan(num)); else if(strncmp(function, "sqrt", 4) == 0) result = sqrt(num); else if(strncmp(function, "cbrt", 4) == 0) result = cbrt(num); else if(strncmp(function, "log", 3) == 0) result = log(num); else if(strncmp(function, "exp", 3) == 0) result = exp(num); else if(strncmp(function, "min", 3) == 0) { while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); num = buildNumber(input); if (num < result) result = num; } } else if(strncmp(function, "max", 3) == 0) { while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); num = buildNumber(input); if (num > result) result = num; } } else if(strncmp(function, "sum", 3) == 0) { while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); num = buildNumber(input); result += num; } } else if(strncmp(function, "avg", 3) == 0 || strncmp(function, "mean", 4) == 0) { // Result already initialized with first number counter = 1; while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); num = buildNumber(input); result += num; counter++; } result /= counter; } else if(strncmp(function, "median", 6) == 0) { // needed for sorting Stack tmp, safe; // Result already initialized with first number counter = 1; stackInit(&tmp, (stackSize(s) > 0 ? stackSize(s) : 1)); stackInit(&safe, (stackSize(s) > 0 ? stackSize(s) : 1)); // add first value to the later sorted stack stackPush(&tmp, input); while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); num = buildNumber(input); // save all numbers larger as the stack value while (stackSize(&tmp) > 0 && buildNumber(stackTop(&tmp)) < num) { stackPush(&safe, stackPop(&tmp)); } // push value on the sorted stack stackPush(&tmp, input); // push all saved numbers back on the sorted stack while (stackSize(&safe) > 0) { stackPush(&tmp, stackPop(&safe)); } counter++; } stackFree(&safe); // calculate the median index counter = (number)(((int)counter+1)/2); // pop all numbers until median index while (counter > 1) { stackPop(&tmp); counter--; } result = buildNumber(stackPop(&tmp)); // pop the remaining sorted stack while (stackSize(&tmp) > 0) { stackPop(&tmp); } stackFree(&tmp); } else if(strncmp(function, "var", 3) == 0) { Stack tmp; counter = 1; // second stack to store values during calculation of mean stackInit(&tmp, (stackSize(s) > 0 ? stackSize(s) : 1)); // push first value to temporary stack stackPush(&tmp, input); number mean = result; while (stackSize(s) > 0 && strcmp(stackTop(s), FUNCTIONSEPARATOR) != 0) { input = (token)stackPop(s); // push value to temporary stack stackPush(&tmp, input); num = buildNumber(input); mean += num; counter++; } // calculate mean mean /= counter; result = 0; // calculate sum of squared differences while (stackSize(&tmp) > 0) { input = (token)stackPop(&tmp); num = buildNumber(input)-mean; result += pow(num,2); } // determine variance result /= counter; stackFree(&tmp); } if (strcmp(stackTop(s), FUNCTIONSEPARATOR) == 0) stackPop(s); stackPush(s, num2Str(result)); return 0; }
void showMeDepth( int n ) { Stack * s = makeStack( &printTreeVerticalMask ); Tree * t; Tree * tmpNode; int i; char dir; void ** args; /* Populate random tree of size n */ srand( time( 0 ) ); srand( rand( ) ); tmpNode = t = makeTree( ); for( i=1; i<n; i++ ) { while( ( CHILD( tmpNode, /*Choose a random direction at every branch*/ ( dir = rand() % 2 ) ) ) ) tmpNode = CHILD( tmpNode, dir ); if( dir ) tmpNode->right = makeTree( ); else tmpNode->left = makeTree( ); tmpNode = t; } /* End tree generator */ tmpNode = t; while( 1 ) { /* We've reached a leaf */ if( !tmpNode ) { /* Popped last element(head) off the stack */ if( !stackSize( s ) ) break; /* Print it for us(move this or add more for better resolution */ stackPrint( s ); printf( "\n" ); /* Get back to parent */ args = stackPop( s ); switch ((uintptr_t)args[0]) { case 0: /* Been down left side. Visiting right */ stackPush( s, 3, 1, i, args[2] ); tmpNode = ((Tree *)args[2])->right; break; case 1: /* Done with left and right. finish up */ /* i is whatever depth was for right side. left depth is stored in args[1] */ i = 1+ max( (uintptr_t)args[1], i ); tmpNode = NULL; break; } free( args ); continue; } /* If we're still going down a side of the tree, push this node on the stack and continue onward. Worry about depth later */ stackPush( s, 3, 0, 0, tmpNode ); tmpNode = tmpNode->left; /* i is our temp counter for depth. Since we haven't reached the bottom, don't start counting just yet. */ i = 0; } freeTree( t ); printf( "depth: %d\n", i ); }
// -------------------------------------------------------------------------- void* ctkBackTrace::returnAddress(unsigned frameNumber) const { if(frameNumber < stackSize()) return d->Frames[frameNumber]; return 0; }
bool postfix(token *tokens, int numTokens, Stack *output) { Stack operators, intermediate; int i; bool err = false; stackInit(&operators, numTokens); stackInit(&intermediate, numTokens); for(i = 0; i < numTokens; i++) { // From Wikipedia/Shunting-yard_algorithm: switch(tokenType(tokens[i])) { case value: { // If the token is a number, then add it to the output queue. //printf("Adding number %s to output stack\n", tokens[i]); evalStackPush(output, tokens[i]); } break; case function: { while(stackSize(&operators) > 0 && (tokenType(tokens[i]) != lparen) && ((precedence(tokens[i], (char*)stackTop(&operators)) <= 0))) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } // If the token is a function token, then push it onto the stack. //printf("Adding operator %s to operator stack\n", tokens[i]); stackPush(&operators, tokens[i]); } break; case argsep: { /* * If the token is a function argument separator (e.g., a comma): * Until the token at the top of the stack is a left * paren, pop operators off the stack onto the output * queue. If no left paren encountered, either separator * was misplaced or parens mismatched. */ while(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen && stackSize(&operators) > 1) { //printf("Moving operator from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } /*if(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen) { err = true; raise(parenMismatch); } printf("Removing left paren from operator stack\n"); stackPop(&operators); // Discard lparen*/ } break; case addop: case multop: case expop: { /* * If the token is an operator, op1, then: * while there is an operator token, op2, at the top of the stack, and * either op1 is left-associative and its precedence is less than or equal to that of op2, * or op1 is right-associative and its precedence is less than that of op2, * pop op2 off the stack, onto the output queue * push op1 onto the stack */ while(stackSize(&operators) > 0 && (tokenType((char*)stackTop(&operators)) == addop || tokenType((char*)stackTop(&operators)) == multop || tokenType((char*)stackTop(&operators)) == expop) && ((leftAssoc(tokens[i]) && precedence(tokens[i], (char*)stackTop(&operators)) <= 0) || (!leftAssoc(tokens[i]) && precedence(tokens[i], (char*)stackTop(&operators)) < 0))) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } //printf("Adding operator %s to operator stack\n", tokens[i]); stackPush(&operators, tokens[i]); } break; case lparen: { // If the token is a left paren, then push it onto the stack //printf("Adding left paren to operator stack\n"); if (tokenType(stackTop(&operators)) == function) stackPush(output, FUNCTIONSEPARATOR); stackPush(&operators, tokens[i]); } break; case rparen: { /* * If the token is a right paren: * Until the token at the top of the stack is a left paren, pop operators off the stack onto the output queue * Pop the left paren from the stack, but not onto the output queue * If the stack runs out without finding a left paren, then there are mismatched parens */ while(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen && stackSize(&operators) > 1) { //printf("Moving operator %s from operator stack to output stack\n", (char*)stackTop(&operators)); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } if(stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) != lparen) { err = true; raise(parenMismatch); } //printf("Removing left paren from operator stack\n"); stackPop(&operators); // Discard lparen while (stackSize(&operators) > 0 && tokenType((token)stackTop(&operators)) == function) { //printf("Removing function from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } } break; default: break; } } /* * When there are no more tokens to read: * While there are still operator tokens on the stack: * If the operator token on the top of the stack is a paren, then there are mismatched parens * Pop the operator onto the output queue */ while(stackSize(&operators) > 0) { if(tokenType((token)stackTop(&operators)) == lparen) { raise(parenMismatch); err = true; } //printf("Moving operator from operator stack to output stack\n"); evalStackPush(output, stackPop(&operators)); stackPush(&intermediate, stackTop(output)); } // pop result from intermediate stack stackPop(&intermediate); // free remaining intermediate results while (stackSize(&intermediate) > 0) { stackPop(&intermediate); } if (err == true) { while (stackSize(&operators) > 0) { token s = stackPop(&operators); //printf("Freeing %s from operators stack\n", s); free(s); } } stackFree(&intermediate); stackFree(&operators); return err; }
void SimpleJsonParser::parse( SimpleJsonTokenizer& tokenizer ) { #define IS_BREAK( t, b ) (t[0] == b && t[1] == '\0') enum ParseState { SCAN=1, ARRAY, PAIR, PAIR_COLON, RVALUE, RVALUE_SEPARATOR }; ParseState state = SCAN; char tag_name[MAXTAGNAMELEN+1]; CString array_index; reset(); push( this ); while ( tokenizer.hasToken() ) { LPSTR token = tokenizer.nextToken(); switch ( state ) { case SCAN: if ( IS_BREAK( token, '[' ) ) { // Start of array setType( JSONARRAY ); state = RVALUE; break; } else if ( IS_BREAK( token, '{' ) ) { // Start of object setType( JSONOBJECT ); state = PAIR; break; } throw std::exception( "Parser expected opening object or array" ); case PAIR: // Check for empty object if ( IS_BREAK( token, '}' ) && top()->getType() == JSONOBJECT && top()->valueCount() == 0 ) { pop(); state = RVALUE_SEPARATOR; break; } strcpy_s( tag_name, strip_quotes( token ) ); state = PAIR_COLON; break; case PAIR_COLON: if ( !IS_BREAK( token, ':' ) ) throw std::exception( "Parser expecting colon seperator" ); state = RVALUE; break; case RVALUE: { if ( IS_BREAK( token, ']' ) ) { // Empty array if ( top()->getType() != JSONARRAY ) throw std::exception( "Unexpected array closing bracket" ); pop(); state = RVALUE_SEPARATOR; break; } JsonNode* node = top(); if ( node->getType() == JSONARRAY ) { tag_name[0] = '\0'; } else if ( node->has_key( tag_name ) ) { CString error; error.Format( "Duplicate JSON tag name '%s'", tag_name ); throw std::exception( (LPCSTR)error ); } if ( IS_BREAK( token, '[' ) ) { push( node->setValue( JSONARRAY, tag_name ) ); state = RVALUE; break; } if ( IS_BREAK( token, '{' )) { push( node->setValue( JSONOBJECT, tag_name ) ); state = PAIR; break; } // Add a constant to current node container if ( node->getType() != JSONOBJECT && node->getType() != JSONARRAY) throw std::exception( "Parser expecting container JSON node" ); node->setValue( strip_quotes( token ), tag_name ); state = RVALUE_SEPARATOR; break; } case RVALUE_SEPARATOR: { JsonNode* node = m_nodeStack[m_stack_ptr-1]; if ( IS_BREAK( token, ',' ) ) { state = node->getType() == JSONARRAY ? RVALUE : PAIR; break; } if ( IS_BREAK( token, '}' ) && node->getType() == JSONOBJECT ) { pop(); break; } if ( IS_BREAK( token, ']' ) && node->getType() == JSONARRAY ) { if ( !node->validateArray( ) ) { CString error; error.Format( "Mixed object types in '%s'", node->getTagName() ); throw std::exception( (LPCSTR)error ); } pop(); break; } throw std::exception( "Parser expecting object or array seperator" ); } } } if ( stackSize() > 0 ) throw std::exception( "Unclosed JSON objects detected" ); }