【发布时间】:2018-11-26 21:38:43
【问题描述】:
我尝试运行一些简单的解析器来解析 [1, 11, 3, 6-4]。基本上,带有范围表示法的整数列表。
我想将所有内容都放入 AST 中,而不需要语义操作。所以我使用 x3::variant。我的代码“似乎”与表达式示例非常相似。但是,它不能在 g++ 6.2 下编译。它确实可以用 clang++ 6.0 编译,但产生错误的结果。
增强版本是 1.63。 看来我有一些“移动”或初始化问题。
#include <iostream>
#include <list>
#include <vector>
#include <utility>
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
#include <boost/fusion/include/io.hpp>
namespace ns
{
namespace ast
{
namespace x3 = boost::spirit::x3;
// forward definition
class uintObj;
struct varVec;
// define type
using uintPair_t = std::pair<unsigned int, unsigned int>;
using uintVec_t = std::vector<uintObj>;
// general token value:
class uintObj : public x3::variant <
unsigned int,
uintPair_t
>
{
public:
using base_type::base_type;
using base_type::operator=;
};
struct varVec
{
uintVec_t valVector;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(
ns::ast::varVec,
valVector
)
namespace ns
{
namespace parser
{
// namespace x3 = boost::spirit::x3;
// using namespace x3;
using namespace boost::spirit::x3;
// definition of the range pair:
rule<class uintPair, ast::uintPair_t> const uintPair = "uintPair";
auto const uintPair_def =
uint_
>> '-'
>> uint_
;
rule<class uintObj, ast::uintObj> const uintObj = "uintObj";
auto const uintObj_def =
uint_
| uintPair
;
// define rule definition : rule<ID, attrib>
// more terse definition :
// struct varVec_class;
// using varVec_rule_t = x3::rule<varVec_class, ast::varVec>;
// varVec_rule_t const varVec = "varVec";
// varVec is the rule, "varVec" is the string name of the rule.
rule<class varVec, ast::varVec> const varVec = "varVec";
auto const varVec_def =
'['
>> uintObj % ','
>> ']'
;
BOOST_SPIRIT_DEFINE(
varVec,
uintObj,
uintPair
);
}
}
int main()
{
std::string input ("[1, 11, 3, 6-4]\n");
std::string::const_iterator begin = input.begin();
std::string::const_iterator end = input.end();
ns::ast::varVec result; // ast tree
using ns::parser::varVec; // grammar
using boost::spirit::x3::ascii::space;
bool success = phrase_parse(begin, end, varVec, space, result);
if (success && begin == end)
std::cout << "good" << std::endl;
else
std::cout << "bad" << std::endl;
return 0;
}
【问题讨论】:
-
我知道还有其他类似的问题。我的问题不是还有其他方法可以做到这一点。我只是觉得没有语义动作的简单 AST 似乎更严格。 stackoverflow.com/questions/34599506/…
-
交换uintPair和uint_后,clang++编译结果很好。但是,另一个问题是我的 g++ v6.2 仍然无法编译。该命令类似于 g++ -I/install/boost_1_63_0/include -std=c++14 -o par21.o -c par21.cpp。不只是我的版本。我的g++也编译不了sehe的版本。
-
在我的回答中查看 cmets
标签: c++ boost-spirit