rt,悬一关
#include<iostream>
#include<map>
#include<queue>
#include<utility>
#include<cstring>
#include<vector>
#define ll long long
#define N 256
#define pr std::pair<ll,ll>
ll max(ll x,ll y){return x>y?x:y;}
ll min(ll x,ll y){return x<y?x:y;}
pr mp(ll x,ll y){return (pr){x,y};}
ll n,op,k,addr_in;
std::string s,ti,ni,in1[N],in2[N];
struct Type{
std::string name;
std::vector<Type*>mem_type;
std::vector<std::string>mem_name;
ll mem_size,mem_align;
void clear(){
name.clear();
mem_type.clear();
mem_name.clear();
mem_align=mem_size=0;
}
};
Type def_type[N];
ll type_num;
std::map<std::string,Type*>nameMapType;
struct element{
Type element_type;
std::string name;
ll addr;
void clear(){
element_type.clear();
name.clear();
addr=0;
}
};
element def_element[N];
ll element_num;
std::map<std::string,element*>nameMapElement;
ll addrPos;
std::map<pr,element*>addrMapElement;
void init();void work();
void type_create(std::string,ll,std::string*,std::string*);
void element_create(std::string,std::string);
ll vis_element(std::string);
std::string vis_addr(ll);
//
int main(){
init(),work();
}
void type_create(std::string typeName,ll num,std::string *ar1,std::string *ar2){
Type newType;
newType.clear();
newType.name=typeName;
for(int i=1;i<=num;i++){
newType.mem_type.push_back(nameMapType[ar1[i]]);
newType.mem_name.push_back(ar2[i]);
}
ll pos=0;
std::vector<Type*>::iterator it=newType.mem_type.begin();
for(;it!=newType.mem_type.end();it++){
ll align=(*it)->mem_align;
ll size=(*it)->mem_size;
newType.mem_align=std::max(newType.mem_align,align);
if(pos%align)
pos=(pos/align+1)*align;
pos+=size;
}
if(pos%newType.mem_align)
pos=(pos/newType.mem_align+1)*newType.mem_align;
newType.mem_size=pos;
def_type[++type_num]=newType;
nameMapType[typeName]=&def_type[type_num];
}
void element_create(std::string typeName,std::string elementName){
element newElement;
newElement.clear();
ll align=nameMapType[typeName]->mem_align;
ll size=nameMapType[typeName]->mem_size;
if(addrPos%align)
addrPos=((addrPos/align+1)*align);
newElement.addr=addrPos;
newElement.element_type=*nameMapType[typeName];
newElement.name=elementName;
def_element[++element_num]=newElement;
nameMapElement[elementName];
addrMapElement[mp(addrPos,addrPos+size-1)]=&def_element[element_num];
addrPos+=size;
}
ll vis_element(std::string elementName){
std::queue<std::string>name;
std::string tool;
tool.clear();
for(int i=0;i<(ll)elementName.size();i++){
if(elementName[i]=='.'){
name.push(tool);
tool.clear();
}else{
tool+=elementName[i];
}
}
name.push(tool);
ll pos=nameMapElement[name.front()]->addr;
Type type=nameMapElement[name.front()]->element_type;
name.pop();
while(name.size()){
std::string Name=name.front();
name.pop();
std::vector<std::string>::iterator it1=type.mem_name.begin();
std::vector<Type*>::iterator it2=type.mem_type.begin();
for(;it1!=type.mem_name.end();it1++,it2++){
if(pos%(*it2)->mem_align)
pos=(pos/(*it2)->mem_align+1)*(*it2)->mem_align;
if(*it1==Name){
type=**it2;
break;
}
else{
pos+=(*it2)->mem_size;
}
}
}
return pos;
}
std::string vis_addr(ll addr){
if(addr>=addrPos)
return "ERR";
element ele;
std::map<pr,element*>::iterator it=addrMapElement.begin();
for(;it!=addrMapElement.end();it++){
if(addr<(*it).first.first or addr>(*it).first.second)
continue;
ele=*((*it).second);
break;
}
ll posTar=addr-ele.addr;
ll pos_s=0,pos_t;
Type type=ele.element_type;
std::string element_name;
element_name.clear();
element_name+=element_name;
while(!type.mem_name.empty()){
std::vector<Type*>::iterator it1=type.mem_type.begin();
std::vector<std::string>::iterator it2=type.mem_name.begin();
for(;it1!=type.mem_type.end();it1++,it2++){
pos_t=pos_s+(*it1)->mem_size;
if(posTar<pos_t and posTar>=pos_s){
element_name+='.'+*it2;
type=**it1;
break;
}else{
if(it1+1==type.mem_type.end())
return "ERR";
ll align=(*(it1+1))->mem_align;
if(pos_t%align)
pos_t=(pos_t/align+1)*align;
if(posTar<pos_t)
return "ERR";
pos_s=pos_t;
}
}
}
if(element_name=="")
return "ERR";
return element_name;
}
void init(){
def_type[1].name="byte";
def_type[2].name="short";
def_type[3].name="int";
def_type[4].name="long";
def_type[1].mem_align=def_type[1].mem_size=1;
def_type[2].mem_align=def_type[2].mem_size=2;
def_type[3].mem_align=def_type[3].mem_size=4;
def_type[4].mem_align=def_type[4].mem_size=8;
nameMapType["byte"]=&def_type[1];
nameMapType["short"]=&def_type[2];
nameMapType["int"]=&def_type[3];
nameMapType["long"]=&def_type[4];
type_num=4;
}
void work(){
std::ios::sync_with_stdio(0);
std::cin>>n;
while(n--){
std::cin>>op;
if(op==1){
std::cin>>s>>k;
for(int i=1;i<=k;i++){
std::cin>>in1[i]>>in2[i];
}
type_create(s,k,in1,in2);
std::cout<<def_type[type_num].mem_size<<' '<<def_type[type_num].mem_align<<std::endl;
}
else if(op==2){
std::cin>>ti>>ni;
element_create(ti,ni);
std::cout<<def_element[element_num].addr<<std::endl;
}
else if(op==3){
std::cin>>s;
std::cout<<vis_element(s)<<std::endl;
}
else if(op==4){
std::cin>>addr_in;
std::cout<<vis_addr(addr_in)<<std::endl;
}
}
}