Нет совпадения для оператора * для экземпляров

Я пытаюсь сгенерировать код для определенного языка, используя bison, flex и llvm. Вот часть кода (точки обозначают код, не связанный с вопросом) для объединения и раздела правил:

%union {
    Node *node;
    NBlock *block;
    NMethodCall* methodcall;
    .
    .
    .
    std::vector<NIdentifier*> idetListvec;
    std::vector<NRecordItem*> recdListvec;
    .
    .

}
.
.
type           <expr>              numeric      
%type           <expr>              CondExpression
%type           <idetListvec>       IdentifierList
%type           <recdListvec>       RecordItemList  VarDefnList FormalParmSecList   VarDefns FormalParameterList

.
.
%%
.
.

FormalParameterList :  TLPAREN FormalParmSecList  TRPAREN  {$$ = $2;}
                    ;

FormalParmSecList : FormalParmSecList  TSEMICOLON   FormalParmSec   { $1->push_back($3);}
                  | FormalParmSec                                   {$$ = new NRecordItemList(); $$->push_back($1);}
                  ;


FormalParmSec : ValueParmSpec                                       {$$ = $1;}
              | VariableParmSpec                                    {$$ = $1;}
              ;

%%

У меня был отдельный файл для так называемого абстрактного синтаксического дерева (AST) для реализации классов. Вот класс, о котором я хочу спросить:

#include <iostream>
#include <vector>
class NStatement;
.
classNRecordItem;
classModule;
.
.
typedef std::vector<NRecordItem*> NRecordItemList;
typedef std::vector<NConstantDeclaration*> NConstantDeclarationList;
typedef std::vector<NTypDefn> NTypDefnList;
typedef std::vector<Module> NModuleList;

class Node {
public:
    virtual ~Node() {}
    //virtual llvm::Value* codeGen(CodeGenContext& context) { return NULL; }
};


class NExpression : public Node {
};

class NStatement : public Node {
};

class NInteger : public NExpression {
public:
    int value;
    NInteger(int value) : value(value) { }
    //virtual llvm::Value* codeGen(CodeGenContext& context);
};
.
.
class NRecordItem : public NStatement {
public:
    const NIdentifier& type;
    NIdentifierList arguments;
    NRecordItem(NIdentifierList& arguments, const NIdentifier& type ) :
        type(type),  arguments(arguments) { }
    //virtual llvm::Value* codeGen(CodeGenContext& context);
};

при запуске кода выдает следующую ошибку:

parser.y:256:26: error: no match for ‘operator=’ (operand types are ‘std::vector<NRecordItem*>’ and ‘NRecordItemList* {aka int*}’)
                   | FormalParmSec         {$$ = new NRecordI
                          ^
In file included from /usr/include/c++/5/vector:69:0,
                 from node.h:2,
                 from parser.y:2:
/usr/include/c++/5/bits/vector.tcc:167:5: note: candidate: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = NRecordItem*; _Alloc = std::allocator<NRecordItem*>]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/5/bits/vector.tcc:167:5: note:   no known conversion for argument 1 from ‘NRecordItemList* {aka int*}’ to ‘const std::vector<NRecordItem*>&’
In file included from /usr/include/c++/5/vector:64:0,
                 from node.h:2,
                 from parser.y:2:
/usr/include/c++/5/bits/stl_vector.h:448:7: note: candidate: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(std::vector<_Tp, _Alloc>&&) [with _Tp = NRecordItem*; _Alloc = std::allocator<NRecordItem*>]
       operator=(vector&& __x) noexcept(_Alloc_traits::_S_not
       ^
/usr/include/c++/5/bits/stl_vector.h:448:7: note:   no known conversion for argument 1 from ‘NRecordItemList* {aka int*}’ to ‘std::vector<NRecordItem*>&&’
/usr/include/c++/5/bits/stl_vector.h:470:7: note: candidate: std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(std::initializer_list<_Tp>) [with _Tp = NRecordItem*; _Alloc = std::allocator<NRecordItem*>]
       operator=(initializer_list<value_type> __l)
       ^

Мой вопрос о правиле 'FormalParmSecList'. Я сохранил значение параметров в векторном классе, но это выдает эту ошибку. любая идея!

3 ответа

Вы пытаетесь поставить std::vector объекты прямо в вашем %union, Это не сработает, так как они не будут построены и разрушены должным образом. Вы должны изменить свой %union использовать указатели:

%union {
    :
    std::vector<NIdentifier*> *idetListvec;
    std::vector<NRecordItem*> *recdListvec;

Вы уже пытаетесь сохранить указатели на векторы в своих действиях, так что похоже, что вы уже пытались сделать это, вы просто пропустили объявление.

$$ = new NRecordItemList();

Этот оператор создает указатель на NRecordItemList объект и назначает его $$, Однако где-то вы заявили, что $$ это NRecordItemList, а не указатель на один. Вам либо нужно удалить new из этого утверждения или измените объявление типа для этого правила грамматики так, чтобы $$ имеет правильный тип. Я не вижу, где вы объявили тип для этого конкретного правила в коде, который вы разместили здесь. Вы должны найти это и исправить это. (Прошло также много времени с тех пор, как я использовал зубров.)

Вы пытаетесь назначить std::vector с указателем на std::vector (ака std::vector*).

Удалить new из строки ошибки, чтобы получить {$$ = NRecordItemList(); $$->push_back($1)}

Другие вопросы по тегам