我正在尝试编写一个解析器,它能够接受表单MATRIX.{variableName} = [1,2,3;4,5,6]的输入,其中矩阵的表示(在本例中是2x3矩阵)有点类似于MATLAB的格式(分号表示新行)。
最初的想法是将输入保存在一个2d的std向量中,以便进一步处理数据。这是我第一次编写解析器,我对灵性框架有点一无所知。
我目前(不那么直观)的解决方案是,输入类似于MATRIX (2,3) = [1,2,3,4,5,6],表示与上面相同的矩阵,并将数据保存在一维向量中,并在以后使用行和列数据进行处理(我认为这有点像特征的动态矩阵的实现)。
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
namespace fusion = boost::fusion;
template <typename Iterator>
bool parse_matrix(Iterator first, Iterator last, unsigned& rows, unsigned& cols, std::vector<double>& vals)
{
using qi::double_;
using qi::uint_;
using qi::_1;
using qi::lit;
using qi::phrase_parse;
using ascii::space;
using phoenix::push_back;
double rN = 0.0;
double iN = 0.0;
unsigned i=0;
rows = 0, cols = 0;
bool r = phrase_parse(first, last,
// Begin grammar
(
lit("MATRIX") >> '(' >> uint_[phoenix::ref(rows) = _1] >> ',' >> uint_[phoenix::ref(cols) = _1] >> ')' >> '='
>> '[' >> double_[push_back(phoenix::ref(vals),_1)]
>> *(',' >> double_[push_back(phoenix::ref(vals),_1)]) >> ']'
// | double_[ref(rN) = _1]
),
// End grammar
space);
if (!r || first != last) // fail if we did not get a full match
return false;
if (vals.size() != (rows*cols))
return false;
// c = std::complex<double>(rN, iN);
return r;
}
}我在想,当解析某些字符(如分号)时,也许可以调用函数,比如在std::vector<std::vector<double> >中添加一个std::vector<std::vector<double> >。这个是可能的吗?或者我如何去实现我最初的想法呢?
发布于 2014-11-20 22:52:11
你需要把你的表达分解成这样的东西:
rows: DOUBLE | rows ',' DOUBLE
columns: rows | rows ';' rows
matrix: IDENTIFIER '.' '{' IDENTIFIER '}' '=' '[' columns ']'现在,您可以为您的行提供一个vector<double>。列的vector< vector<double> >,并将结果保存在矩阵中。
当然,当得到矩阵中的列时,应该检查所有行的大小是否相同。它不是必需的,但是显然像[1,2;3,4,5]这样的矩阵是无效的,即使语法允许它。
https://stackoverflow.com/questions/27050956
复制相似问题