Boost Spirit符号表中的错误处理

时间:2014-03-24 11:47:52

标签: c++ parsing boost-spirit

假设我有这样的符号表:

struct jass_types : qi::symbols<char, jass_type> {

现在我想用其父类型填充一个自定义声明的类型:

identifier %= 
    char_("a-zA-Z") >> -(*char_("a-zA-Z_0-9") >> char_("a-zA-Z0-9"))
    ;

type %=
    lit("type") >> identifier >>
    lit("extends") >> identifier[type_symbols.find(_1)]

结构如下:

BOOST_FUSION_ADAPT_STRUCT(
wc3lib::jass::jass_type,
(std::string, identifier)
(wc3lib::jass::jass_type*, parent)
)

我如何编写将其存储0的代码写入属性&#34; parent&#34;如果&#34;之后的标识符延伸&#34;在符号表中找不到,我如何正确地对缺失的符号作出反应?

我的想法是做出类似的事情:

boost::variant<wc3lib::jass::jass_type*,std::string> parent

并根据事实填写指针或标识符,如果在符号表中找到类型,但我必须在之后检测父类型信息。 另一个选择是将父级存储为0作为连字符,并创建一个带有标识符信息等的错误对象。如果找不到符号,Boost可能已经完全相同了???

修改

首先犯了使用_2而不是_1的错误,但它仍然无法工作,因为它显然需要一个char *值而不是std :: string,所以我添加了一个自定义函数:

inline jass_type* get_type_symbol(jass_types &types, const std::string &value) {
    return types.find(value.c_str());
}

和语义行为:

type =
    lit("type") >> identifier >>
    lit("extends") >> identifier[phoenix::bind(&get_type_symbol, ref(type_symbols), _1)]
    ;

但它似乎仍然过于复杂,如果找不到符号,我无法解决标识符的正确错误检测/存储问题!

1 个答案:

答案 0 :(得分:0)

你可以这样做:

// simplified identifier rule exposes a `std::strirng`:
qi::rule<It, std::string()> identifier = char_("a-zA-Z") >> *char_("a-zA-Z_0-9");

struct jass_types : qi::symbols<char, jass_type*> {
        // ...
};

typedef boost::variant<jass_type*, std::string> jass_typeref;
jass_types type_symbols;

请注意,我使symbols<>解析器直接返回指向jass_type的指针。现在规则可以简单如下:

qi::rule<It, jass_typeref()> typeref_ = type_symbols | identifier;

使用它,例如如

type %= "type" >> identifier >> "extends" >> typeref_;

要提供默认值,您可以执行

type %= "type" >> identifier >> 
        ("extends" >> typeref_ | qi::attr(std::string("::object")));

(假设所有类型都延伸::object