/* * Internal buffer looks like this. * num[0] op[0] num[1] op[1] num[2] * If priority of op[0] is higher than op[1], (num[0] op[0] num[1]) is computed, * otherwise (num[1] op[1] num[2]) is computed. * Then, the next op and num is read from the script. * Num is an immediate value, a variable or a bracketed expression. */ void ScriptHandler::readNextOp(const char** buf, int* op, int* num) { bool minus_flag = false; SKIP_SPACE(*buf); const char* buf_start = *buf; if (op) { if ((*buf)[0] == '+') *op = OP_PLUS; else if ((*buf)[0] == '-') *op = OP_MINUS; else if ((*buf)[0] == '*') *op = OP_MULT; else if ((*buf)[0] == '/') *op = OP_DIV; else if ((*buf)[0] == 'm' && (*buf)[1] == 'o' && (*buf)[2] == 'd' && ((*buf)[3] == ' ' || (*buf)[3] == '\t' || (*buf)[3] == '$' || (*buf)[3] == '%' || (*buf)[3] == '?' || ((*buf)[3] >= '0' && (*buf)[3] <= '9'))) *op = OP_MOD; else { *op = OP_INVALID; return; } if (*op == OP_MOD) *buf += 3; else (*buf)++; SKIP_SPACE(*buf); } else { if ((*buf)[0] == '-') { minus_flag = true; (*buf)++; SKIP_SPACE(*buf); } } if ((*buf)[0] == '(') { (*buf)++; *num = parseIntExpression(buf); if (minus_flag) *num = -*num; SKIP_SPACE(*buf); if ((*buf)[0] != ')') errorAndExit(") is not found."); (*buf)++; } else { *num = parseInt(buf); if (minus_flag) *num = -*num; if (current_variable.type == VAR_NONE) { if (op) *op = OP_INVALID; *buf = buf_start; } } }
int ScriptHandler::readInt() { string_buffer.trunc(0); end_status = END_NONE; current_variable.type = VAR_NONE; current_script = next_script; SKIP_SPACE(current_script); const char* buf = current_script; int ret = parseIntExpression(&buf); next_script = checkComma(buf); return ret; }
int StereotypeDefinitionParser::parseIntExpression() { Token token; token = d->m_scanner->read(); if (token.type() == Token::TokenOperator && token.subtype() == OPERATOR_MINUS) { return -parseIntExpression(); } else { bool ok = false; if (token.type() == Token::TokenInteger) { int value = token.text().toInt(&ok); QMT_CHECK(ok); return value; } else { throw StereotypeDefinitionParserError(QStringLiteral("Expected integer constant."), token.sourcePos()); } } }
ScriptHandler::array_ref ScriptHandler::parseArray(const char** buf) { SKIP_SPACE(*buf); (*buf)++; // skip '?' int no = parseInt(buf); SKIP_SPACE(*buf); h_index_t indices; while (**buf == '[') { (*buf)++; indices.push_back(parseIntExpression(buf)); SKIP_SPACE(*buf); if (**buf != ']') errorAndExit("parseArray: no ']' is found."); (*buf)++; } return std::make_pair(no, indices); }
int ScriptHandler::parseArray( char **buf, struct ArrayVariable &array ) { SKIP_SPACE( *buf ); (*buf)++; // skip '?' int no = parseInt( buf ); SKIP_SPACE( *buf ); array.num_dim = 0; while ( **buf == '[' ){ (*buf)++; array.dim[array.num_dim] = parseIntExpression(buf); array.num_dim++; SKIP_SPACE( *buf ); if ( **buf != ']' ) errorAndExit( "parseArray: missing ']'." ); (*buf)++; } for ( int i=array.num_dim ; i<20 ; i++ ) array.dim[i] = 0; return no; }
int StereotypeDefinitionParser::parseIntProperty() { expectColon(); return parseIntExpression(); }