2013-09-24 5 views
0

В настоящее время я разрабатываю небольшой компилятор для языка для определения проблем. Вы можете представить себе ребенка-ублюдка Лиспа и Пролога. Теперь, к делу:Реализация таблицы символов для компилятора в C++

Functor - базовый класс, из которого 3 класса наследуют: A, B, C.

Я сделал лексер и парсер с ANTLR3C, который дает мне дерево АСТ. Я обход дерева, и когда я найти функцию типа А, я создаю объект типа A с данными из дерева, а объект sym_register держать его:

#ifndef SYM_REGISTER_H 
#define SYM_REGISTER_H 

#include <vector> 
#include <string> 

enum class Symbol_type : int { T_A, T_B, T_C, T_D }; 

class sym_register { 
    public: 
     std::string name; 
     Symbol_type type; 
     std::shared_ptr<Functor> declaration; 
     std::vector <InstancedFunctor> result; 

     sym_register(std::string n, Symbol_type t, std::shared_ptr<Functor> p){ 
      name = n; type = t; declaration = p; 
     } 
}; 

#endif 

Класс перечисления Symbol_type дает мне информация о том, какой объект является объявлением std :: shared_ptr; указывая, чтобы я мог получить полную информацию об объекте.

Это, как я хранить символы в моем главном классе задачи:

class Problem { 
    std::map< std::string, std::shared_ptr<sym_register> > sym_table; 
}; 

Моя проблема, когда я пытаюсь получить символы из таблицы, так как я не в состоянии получить «декларацию» атрибут к его первоначальному классу, я пробовал использовать static_cast и reinterpret_cast без каких-либо результатов.

Итак, у меня есть различные вопросы:

  1. является «дополнительной» информации из унаследованных классов потеряли, когда я хранить указатель на объект типа А на станд :: shared_ptr?
  2. Должен ли я перейти на коммутатор и (небезопасное) явное преобразование?
  3. Должен ли я хранить указатели до NULL (a-la C) вместо std :: shared_ptr?
  4. Каков правильный способ сделать это?

EDIT: Я в принципе хочу, чтобы быть в состоянии сделать:

std::shared_ptr<A> foo = Problem.getSymbol("objectWithTypeA"); 
// and so on with the rest of the class hierarchy ... 

edit2: Ошибки компиляции являются:

std::shared_ptr<A> foo = it.second->declaration; 
// error: conversion from ‘std::shared_ptr<Functor>’ 
// to non-scalar type ‘std::shared_ptr<A>’ requested 

std::shared_ptr<A> foo(reinterpret_cast<std::shared_ptr<A> >(it.second->declaration)); 
// error: invalid cast from type ‘std::shared_ptr<Functor>’ 
// to type ‘std::shared_ptr<A>’ 

std::shared_ptr<A> foo(static_cast<std::shared_ptr<A> >(it.second->declaration)); 
// error: no matching function for call to ‘std::shared_ptr<A>::shared_ptr(std::shared_ptr<Functor>&)’ 
// note: candidates are: 
// long list of template instantiations with a final 
// note: no known conversion for argument 1 
// from ‘std::shared_ptr<Functor>’ to ‘const std::shared_ptr<A>&’ 

std::shared_ptr<A> foo(static_cast<A*>(it.second->declaration)); 
// error: invalid static_cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’ 

std::shared_ptr<A> foo(reinterpret_cast<A*>(it.second->declaration)); 
// error: invalid cast from type ‘std::shared_ptr<Functor>’ to type ‘A*’ 
+0

Что вы имеете в виду, не имея возможности получить атрибут «объявление»? Есть ли ошибка компиляции или ошибка времени выполнения? – molbdnilo

+0

В основном ошибки компиляции, когда я пытаюсь применить атрибут «объявление» к его первоначальному классу (хранятся в атрибуте «type». – CatOsMandros

+0

И что такое ошибка компиляции? – filmor

ответ

2

Вы не можете найти: std::dynamic_pointer_cast<>?

http://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

std::shared_ptr<A> foo = std::dynamic_pointer_cast<A>( 
          Problem.getSymbol("objectWithTypeA")); 

Где Problem.getSymbol("objectWithTypeA") возвращает std::shared_ptr<Functor>

Обратите внимание, что если объект не относится к типу A возвращаемый shared_ptr будет пустым.

0

А "быстрый и грязный" решение этой проблемы делает это:

shared_ptr<A> foo = shared_ptr<A>((A *)&*it.second->declaration); 

, но я чувствую, что он должен быть лучше/чище/более безопасное решение этой проблемы (с этой конкретной реализацией или без нее).

+0

Пожалуйста, не используйте C-casts в коде C++. Они передают меньше смысла и труднее искать. – RedX

+0

Да RedX, этого я и хотел избежать. У fjardon есть решение для моей проблемы :) – CatOsMandros

Смежные вопросы