野牛地图定义

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 */
                               }

备注

  1. 一般来说,最好在您的问题中包含类似的详细信息,而不是强迫潜在的回答者猜测。我们可能会猜错,在这种情况下答案会产生误导,或者我们可能根本懒得去尝试。

  2. 我完全不清楚为什么 myMapmapped_typestd::map<int, std::string>。问题中的其他所有内容似乎都表明它应该是 std::map<std::string, int>.