void IRCSession::makepolishform(string szam) { string s = szam; q = TokenQueue(); sk = TokenStack(); CalcLexer cl = CalcLexer(s); Token t; do { if(t.tkntype == TKN_NEXT_LINE) cl = CalcLexer(s); t = cl.getNextToken(); if(t.tkntype == TKN_NUMBER || t.tkntype == TKN_NAME) q.put(t); else if(t.tkntype == TKN_OPEN_PAR) sk.put(t); else if(t.tkntype == TKN_CLOSE_PAR) { Token t1; while(!sk.empty() && sk.seek().tkntype != TKN_OPEN_PAR) q.put(sk.get()); sk.get(); } else if(t.tkntype == TKN_OPERATOR) { while(!sk.empty() && getpriority(sk.seek()) <= getpriority(t)) q.put(sk.get()); sk.put(t); } } while(t.tkntype != TKN_TERMINATION); while(!sk.empty()) q.put(sk.get()); }
void gen_aux (const Grammar &g, const std::string &start, std::vector<std::string> &result) { TokenStack lifo; expand_aux (g, start, lifo); while (!lifo.empty()) { const std::string curr_word = lifo.top(); lifo.pop(); if (!bracketed (curr_word)) { result.push_back (curr_word); } else { expand_aux (g, curr_word, lifo); } } }
void IRCSession::calculate(string privmsg) { sk = TokenStack(); while(!q.empty()) { Token t = q.get(); if(t.tkntype == TKN_NUMBER || t.tkntype == TKN_NAME) sk.put(t); else if(t.tkntype == TKN_OPERATOR) { if(t.str == "+") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, o1.number+o2.number, ""); sk.put(e); } else if(t.str == "-") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, o1.number-o2.number, ""); sk.put(e); } else if(t.str == "*") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, o1.number*o2.number, ""); sk.put(e); } else if(t.str == "/") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, o1.number/o2.number, ""); sk.put(e); } else if(t.str == "%") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, cast_int(o1.number)%cast_int(o2.number), ""); sk.put(e); } else if(t.str == "^" || t.str == "**") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, pow(o1.number, o2.number), ""); sk.put(e); } /*else if(t.str == "sin") { Token o1, o2; if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o2 = getValue(sk.get()); if(!sk.empty() && (sk.seek().tkntype == TKN_NUMBER || sk.seek().tkntype == TKN_NAME)) o1 = getValue(sk.get()); Token e = Token(TKN_NUMBER, sin(12), ""); sk.put(e); }*/ } } double d; if(!sk.empty()) d = getValue(sk.get()).number; else d = 0.0f; if(d-cast_int(d) < 0.00000049) SendChatMessage(PRIVMSG, privmsg.c_str(), "%d", cast_int(d)); else SendChatMessage(PRIVMSG, privmsg.c_str(), "%f", d); varv.clear(); }
// 逆波兰式计算求值 bool CalcExpr(const TokenVector & input, const TokenVector & expr, Token & result) { TokenStack stack; TokenVector::const_iterator it = expr.begin(); for (; it != expr.end(); ++it) { if (it->type == INT || it->type == FLOAT || it->type == BOOL) { stack.push(*it); } else if (it->type == ARG) { if (it->value.index >= input.size()) return false; const Token & a = input[it->value.index]; if (a.type == INT || a.type == FLOAT || a.type == BOOL) { stack.push(a); } else { return false; } } else if (it->type == RAND) { Token a; a.type = INT; a.value.i = rand(); stack.push(a); } else if (it->type == OP) { if (stack.size() < 2) return false; Token a = stack.top(); stack.pop(); Token b = stack.top(); stack.pop(); Token c; if (GetValue(it->value.op, b, a, c)) { stack.push(c); } else { return false; } } } if (!stack.empty()) { result = stack.top(); return true; } else { return false; } }
// 把解析好的表达式转换成逆波兰式 bool ConvertExpr(const TokenVector & input, TokenVector & output) { TokenStack stack; output.clear(); TokenVector::const_iterator it = input.begin(); for (; it != input.end(); ++it) { if (it->type == OP) { // 左括号,直接压进操作符栈 if (it->value.op == LEFT) { stack.push(*it); } // 右括号,从栈里弹出操作符,直到碰到右括号 else if (it->value.op == RIGHT) { bool find_left = false; while (!stack.empty()) { if (stack.top().value.op == LEFT) { find_left = true; stack.pop(); break; } else { output.push_back(stack.top()); stack.pop(); } } if (!find_left) return false; } // 其它操作符,和栈顶操作符比较优先级 else { while (!stack.empty() && stack.top().value.op != LEFT && OPPriority(stack.top().value.op) >= OPPriority(it->value.op)) { output.push_back(stack.top()); stack.pop(); } stack.push(*it); } } // 非操作符直接输出 else { output.push_back(*it); } } while (!stack.empty()) { output.push_back(stack.top()); stack.pop(); } return true; }
// Process declaration statements. void Parser::procDeclaration() { Token declToken; // Actual token of the declared entity TokenStack varNames; // Names of declared variables bool haveFunction; // Have a function declaration bool insideParams; // Inside parameter list of a function int parenCount; // Count of unmatched parentheses int consParenCount; // Count of consecutive open parantheses declToken = _currToken; if (_buffer.lastLookahead().getType() == Token::openparen) { haveFunction = true; insideParams = true; parenCount = 1; // Burn the paranthese, so not confused with argument declarations _buffer.nextToken(); } else { haveFunction = false; insideParams = false; parenCount = 0; } // Process the rest of the declaration. consParenCount = 0; while (_statementType == declaration) { _currToken = _buffer.nextToken(); // Check for defined symbols if (_currToken.getType() == Token::identifier) _symbolTable.checkForSymbol(_currToken); // Process combined types if (_currToken.getType() == Token::compound) procCombType(); switch (_currToken.getType()) { case Token::identifier: // Burn parenthases around the identifier while ((_buffer.nextLookahead().getType() == Token::closeparen) && (consParenCount > 0)) { _buffer.nextToken(); consParenCount--; } if (_buffer.lastLookahead().getType() == Token::openparen) /* Function call. This terminates a function declaration, and marks the start of the initial value for a variable declaration */ _statementType = expression; else { /* Variable name. For functions, this is a parameter name; for variable declarations, assume multiple vars are being declared in one declaration statement. Note: due to K+R style parameter declarations, function parameter declarations do not need to be whithin parentheses */ _currToken.setType(Token::varname); if (haveFunction || (_braceCount > 0)) _currToken.setScope(Token::localscope); else _currToken.setScope(Token::filescope); varNames.push(_currToken); // Add to variable list /* K+R variable declarations have a trailing semicolon, which must be burned also */ if (haveFunction && (!insideParams) && // K+R style declaration (_buffer.lastLookahead().getType() == Token::semicolon)) _buffer.nextToken(); } break; case Token::openparen: parenCount++; break; case Token::closeparen: parenCount--; if (insideParams && (parenCount <= 0)) insideParams = false; break; case Token::typedeftoken: case Token::statictoken: if (!insideParams) // Modifier on the entire declaration _parseStack.push(_currToken); break; case Token::ampersand: case Token::othersymbol: /* Have reached the initializer list for var declarations; this is an error for function declarations */ if (haveFunction) _statementType = undet; else _statementType = expression; break; case Token::typetoken: case Token::declsymbol: // Ignore it break; case Token::fieldaccess: /* If inside params and have a dot, assume this is part of varags symbol (It is not common enough to have a seperate token for it) */ if ((!insideParams) || (_currToken.getLexeme() != ".")) _statementType = undet; // else part of varargs indicator, so ignore it break; default: // token is not allowed in declarations _statementType = undet; } // Update or clear consecutive parenthese count, as needed if (_currToken.getType() == Token::openparen) consParenCount++; else consParenCount = 0; } // Process the just read declaration if (haveFunction) procFunctDeclaration(declToken, _currToken, insideParams); else { // variable or type declaration // Set token type if (_parseStack.hasType(Token::typedeftoken)) declToken.setType(Token::typetoken); else declToken.setType(Token::varname); // Set its scope if (_braceCount > 0) declToken.setScope(Token::localscope); else declToken.setScope(Token::filescope); _symbolTable.updateNameSpace(declToken); } /* add new variables to the namespace. Ignore the vars in a function declaration unless it is followed by an openbrace, as it is actually a prototype, not a declaration */ if ((declToken.getType() == Token::varname) || (declToken.getType() == Token::functdecl)) while (!varNames.empty()) _symbolTable.updateNameSpace(varNames.pop()); _readNextToken = false; // Need to process token that ended declaration }