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

标签 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. 正确的做法是什么?

编辑:我基本上希望能够做到:

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

最佳答案

您不是在寻找: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 将为空。

关于c++ - 在 C++ 中为编译器实现符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18977832/

相关文章:

c++ - 如何删除 QToolButton 上的轮廓

c++11 - std::map emplace gcc 4.8.2

java - int i = array.length 比只调用 array.length 两次有什么优势吗?

compiler-construction - 为 x86 处理器生成程序集

c++ - 防止意外隐藏(由 CRTP mixin 提供的方法)

c++ - 移动 std::deque 后引用/指针是否保证有效?

c++ - 如何使用 std::bind 将函数与对象指针参数绑定(bind)?

multithreading - 使用 std::atomic 在 C++11 中编写线程安全的双端队列

c++ - 将 Nginx 构建到库中

c# - 通过来自 c# net core 的非托管 c++ dll 订阅 Windows 消息