我正在野牛写作并尝试保存地图地图 但是我对地图的联合类型有问题:
ABCD
所以例如我有:
ABC = {A 1,B:2,C:3}
我需要将它保存在地图中: 所以我有:
%union {
int int_value; /* integer value */
char* string_value; /* string value */
void* map_value; /* map value */
};
assign:
TOKEN_VAR '=' '{' Exp "}" {myMap[$1]=$4; mapSave.clear();} ;
Exp : TOKEN_MAP {$$=$1;}
| value{}
| Exp',' value{}
;
value: stringExpr ':' intExpr {mapSave[$1]=$3;}
;
我收到很多错误:
typedef map<int, string> innerMap;
typedef map<string, innerMap> mainMap;
mainMap myMap;
map<string,int> mapSave;
或许,有人有想法这样做吗?
谢谢
答案 0 :(得分:1)
据推测,您的野牛文件包含声明:
%type <map_value> Exp
(注1)。但是,map_value
标记实际上不是std::map
的实例,甚至也不是std::map*
的实例。这是void*
。所以在声明中,
myMap[$1]=$4;
您正在尝试将void*
($4
)分配给std::map<int, std::string>
(mapped_type
myMap
。这显然不会起作用,因为没有办法将void*
转换为任何类型的std::map
。
这正是错误消息告诉你的。
您无法通过map_value
std::map<int, std::string>
(注释2)来解决此问题,因为std::map
不能是联盟成员,但您可以使map_value
指向此类mapSave
一张地图。智能指针会更好,但也不能成为工会成员,所以你必须自己处理内存管理。
我怀疑你真的打算使用全局$4
代替myMap[$1] = mapSave;
。你当然可以写free($1)
(但见下文;你可能还需要mapSave
),但这有点丑陋,原因如下:首先,全局std::map
的不必要的存在和第二,分配涉及最近构建的char*
的副本,这是可以避免的。
string_value
yylval
也存在内存管理问题。如果您使用(f)lex操作填写词法扫描程序中的[[:alpha:]][[:alnum:]]* { yylval.string_value = yytext; /* DON'T DO THIS */
return TOKEN_VAR;
}
成员,请执行以下操作:
[[:alpha:]][[:alnum:]]* { yylval.string_value = strdup(yytext);
return TOKEN_VAR;
}
然后你会发现该字符串的值不正确。你需要做的是这样的事情:
std::string
但是一旦你创建了一个value: stringExpr ':' intExpr { mapSave[$1]=$3;
free($1); /* Free the copied string */
}
,就需要释放复制的字符串,这意味着你的野牛行动必须看起来像:
mapped_type
一般来说,最好在问题中包含类似的详细信息,而不是强迫潜在的回答者猜测。我们可能会猜错,在这种情况下,答案会产生误导,或者我们可能根本不愿意尝试。
我一点也不清楚为什么myMap
的{{1}}是std::map<int, std::string>
。问题中的其他所有内容似乎都表明它应该是std::map<std::string, int>
。