2017-11-02 17 views
1

次のプログラムは元のものから縮小されました。私はそれが実行されると、セグメンテーション違反を取得します。 ArithmeticUnaryExpressionで24行目を削除すると、プログラムはクラッシュしなくなりました。セグメンテーション違反を取り除くにはどうすればよいですか?入れ子にされたboost :: variantのセグメンテーションフォールト

#include <boost/config/warning_disable.hpp> 
#include <boost/spirit/home/x3.hpp> 
#include <boost/spirit/home/x3/support/ast/variant.hpp> 
#include <boost/spirit/include/qi_expect.hpp> 
#include <boost/spirit/home/x3/directive/expect.hpp> 

#include <iostream> 
#include <string> 

namespace wctl_parser { 

namespace x3 = boost::spirit::x3; 
namespace ascii = x3::ascii; 
namespace qi = boost::spirit::qi; 

using x3::ulong_; 
using x3::lexeme; 

//--- Ast structures 
struct ArithmeticUnaryExpression; 
using AtomicProp = std::string; 

using ArithmeticExpression = x3::variant< 
    x3::forward_ast<ArithmeticUnaryExpression>, 
    unsigned long 
>; 

struct ArithmeticUnaryExpression { 
    std::string op; 
    ArithmeticExpression operand; 
}; 

using Expression = x3::variant< 
    ArithmeticExpression 
>; 

template <typename T> auto rule = [](const char* name = typeid(T).name()) { 
    struct _{}; 
    return x3::rule<_, T> {name}; 
}; 

template <typename T> auto as = [](auto p) { return rule<T>() = p; }; 

//--- Rules 

x3::rule<struct aTrivRule, ArithmeticExpression> aTriv("aTriv"); 
x3::rule<struct exprRule, Expression> expr("expression"); 

auto const aTriv_def = rule<ArithmeticExpression>("aTriv") 
    = ulong_ 
// | '(' > expr > ')' 
    ; 

auto const primitive = rule<Expression>("primitive") 
    = aTriv 
    ; 

auto const expr_def 
    = primitive 
    ; 

BOOST_SPIRIT_DEFINE(aTriv) 
BOOST_SPIRIT_DEFINE(expr) 

auto const entry = x3::skip(ascii::space) [expr]; 

} //End namespace 

int main() { 

    std::string str("prop"); 
    namespace x3 = boost::spirit::x3; 
    wctl_parser::Expression root; 
    auto iter = str.begin(); 
    auto end = str.end(); 
    bool r = false; 
    r = parse(iter, end, wctl_parser::entry, root); 
    if (r) { 
     std::cout << "Parses OK:" << std::endl << str << std::endl; 
     if (iter != end) std::cout << "Partial match" << std::endl; 
     std::cout << std::endl << "----------------------------\n"; 
    } 
    else { 
     std::cout << "!! Parsing failed:" << std::endl << str << std::endl << std::endl << "----------------------------\n"; 
    } 
    return 0; 
} 

答えて

2

あなたのバリアント

using ArithmeticExpression = x3::variant< 
    x3::forward_ast<ArithmeticUnaryExpression>, 
    unsigned long 
>; 

は、最初の要素タイプをデフォルト・構築します。第1の要素タイプは、デフォルトで構築されるArithmeticExpressionを含む。あなたはすでに問題を見ることができますか?

ただ、デフォルト構築状態は無限再帰につながるものではないことを確認してください:

using ArithmeticExpression = x3::variant< 
    unsigned long, 
    x3::forward_ast<ArithmeticUnaryExpression> 
>; 
関連する問題