在C ++中为编译器实现符号表

时间:2013-09-24 09:33:41

标签: c++ c++11 compiler-construction symbols

我目前正在开发一种用于问题定义语言的小型编译器。你可以想象一个Lisp和Prolog的私生子。现在,对于案例:

Functor是一个基类,3个类继承该类:A,B,C。

我用ANTLR3C制作了一个词法分析器和解析器,它给了我一个AST树。我遍历树,当我找到类型A的函数时,我使用树中的数据创建一个类型为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. 当我在std :: shared_ptr上存储指向A类型对象的指针时,继承类中的“额外”信息是否会丢失?
  2. 我应该进行切换和(不安全)显式转换吗?
  3. 我应该将指针存储为NULL(a-la C)而不是std :: shared_ptr吗?
  4. 这样做的正确方法是什么?
  5. 编辑:我基本上希望能够做到:

    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*’
    

2 个答案:

答案 0 :(得分: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将为空。

答案 1 :(得分:0)

针对此问题的“快速而肮脏”的解决方案是:

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

但我觉得应该是这个问题的更好/更清洁/更安全的解决方案(有或没有这个特定的实现)。