Câu hỏi được in đậm ở phía dưới, vấn đề cũng được tóm tắt bằng đoạn mã chưng cất về cuối.
Tôi đang cố gắng thống nhất hệ thống kiểu của mình (hệ thống kiểu thực hiện và chuyển từ kiểu sang chuỗi) thành một thành phần duy nhất (theo định nghĩa của Lakos). Tôi đang sử dụng boost::array
, boost::variant
và boost::mpl
, để đạt được điều này. Tôi muốn thống nhất các quy tắc phân tích cú pháp và trình tạo cho các loại của mình trong một biến thể. có một loại không xác định, một loại int4 (xem bên dưới) và một loại int8. Biến thể đọc là variant<undefined, int4,int8>
.
đặc điểm int4:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
template<>
struct rbl_type_parser_rule<rbl_int4>
{
typedef rbl_int4_parser_rule_definition string_parser;
};
biến thể ở trên bắt đầu là không xác định và sau đó tôi khởi tạo các quy tắc. Tôi đã gặp sự cố, gây ra lỗi 50 trang và cuối cùng tôi đã tìm ra được nó, Biến thể sử dụng operator=
trong quá trình gán và boost::spirit::qi::int_parser<>
không thể gán một biến thể cho người khác (toán tử =).
Ngược lại, tôi không gặp vấn đề với loại không xác định của mình:
struct rbl_undefined_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, void()> rule_type;
rule_type rule;
rbl_undefined_parser_rule_definition()
{
rule.name("undefined parse rule");
rule = boost::spirit::qi::eps;
}
};
template<>
struct rbl_type_parser_rule<rbl_undefined>
{
typedef rbl_undefined_parser_rule_definition string_parser;
};
Chưng cất vấn đề:
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <boost/cstdint.hpp>
typedef boost::spirit::qi::rule<std::string::iterator,void()> r1;
typedef boost::spirit::qi::rule<std::string::iterator,int()> r2;
typedef boost::variant<r1,r2> v;
int main()
{
/*
problematic
boost::spirit::qi::int_parser<int32_t> t2;
boost::spirit::qi::int_parser<int32_t> t1;
t1 = t2;
*/
//unproblematic
r1 r1_;
r2 r2_;
r1_ = r2_;
v v_;
// THIS is what I need to do.
v_ = r2();
}
Có một khoảng cách ngữ nghĩa giữa các trình phân tích cú pháp cụ thể và các quy tắc. Bộ não của tôi lúc này đang hút thuốc vì vậy tôi sẽ không nghĩ về bệnh liệt dương, Câu hỏi của tôi là, làm cách nào để giải quyết vấn đề này? Tôi có thể nghĩ ra ba cách tiếp cận để giải quyết vấn đề.
một: Các thành viên hàm tĩnh:
struct rbl_int4_parser_rule_definition
{
typedef boost::spirit::qi::rule<std::string::iterator, rbl_int4()> rule_type;
//boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule_type rule;
rbl_int4_parser_rule_definition()
{
static boost::spirit::qi::int_parser<rbl_int4> parser_int32_t;
rule.name("rbl int4 rule");
rule = parser_int32_t;
}
};
Tôi đoán cách tiếp cận một ngăn chặn mã an toàn luồng? ?
hai: Trình phân tích cú pháp tích phân được bao bọc trong shared_ptr. Có hai lý do khiến tôi bận tâm với TMP cho hệ thống đánh máy: 1 hiệu quả, 2 là tập trung mối quan tâm vào các thành phần. sử dụng con trỏ đánh bại lý do đầu tiên.
ba: operator = được định nghĩa là không chọn. biến thể đảm bảo rằng cái lhs
được tạo mặc định trước khi gán.
Chỉnh sửa: Tôi đang nghĩ lựa chọn 3 hợp lý nhất (toán tử = là không chọn). Khi vùng chứa quy tắc được tạo, nó sẽ không thay đổi và tôi chỉ chỉ định để buộc đặc điểm quy tắc của một loại vào phần bù của nó.
parser_int32_t
có trạng thái và tham chiếu được sử dụng. Nếu không có trạng thái hoặc một bản sao được tạo ra, thì nó là an toàn. Từ ngữ nghĩa, tôi sẽ nói một bản sao được tạo ra.