野牛地图定义
BISON MAP define
我正在用 bison 写作并尝试保存地图中的地图
但我对地图的联合类型有疑问:
%union {
int int_value; /* integer value */
char* string_value; /* string value */
void* map_value; /* map value */
};
assign:
TOKEN_VAR '=' '{' Exp "}" {myMap[]=; mapSave.clear();} ;
Exp : TOKEN_MAP {$$=;}
| value{}
| Exp',' value{}
;
value: stringExpr ':' intExpr {mapSave[]=;}
;
例如我有:
abc={a:1,b:2,c:3}
我需要将其保存在地图的地图中:
所以我有:
typedef map<int, string> innerMap;
typedef map<string, innerMap> mainMap;
mainMap myMap;
map<string,int> mapSave;
我收到很多错误:
error: no match for ‘operator=’ (operand types are ‘std::map<std::basic_string<char>, std::map<int, std::basic_string<char> > >::mapped_type {aka std::map<int, std::basic_string<char> >}’ and ‘void*’)
TOKEN_VAR '=' '{' Exp "}" {myMap[]=; mapForSave.clear();}
^
note: candidate is:
In file included from /usr/include/c++/4.8/map:61:0,
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compare, _Alloc>::operator=(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = int; _Tp = std::basic_string<char>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::basic_string<char> > >]
operator=(const map& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: no known conversion for argument 1 from ‘void*’ to ‘const std::map<int, std::basic_string<char> >&’
也许,有人有办法做到这一点?
谢谢
据推测,您的 bison 文件包含以下声明:
%type <map_value> Exp
(注1)。然而,map_value
标签实际上不是 std::map
的实例,甚至也不是 std::map*
的实例。是一个void*
。所以在声明中,
myMap[]=;
您正在尝试将 void*
(</code>) 分配给 <code>std::map<int, std::string>
([=23= 的 mapped_type
)。这显然行不通,因为无法将 void*
转换为任何类型的 std::map
。
这正是错误消息告诉您的内容。
你不能通过使 map_value
成为 std::map<int, std::string>
(注 2)来解决这个问题,因为 std::map
不能成为联合成员,但你可以使 map_value
成为指针到这样一张地图。智能指针会更好,但它也不能是联合成员,所以你必须自己处理内存管理。
不过,我怀疑您真的打算使用全局 mapSave
而不是 </code>。你当然可以写 <code>myMap[] = mapSave;
(但见下文;你可能还需要 free()
),但这很丑陋,原因如下:首先,全局 mapSave
和其次,赋值涉及最近构造的副本std::map
,这是可以避免的。
char*
string_value
也存在内存管理问题。如果您使用 (f)lex 操作在词法扫描器中填写 yylval
成员,例如:
[[: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[]=;
free(); /* Free the copied string */
}
备注
一般来说,最好在您的问题中包含类似的详细信息,而不是强迫潜在的回答者猜测。我们可能会猜错,在这种情况下答案会产生误导,或者我们可能根本懒得去尝试。
我完全不清楚为什么 myMap
的 mapped_type
是 std::map<int, std::string>
。问题中的其他所有内容似乎都表明它应该是 std::map<std::string, int>
.
我正在用 bison 写作并尝试保存地图中的地图 但我对地图的联合类型有疑问:
%union {
int int_value; /* integer value */
char* string_value; /* string value */
void* map_value; /* map value */
};
assign:
TOKEN_VAR '=' '{' Exp "}" {myMap[]=; mapSave.clear();} ;
Exp : TOKEN_MAP {$$=;}
| value{}
| Exp',' value{}
;
value: stringExpr ':' intExpr {mapSave[]=;}
;
例如我有:
abc={a:1,b:2,c:3}
我需要将其保存在地图的地图中: 所以我有:
typedef map<int, string> innerMap;
typedef map<string, innerMap> mainMap;
mainMap myMap;
map<string,int> mapSave;
我收到很多错误:
error: no match for ‘operator=’ (operand types are ‘std::map<std::basic_string<char>, std::map<int, std::basic_string<char> > >::mapped_type {aka std::map<int, std::basic_string<char> >}’ and ‘void*’)
TOKEN_VAR '=' '{' Exp "}" {myMap[]=; mapForSave.clear();}
^
note: candidate is:
In file included from /usr/include/c++/4.8/map:61:0,
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: std::map<_Key, _Tp, _Compare, _Alloc>& std::map<_Key, _Tp, _Compare, _Alloc>::operator=(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = int; _Tp = std::basic_string<char>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::basic_string<char> > >]
operator=(const map& __x)
^
/usr/include/c++/4.8/bits/stl_map.h:264:7: note: no known conversion for argument 1 from ‘void*’ to ‘const std::map<int, std::basic_string<char> >&’
也许,有人有办法做到这一点?
谢谢
据推测,您的 bison 文件包含以下声明:
%type <map_value> Exp
(注1)。然而,map_value
标签实际上不是 std::map
的实例,甚至也不是 std::map*
的实例。是一个void*
。所以在声明中,
myMap[]=;
您正在尝试将 void*
(</code>) 分配给 <code>std::map<int, std::string>
([=23= 的 mapped_type
)。这显然行不通,因为无法将 void*
转换为任何类型的 std::map
。
这正是错误消息告诉您的内容。
你不能通过使 map_value
成为 std::map<int, std::string>
(注 2)来解决这个问题,因为 std::map
不能成为联合成员,但你可以使 map_value
成为指针到这样一张地图。智能指针会更好,但它也不能是联合成员,所以你必须自己处理内存管理。
不过,我怀疑您真的打算使用全局 mapSave
而不是 </code>。你当然可以写 <code>myMap[] = mapSave;
(但见下文;你可能还需要 free()
),但这很丑陋,原因如下:首先,全局 mapSave
和其次,赋值涉及最近构造的副本std::map
,这是可以避免的。
char*
string_value
也存在内存管理问题。如果您使用 (f)lex 操作在词法扫描器中填写 yylval
成员,例如:
[[: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[]=;
free(); /* Free the copied string */
}
备注
一般来说,最好在您的问题中包含类似的详细信息,而不是强迫潜在的回答者猜测。我们可能会猜错,在这种情况下答案会产生误导,或者我们可能根本懒得去尝试。
我完全不清楚为什么
myMap
的mapped_type
是std::map<int, std::string>
。问题中的其他所有内容似乎都表明它应该是std::map<std::string, int>
.