BISON MAP定义

时间:2016-12-03 10:43:12

标签: bison

我正在野牛写作并尝试保存地图地图 但是我对地图的联合类型有问题:

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;
或许,有人有想法这样做吗?

谢谢

1 个答案:

答案 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

注释

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

  2. 我一点也不清楚为什么myMap的{​​{1}}是std::map<int, std::string>。问题中的其他所有内容似乎都表明它应该是std::map<std::string, int>