Fragment * Parser::nt_curly_block(Fragment *preceding, int depth) { logtrace << depth << ") nt_curly_block: begin."; Token& tok = next_token(); assert( matchSymbol('{') ); pushExpectedSymbol("}"); Fragment *block = new Fragment(Fragment::Kind::block); block->push_token(&tok); block->set_previous_fragment( preceding ); if (preceding != nullptr) preceding->set_next_fragment( block ); while(true) { nt_whatever(block, depth+1); tok = next_token(); if (tok.is_symbol('}')) { logdebug << depth << ") nt_curly_block: matched expected '}' symbol" "– end-of-block – ok, returning to caller."; break; } } logtrace << depth << ") nt_curly_block: end."; return block; }
bool ArmParser::parseThumbParameters(Parser& parser, const tThumbOpcode& opcode, ThumbOpcodeVariables& vars) { const u8* encoding = (const u8*) opcode.mask; ArmRegisterValue tempRegister; int value; while (*encoding != 0) { bool optional = *encoding == '/'; if (optional) encoding++; switch (*encoding++) { case 'd': // register CHECK(parseRegister(parser,vars.rd,7)); break; case 's': // register CHECK(parseRegister(parser,vars.rs,7)); break; case 'n': // register CHECK(parseRegister(parser,vars.rn,7)); break; case 'o': // register CHECK(parseRegister(parser,vars.ro,7)); break; case 'D': // register CHECK(parseRegister(parser,vars.rd,15)); break; case 'S': // register CHECK(parseRegister(parser,vars.rs,15)); break; case 'r': // forced register CHECK(parseRegister(parser,tempRegister,15)); CHECK(*encoding++ == tempRegister.num); break; case 'R': // register list value = encoding[0] | (encoding[1] << 8); CHECK(parseRegisterList(parser,vars.rlist,value)); encoding += 2; break; case 'I': // immediate case 'i': CHECK(parseImmediate(parser,vars.ImmediateExpression)); vars.ImmediateBitLen = *encoding++; break; default: CHECK(matchSymbol(parser,*(encoding-1),optional)); break; } } // the next token has to be an identifier, else the parameters aren't // completely parsed return parser.atEnd() || parser.peekToken().type == TokenType::Identifier; }
bool ArmParser::parseArmParameters(Parser& parser, const tArmOpcode& opcode, ArmOpcodeVariables& vars) { const u8* encoding = (const u8*) opcode.mask; ArmRegisterValue tempRegister; vars.Shift.UseShift = false; vars.Shift.UseFinal = false; vars.psr = false; vars.writeback = false; vars.SignPlus = false; vars.Opcode.UseNewEncoding = false; vars.Opcode.UseNewType = false; while (*encoding != 0) { bool optional = *encoding == '/'; if (optional) encoding++; switch (*encoding++) { case 'd': // register CHECK(parseRegister(parser,vars.rd,*encoding++ == '1' ? 14 : 15)); break; case 's': // register CHECK(parseRegister(parser,vars.rs,*encoding++ == '1' ? 14 : 15)); break; case 'n': // register CHECK(parseRegister(parser,vars.rn,*encoding++ == '1' ? 14 : 15)); break; case 'm': // register CHECK(parseRegister(parser,vars.rm,*encoding++ == '1' ? 14 : 15)); break; case 'D': // cop register CHECK(parseCopRegister(parser,vars.CopData.cd)); break; case 'N': // cop register CHECK(parseCopRegister(parser,vars.CopData.cn)); break; case 'M': // cop register CHECK(parseCopRegister(parser,vars.CopData.cm)); break; case 'W': // writeback parseWriteback(parser,vars.writeback); break; case 'p': // psr parsePsr(parser,vars.psr); break; case 'P': // msr/mrs psr data CHECK(parsePsrTransfer(parser,vars,*encoding++ == '1')); break; case 'R': // register list CHECK(parseRegisterList(parser,vars.rlist,0xFFFF)); break; case 'S': // shift CHECK(parseShift(parser,vars,*encoding++ == '1')); break; case 'I': // immediate case 'i': CHECK(parseImmediate(parser,vars.ImmediateExpression)); vars.ImmediateBitLen = 32; break; case 'j': // variable bit immediate CHECK(parseImmediate(parser,vars.ImmediateExpression)); vars.ImmediateBitLen = *encoding++; break; case 'X': // cop number CHECK(parseCopNumber(parser,vars.CopData.pn)); break; case 'Y': // cop opcode number CHECK(parseImmediate(parser,vars.CopData.CpopExpression)); vars.ImmediateBitLen = 4; break; case 'Z': // cop info number CHECK(parseImmediate(parser,vars.CopData.CpinfExpression)); vars.ImmediateBitLen = 3; break; case 'z': // shift for pseudo opcodes CHECK(parsePseudoShift(parser,vars,*encoding++)); break; case 'v': // sign for register index parameter parseSign(parser,vars.SignPlus); break; default: CHECK(matchSymbol(parser,*(encoding-1),optional)); break; } } // the next token has to be an identifier, else the parameters aren't // completely parsed return parser.atEnd() || parser.peekToken().type == TokenType::Identifier; }