/** uses isOperator to convert each character into an int based on their * precedence, and then returns the comparison */ int precedence( char operator1, char operator2 ){ int o1 = isOperator(operator1); int o2 = isOperator(operator2); return o1 - o2; }
void convertToPostfix( char infix[], char postfix[] ){ /* create the stack and add left bracket * My stack implimentation uses a single node as the * head node (called 'stack') which only points to the first * item of the stack and itself holds no data. if the stack is * empty the head node's nextPtr field will be NULL. Otherwise it * will maintain a link to the actual first node in the stack */ StackNodePtr stack = malloc(sizeN); push(&stack, '('); //append the ')' to the end of the infix expression int inf; for (inf = 0; inf < 79; inf++){ if (infix[inf] == '\0'){ infix[inf] = ')'; infix[inf+1] = '\0'; break; } } //begin conversion inf = 0; int post = 0; //while stack isnt empty while (!isEmpty(stack) && inf < 80){ //look at next character in postfix char c = infix[inf]; //check if operator if (isOperator(c)){ //character is an operator if (isOperator(c) == 5){ /* operator is right bracket so pop all operators * from stack onto postfix until hit left bracket */ while (isOperator(stackTop(stack)) != 4){ postfix[post++] = pop(&stack); } //finally pop the left bracket pop(&stack); inf++; } else if (precedence(stackTop(stack), c) >= 0 && isOperator(stackTop(stack)) != 4){ /* operator on stack is higher/equal precedence, * have to pop it */ postfix[post++] = pop(&stack); } else { /* character is operator of lower precedence (or * is left bracket), so push onto stack */ push(&stack, c); inf++; } } else { //character is a digit, so put onto postfix postfix[post++] = c; inf++; } } }
char* Calculator::infixToPostfix(const char *infix) { // TODO: uses the stack to convert an input string (including parentheses) from infix // notation to postfix notation. If the input string does not contain balanced parentheses, // or if it contains invalid characters, throw a custom exception and stop. Stack<char> stackOfChars; if (checkDelimiters(infix) == false) { // std::cerr << "Throw a custom exception and stop" << std::endl; throw(UnbalancedParentheses()); return nullptr; } if (checkValidChars(infix) == false) { // std::cerr << "Throw a custom exception and stop" << std::endl; throw(InvalidCharacter()); return nullptr; } std::string postfix = ""; for (unsigned int i = 0; i < strlen(infix); i++) { char chr = infix[i]; if (isdigit(chr) || chr == '.') // add chr to end of the postfix expression postfix = postfix + chr; else if (chr == '(') stackOfChars.push(chr); else if (isOperator(chr)) { while (!stackOfChars.isEmpty() && (weight(stackOfChars.top()) >= weight(chr))) // Consider the precedence utilizing weight { char c = stackOfChars.top(); stackOfChars.pop(); postfix = postfix + " "; postfix = postfix + c; } postfix = postfix + " "; stackOfChars.push(chr); } else if (chr == ')') { while (!stackOfChars.isEmpty() && stackOfChars.top() != '(') { char c = stackOfChars.top(); stackOfChars.pop(); postfix = postfix + " "; postfix = postfix + c; } if (stackOfChars.top() == '(') stackOfChars.pop(); } else if (chr == '(') { char c = stackOfChars.top(); stackOfChars.pop(); } } while (!stackOfChars.isEmpty()) { char c = stackOfChars.top(); stackOfChars.pop(); postfix = postfix + " "; postfix = postfix + c; } // Steps to return the newly made Postfix char *ptrToPostFix = new char[postfix.size() + 1]; strcpy_s(ptrToPostFix, postfix.size() + 1, postfix.c_str()); // Or std::strcpy(ptrToPostFix, postfix.c_str()) if you disable deprecation settings return ptrToPostFix; }
double Calculator::evaluatePostfix(const char * postfix) { // TODO: uses the stack to evaluate an input string in postfix notation. // If a divide-by-zero error occurs, throw a custom exception and stop. postfix = infixToPostfix(postfix); Stack<double> stackOfDoubles; for (unsigned int i = 0; i < strlen(postfix); i++) // Unsigned int to avoid mismatch { char token = postfix[i]; if (isdigit(token)) { double operand = 0; double convert = 0; int countHowManyDecPlaces = 0; bool isDecimal = false; // FLAG while (i < strlen(postfix) && (isdigit(postfix[i]) || postfix[i] == '.')) { // if it's a decimal if (postfix[i] == '.') { i++; isDecimal = true; continue; } else { operand *= 10; convert = postfix[i] - '0'; operand = operand + convert; i++; if (isDecimal) { countHowManyDecPlaces++; } } } if (countHowManyDecPlaces != 0) // Handling of decimal inputs { // 1 decimal place if (countHowManyDecPlaces == 1) operand = operand / 10; // 2 decimal places if (countHowManyDecPlaces == 2) operand = operand / 100; // 3 decimal places if (countHowManyDecPlaces == 3) operand = operand / 1000; // 4 decimal places if (countHowManyDecPlaces == 4) operand = operand / 10000; // 5 decimal places if (countHowManyDecPlaces == 5) operand = operand / 100000; } i--; // Decrement i inorder to stay return back to track stackOfDoubles.push(operand); } else if (isOperator(token)) { double operand2 = stackOfDoubles.top(); stackOfDoubles.pop(); // Get two operands to prepare for calculator functions double operand1 = stackOfDoubles.top(); stackOfDoubles.pop(); if (operand2 == 0 && (postfix[i] == '/' || postfix[i] == '%')) { throw DivideByZero(); return 0; } if (token == '+') // Perform the operation: operand1 chr operand2 stackOfDoubles.push(operand1 + operand2); if (token == '-') // Perform the operation: operand1 chr operand2 stackOfDoubles.push(operand1 - operand2); if (token == '*') // Perform the operation: operand1 chr operand2 stackOfDoubles.push(operand1 * operand2); if (token == '/') // Perform the operation: operand1 chr operand2 stackOfDoubles.push(operand1 / operand2); } } double answer; answer = stackOfDoubles.top(); return answer; }
short SlkToken::getOperatorTokenValue(void)const { const char* pOperator=mCurToken; const char* pLastToken=mLastToken; int lastIsOperator=TRUE; if(pLastToken && pLastToken[0]) { if(isDelimiter(pLastToken[0])) { lastIsOperator=TRUE; } else { lastIsOperator=isOperator(pLastToken[0]); } } short val=OP_TOKEN_0_; if(pOperator && pOperator[0]) { if((pOperator[0]=='?' || pOperator[0]==':') && pOperator[1]=='\0') { val=OP_TOKEN_1_; } else if(pOperator[0]=='|' && pOperator[1]=='|') { val=OP_TOKEN_2_; } else if(pOperator[0]=='&' && pOperator[1]=='&') { val=OP_TOKEN_3_; } else if(pOperator[0]=='|' && pOperator[1]=='\0') { val=OP_TOKEN_4_; } else if(pOperator[0]=='^' && pOperator[1]=='\0') { val=OP_TOKEN_5_; } else if(pOperator[0]=='&' && pOperator[1]=='\0') { val=OP_TOKEN_6_; } else if((pOperator[0]=='=' || pOperator[0]=='!') && pOperator[1]=='=') { val=OP_TOKEN_7_; } else if((pOperator[0]=='<' || pOperator[0]=='>') && (pOperator[1]=='=' || pOperator[1]=='\0')) { val=OP_TOKEN_8_; } else if((pOperator[0]=='<' && pOperator[1]=='<') || (pOperator[0]=='>' && pOperator[1]=='>') || (pOperator[0]=='>' && pOperator[1]=='>' && pOperator[2]=='>')) { val=OP_TOKEN_9_; } else if((pOperator[0]=='+' || pOperator[0]=='-') && pOperator[1]=='\0') { if(lastIsOperator) val=OP_TOKEN_12_; else val=OP_TOKEN_10_; } else if((pOperator[0]=='*' || pOperator[0]=='/' || pOperator[0]=='%') && pOperator[1]=='\0') { val=OP_TOKEN_11_; } else if((pOperator[0]=='+' && pOperator[1]=='+') || (pOperator[0]=='-' && pOperator[1]=='-') || (pOperator[0]=='~' && pOperator[1]=='\0') || (pOperator[0]=='!' && pOperator[1]=='\0')) { val=OP_TOKEN_12_; } else { val=OP_TOKEN_0_; } } return val; }
short SlkToken::get(void) { if(NULL==mSource || NULL==mErrorAndStringBuffer) { return END_OF_SLK_INPUT_; } newToken(); for(;;) { if(*mIterator=='\0') { if(isCanFinish()) { endTokenWithEof(); return END_OF_SLK_INPUT_; } else { if(!mIterator.Load()) { endTokenWithEof(); return END_OF_SLK_INPUT_; } } } int isSkip=TRUE; //跳过注释与白空格 for(;isSkip && *mIterator!='\0';) { isSkip=FALSE; for(;isWhiteSpace(*mIterator);++mIterator) { if(*mIterator=='\n')++mLineNumber; isSkip=TRUE; } //#引导的单行注释 if(*mIterator=='#') { for(;*mIterator!='\0' && *mIterator!='\n';++mIterator); isSkip=TRUE; } //C++风格的单行注释与多行注释 if(*mIterator=='/' && (*(mIterator+1)=='/' || *(mIterator+1)=='*')) { ++mIterator; if(*mIterator=='/') { ++mIterator; for(;*mIterator!='\0' && *mIterator!='\n';++mIterator); isSkip=TRUE; } else if(*mIterator=='*') { ++mIterator; for(;;) { if(*mIterator!='\0') { if(*mIterator=='\n')++mLineNumber; if(*mIterator=='*' && *(mIterator+1)=='/') { ++mIterator; ++mIterator; break; } } else { if(mIterator.Load()) { continue; } else { endTokenWithEof(); return END_OF_SLK_INPUT_; } } ++mIterator; } isSkip=TRUE; } } } if(*mIterator!='\0') break; } if(isCanFinish()) setCanFinish(FALSE); if(*mIterator=='{' && *(mIterator+1)==':') { ++mIterator; ++mIterator; int line=mLineNumber; //搜索脚本结束 :} for(;*mIterator!='\0';) { while(*mIterator!='\0' && *mIterator!=':') { if(*mIterator=='\n')++mLineNumber; pushTokenChar(*mIterator); ++mIterator; } if(*mIterator=='\0') break; IScriptSource::Iterator next=mIterator+1; if(*next=='}') { ++mIterator; ++mIterator; break; } else { pushTokenChar(*mIterator); ++mIterator; } } if(*mIterator=='\0') { char* pInfo=mErrorAndStringBuffer->NewErrorInfo(); if(pInfo) tsnprintf(pInfo,MAX_ERROR_INFO_CAPACITY,"[line %d ]:ExternScript can't finish!",line); } endToken(); return SCRIPT_CONTENT_; } else if(isOperator(*mIterator))//操作符 { getOperatorToken(); return getOperatorTokenValue(); } else if(*mIterator=='.' && 0==myisdigit(*(mIterator+1),FALSE)) { char c=*mIterator; ++mIterator; pushTokenChar(c); endToken(); return DOT_; } else if(isDelimiter(*mIterator))//分隔符 { char c=*mIterator; ++mIterator; pushTokenChar(c); endToken(); switch(c) { case '(': return LPAREN_; case ')': return RPAREN_; case '[': return LBRACK_; case ']': return RBRACK_; case '{': return LBRACE_; case '}': return RBRACE_; case ',': return COMMA_; case ';': return SEMI_; default: return END_OF_SLK_INPUT_; } } else//关键字、标识符或常数 { if(*mIterator=='"' || *mIterator=='\'')//引号括起来的名称或关键字 { int line=mLineNumber; char c=*mIterator; for(++mIterator;*mIterator!='\0' && *mIterator!=c;) { if(*mIterator=='\n')++mLineNumber; if(*mIterator=='\\') { //pushTokenChar(*mIterator); ++mIterator; } pushTokenChar(*mIterator); ++mIterator; if(*mIterator=='\0') { if(mIterator.Load()) { continue; } else { char* pInfo=mErrorAndStringBuffer->NewErrorInfo(); if(pInfo) tsnprintf(pInfo,MAX_ERROR_INFO_CAPACITY,"[line %d ]:String can't finish!",line); endTokenWithEof(); return END_OF_SLK_INPUT_; } } } if(*mIterator!='\0') { ++mIterator; } else { char* pInfo=mErrorAndStringBuffer->NewErrorInfo(); if(pInfo) tsnprintf(pInfo,MAX_ERROR_INFO_CAPACITY,"[line %d ]:String can't finish!",line); } endToken(); return STRING_; } else { int isNum=TRUE; int isHex=FALSE; if(*mIterator=='0' && *(mIterator+1)=='x') { isHex=TRUE; pushTokenChar(*mIterator); ++mIterator; pushTokenChar(*mIterator); ++mIterator; } for(;*mIterator!='\0' && !isDelimiter(*mIterator) && !isWhiteSpace(*mIterator) && !isOperator(*mIterator);++mIterator) { if(*mIterator=='#') break; else if(*mIterator=='/') { IScriptSource::Iterator next=mIterator+1; if(*next!='\0' && (*next=='/' || *next=='*')) { break; } } else if(*mIterator=='.') { if(!isNum) { break; } else { IScriptSource::Iterator next=mIterator+1; if(0==myisdigit(*next,isHex)) { break; } } } else if(0==myisdigit(*mIterator,isHex)) { isNum=FALSE; } pushTokenChar(*mIterator); } endToken(); if(isNum) return NUMBER_; else return IDENTIFIER_; } } }
int isSymbol(char x){ if((isOperator(x)==0)&&x!='('&&x!=')'){ return 1; } return 0; }
_EXPORT void ColorLine(CLanguageProxy& proxy, int& state) { const char *text = proxy.Text(); int size = proxy.Size(); int i = 0, s = 0, kws = 0, cc_cnt = 0, esc = 0; char c; bool leave = false; // floating point flag, true when the NUMERIC: label finds a . inside a number, and checks to make sure that a number with two '.' is invalid. (and not highlighted as numeric) bool floating_point = false; // same flag, only for hex numbers. allows proper highlighting only for 1 x per number. (0x21 is ok. 0x023x31 is not. will look wierd.) bool hex_num = false; int ifZeroCounter = state >> STATE_SHIFT; state = state & STATE_MASK; if (state == COMMENT || state == LCOMMENT) proxy.SetColor(0, kColorComment1); else proxy.SetColor(0, kColorText); if (size <= 0) return; while (!leave) { GETCHAR; switch (state) { case START: s = i - 1; proxy.SetColor(s, kColorText); if (c == '#') { kws = proxy.Move(c, 1); state = PRAGMA1; } else if (isalpha(c) || c == '_') { kws = proxy.Move(c, 1); state = IDENT; } else if (c == '/' && text[i] == '*') { i++; state = COMMENT; } else if (c == '/' && text[i] == '/') { i++; state = LCOMMENT; } else if (c == '"') state = STRING; else if (c == '\'') { state = CHAR_CONST; cc_cnt = 0; } // m7m: here are the 3 magic IFs. else if (isNumeric(c)) { state = NUMERIC; } else if (isOperator(c)) { state = OPERATOR; } else if (isSymbol(c)) { state = SYMBOL; } else if (c == '\n' || c == 0) leave = true; break; case COMMENT: if ((s == 0 || i > s + 1) && c == '*' && text[i] == '/') { proxy.SetColor(s, kColorComment1); i++; state = START; } else if (c == 0 || c == '\n') { proxy.SetColor(s, kColorComment1); leave = true; } break; case LCOMMENT: proxy.SetColor(s, kColorComment1); leave = true; if (text[size - 1] == '\n') state = START; break; case IDENT: if (!isalnum(c) && c != '_') { int kwc; if (i > s + 1 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; // default: ASSERT(false); } } else proxy.SetColor(s, kColorText); i--; state = START; } else if (kws) kws = proxy.Move((int)(unsigned char)c, kws); break; case PRAGMA1: if (c == ' ' || c == '\t') ; else if (islower(c)) { kws = proxy.Move((int)(unsigned char)c, kws); state = PRAGMA2; } else { proxy.SetColor(s, kColorText); i--; state = START; } break; case PRAGMA2: if (!islower(c)) { int kwc; if (i > s + 2 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; // default: ASSERT(false); } // check for "#if 0" or "elif 0" bool ifZero = false; int k = s + 1; while (text[k] == ' ' || text[k] == '\t') k++; int len = i - 1 - k; if (strings_equal(text + k, "if", len, 2) || strings_equal(text + k, "elif", len, 4)) { k = i - 1; while (text[k] == ' ' || text[k] == '\t') k++; if (text[k] == '0' && (k + 1 == size || text[k + 1] == 0 || isspace(text[k + 1]))) { proxy.SetColor(s, kColorComment1); state = IF_ZERO; ifZeroCounter = 1; leave = true; } } } else { proxy.SetColor(s, kColorText); } if (state != IF_ZERO) { state = strncmp(text+i-8, "include", 7) ? START : INCL1; s = --i; } } else if (kws) kws = proxy.Move((int)(unsigned char)c, kws); break; case INCL1: if (c == '"') state = INCL2; else if (c == '<') state = INCL3; else if (c != ' ' && c != '\t') { state = START; i--; } break; case INCL2: if (c == '"') { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { proxy.SetColor(s, kColorText); leave = true; state = START; } break; case INCL3: if (c == '>') { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { proxy.SetColor(s, kColorText); leave = true; state = START; } break; case STRING: if (c == '"' && !esc) { proxy.SetColor(s, kColorString1); state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } leave = true; } else esc = !esc && (c == '\\'); break; case CHAR_CONST: if (c == '\t' || c == '\n' || c == 0 || (c == '\'' && !esc && (cc_cnt == 0 || cc_cnt > 5))) { // invalid char constant - either invalid char or too short/long proxy.SetColor(s, kColorText); state = START; } else if (c == '\'' && !esc) { proxy.SetColor(s, kColorCharConst); state = START; } else { if (!esc) cc_cnt++; esc = !esc && (c == '\\'); } break; case NUMERIC: { proxy.SetColor(s, kColorNumber1); if (isNumeric(text[i-1]) || (hex_num && isHexNum(text[i - 1]))) ; else if (text[i-1]=='.' && floating_point==false && hex_num==false) floating_point = true; else if (text[i-1]=='x' && hex_num==false && floating_point==false) hex_num = true; else { i--; hex_num = false; state = START; } } break; case OPERATOR: { proxy.SetColor(s, kColorOperator1); if (isOperator(text[i-1])) ; else { i--; state = START; } } break; case SYMBOL: { proxy.SetColor(s, kColorSeparator1); if (isSymbol(text[i-1])) ; else { i--; state = START; } } break; case IF_ZERO: { if (isspace(c)) break; proxy.SetColor(i - 1, kColorComment1); if (c == '#') { // get the preprocessor keyword while (isspace(GETCHAR)); int s = i - 1; int end = s; while (end < size && text[end] != 0 && !isspace(text[end])) end++; int len = end - s; // on "#if", "#ifdef", "#ifndef" increment the nesting // counter if (strings_equal(text + s, "if", len, 2) || strings_equal(text + s, "ifdef", len, 5) || strings_equal(text + s, "ifndef", len, 6)) { ifZeroCounter++; i = end + 1; } // on "endif" decrement the nesting counter else if (strings_equal(text + s, "endif", len, 5)) { ifZeroCounter--; i = end + 1; // if the counter drops to zero, we fall be to normal // parsing if (ifZeroCounter == 0) { state = START; leave = true; break; } } // on "else" or "elif" and nest count 1, fall back to normal // parsing: else if (ifZeroCounter == 1 && (strings_equal(text + s, "else", len, 4) || strings_equal(text + s, "elif", len, 4))) { i = end + 1; ifZeroCounter == 0; state = START; leave = true; break; } } // we need to check for C style comments int commentOffset; if (find_comment_start(text + i - 1, size - i + 1, commentOffset)) { state = IF_ZERO_COMMENT; i += commentOffset + 1; } else leave = true; } break; case IF_ZERO_COMMENT: { proxy.SetColor(i - 1, kColorComment1); int commentEnd; if (find_comment_end(text + i - 1, size - i + 1, commentEnd)) { i += commentEnd + 1; state = IF_ZERO; } else leave = true; } break; default: // error condition, gracefully leave the loop leave = true; break; } } state |= ifZeroCounter << STATE_SHIFT; } /* ColorLine */
_EXPORT void ColorLine(CLanguageProxy& proxy, int32& state) { const char *text = proxy.Text(); int32 size = proxy.Size(); int32 i = 0, s = 0, kws = 0, esc = 0; char c; bool leave = false; bool floating_point = false; bool hex_num = false; // int sqrBraquetStrCount = 0; if (state == LCOMMENT) proxy.SetColor(0, kColorComment1); else proxy.SetColor(0, kColorText); if (size <= 0) return; while (!leave) { GETCHAR; switch (state) { case START: if (isalpha(c) || c == '_') { kws = proxy.Move(tolower(c), 1); state = IDENT; } else if (c == '-' && text[i] == '-') { i++; state = LCOMMENT; } else if (c == '"') state = STRING; else if (c == '\'') state = STRING2; /* else if (c == '[' && text[i] == '[') { sqrBraquetStrCount++; state = STRING3; } */ else if (isNumeric(c) || (c == '$' && isHexNum(text[i]))) { state = NUMERIC; } else if (isOperator(c)) { state = OPERATOR; } else if (isSymbol(c)) { state = SYMBOL; } else if (c == '\n' || c == 0) leave = true; if (leave || (state != START && s < i)) { proxy.SetColor(s, kColorText); s = i - 1; } break; // -- format comments case LCOMMENT: proxy.SetColor(s - 1, kColorComment1); leave = true; if (text[size - 1] == '\n') state = START; break; case IDENT: if (!isalnum(c) && c != '_') { int32 kwc; if (i > s + 1 && (kwc = proxy.IsKeyword(kws)) != 0) { switch (kwc) { case 1: proxy.SetColor(s, kColorKeyword1); break; case 2: proxy.SetColor(s, kColorUserSet1); break; case 3: proxy.SetColor(s, kColorUserSet2); break; case 4: proxy.SetColor(s, kColorUserSet3); break; case 5: proxy.SetColor(s, kColorUserSet4); break; } s = --i; state = START; } else { proxy.SetColor(s, kColorText); s = --i; state = START; } } else if (kws) kws = proxy.Move((int)(unsigned char) c, kws); break; case STRING: if (c == '"' && !esc) { proxy.SetColor(s, kColorString1); s = i; state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } s = size; leave = true; } else esc = !esc && (c == '\\'); break; case STRING2: if (c == '\'' && !esc) { proxy.SetColor(s, kColorString1); s = i; state = START; } else if (c == '\n' || c == 0) { if (text[i - 2] == '\\' && text[i - 3] != '\\') { proxy.SetColor(s, kColorString1); } else { proxy.SetColor(s, kColorText); state = START; } s = size; leave = true; } else esc = !esc && (c == '\\'); break; /* case STRING3: break; */ case NUMERIC: proxy.SetColor(s, kColorNumber1); if (isNumeric(text[i - 1]) || (hex_num && isHexNum(text[i - 1]))) ; else if (text[i - 1] == '.' && floating_point == false) floating_point = true; else if (isHexNum(text[i - 1]) && hex_num == false) hex_num = true; else { s = i - 1; i--; state = START; } break; case OPERATOR: proxy.SetColor(s, kColorOperator1); if (isOperator(text[i - 1])) ; else { s = i - 1; i--; state = START; } break; case SYMBOL: proxy.SetColor(s, kColorSeparator1); if (isSymbol(text[i - 1])) ; else { s = i - 1; i--; state = START; } break; default: leave = true; break; } } }
command_stream_t make_command_stream (int (*get_next_byte) (void *), void *get_next_byte_argument) { //create a command stream struct command_stream_t stream = (command_stream_t)checked_malloc(sizeof(struct command_stream)); struct node* head; struct node* current; current = (struct node *)checked_malloc(sizeof(struct node)); head = current; int current_byte; char* str = (char*)checked_malloc(sizeof(char)); int wordSize=0; char current_char; int line = 1; int foundComment = 0; while((current_byte = get_next_byte(get_next_byte_argument))!= EOF){ current_char = current_byte; if(current_char == '#') { foundComment = 1; continue; } if(isOperator(current_char)) { if(!(str[0]=='\0')) { current = saveToNode(str, current, OPERATOR, wordSize); str[0]='\0'; memset(str,0,strlen(str)); wordSize = 0; } wordSize++; str = (char*)realloc(str,wordSize*sizeof(char)); str[wordSize-1] = current_byte; current = saveToNode(str, current, OPERATOR, wordSize); str[0]='\0'; memset(str,0,strlen(str)); wordSize=0; continue; } if(isalphaNum(current_char) || current_char==' ') { if(foundComment) { continue; } wordSize++; str = (char*)realloc(str,wordSize*sizeof(char)); str[wordSize-1] = current_byte; } if((strncmp(str,"if",2)==0) || (strncmp(str,"while",5)==0) || (strncmp(str,"until",2)==0) || (strncmp(str,"else",4)==0) || (strncmp(str,"done",4)==0)) { current = saveToNode(str, current, COMPOUND, wordSize); str[0]='\0'; memset(str,0,strlen(str)); wordSize = 0; continue; } if(current_char=='\n' || current_char==';') { if(foundComment) { foundComment = 0; continue; } if(!(str[0]=='\0')) { current = saveToNode(str, current, COMMAND, wordSize); str[0]='\0'; memset(str,0,strlen(str)); wordSize = 0; } wordSize++; current = saveToNode(str, current, NEWLINE_SEMICOLON, wordSize); str[0]='\0'; memset(str,0,strlen(str)); wordSize = 0; continue; } } current = head; command_node* c_node = checked_malloc(sizeof(struct command_node)); stream->commands = checked_malloc(sizeof(struct command_node)); while(current->next != NULL) { printf("Node: "); printf(current->word); printf(", Operator: "); printf("%i", current->flag); printf("\n"); current = current->next; } return *stream; }
void convertToPostfix( char infix[], char postfix[] ){ StackNodePtr head = (StackNodePtr)malloc(Node_Size); //allocate memory for first node head->nextPtr=NULL; //the bottom node of stack always has nextPtr=NULL head->data='\0'; //the bottom node of stack always has data='\0' (escape character) int inputLen; push(&head,'('); //push a left parenthesis onto stack for(int i = 0; i<MAXSIZE; i++){ //this loop adds the right parenthesis to the infix string if(infix[i]=='\0'){ infix[i]=')'; infix[i+1]='\0'; inputLen = i; break; } } int nextInPostfix = 0; //used to keep track of next available character in the postfix (output string) for(int i = 0; i<inputLen+1; i++){ //go through all of the input characters and process them ( plus one (the escape character)) if(isOperator(infix[i])){ //if current input char is an operator while(isOperator(stackTop(head))){ //run this loop while the top item in the stack is an operator (except if broken) if(precedence(stackTop(head),infix[i])>=0){ //pop stack to postfix if the top stack operator is of higher precedence than the current input operator char toPostfix = pop(&head); printStack(head); postfix[nextInPostfix++] = toPostfix; //uses ++ after variable name to increment so it doesn't get overwritten } else break; //stops the loop running on the same character forever if the precedence is lesser } push(&head,infix[i]); //push the current operator onto the stack for future use printStack(head); } else if(infix[i]=='('){ //if current input char is ( then push it onto the stack push(&head, '('); printStack(head); } else if(infix[i]==')'){ //if current input char is ) if(isOperator(stackTop(head))){ //if the top of the stack is an operator while(stackTop(head)!='('){ //pop off stack into postfix output until top of the stack is a left parenthesis char toPostfix = pop(&head); printStack(head); postfix[nextInPostfix++] = toPostfix; } pop(&head); //pop off the extraneous parenthesis if(!isEmpty(head)) printStack(head); } } else { //if the input character is just a number then add it to postfix postfix[nextInPostfix++] = infix[i]; } if(isEmpty(head)) { printf("The stack is empty.\n"); postfix[nextInPostfix++] = '\0'; //adds end to postfix string so it prints correctly when compiled on ECS machines return; } } }