sro*_*ssi 3 c++ boost boost-bind boost-spirit boost-function
我想定义一个带有2个参数的函数
double func(double t, double x);
Run Code Online (Sandbox Code Playgroud)
从外部文本文件中读取实际实现的位置.
例如,在文本文件中指定
function = x*t;
Run Code Online (Sandbox Code Playgroud)
功能应该实现的乘法x和t,以便它可以在稍后阶段被调用.我正在尝试使用boost :: spirit来解析函数.但我不知道如何实现它.
下面,我创建了一个实现乘法的简单函数.我将它绑定到boost函数,我可以使用它.我还创建了一个简单的语法,它解析了两个双精度数之间的乘法.
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include "boost/function.hpp"
#include "boost/bind.hpp"
#include <boost/spirit/include/qi_symbols.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii=boost::spirit::ascii;
using boost::spirit::ascii::space;
using boost::spirit::qi::symbols;
template< typename Iterator >
struct MyGrammar : public virtual qi::grammar< Iterator, ascii::space_type >
{
MyGrammar() : MyGrammar::base_type(expression)
{
using qi::double_;
//The expression should take x and t as symbolic expressions
expression = (double_ >> '*' >> double_)[std::cout << "Parse multiplication: " << (qi::_1 * qi::_2)];
}
qi::rule<Iterator, ascii::space_type> expression;
};
double func(const double a, const double b)
{
return a*b; //This is the operation to perform
}
int main()
{
typedef std::string::const_iterator iterator_Type;
typedef MyGrammar<iterator_Type> grammar_Type;
grammar_Type calc;
std::string str = "1.*2."; // This should be changed to x*t
iterator_Type iter = str.begin();
iterator_Type end = str.end();
bool r = phrase_parse(iter, end, calc, space);
typedef boost::function < double ( const double t,
const double x) > function_Type;
function_Type multiplication = boost::bind(&func, _1, _2);
std::cout << "\nResult: " << multiplication( 2.0, 3.0) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我修改上面的代码设置
std::string str = "x*t";
Run Code Online (Sandbox Code Playgroud)
我如何解析这样的表达式并将其绑定到函数,multiplication这样,如果我调用multiplication(1.0, 2.0)它,它将t与1.0,x关联到2.0并返回操作的结果?
你将学习精神.大!
不过,你似乎咬得比你在这里咀嚼更多.
首先,你的语法实际上并没有解析表达式.它当然不会导致您可以绑定的函数.
实际上,您正在使用不产生任何结果的语法来解析输入.它只会产生一个副作用(即将简单的二进制表达式的结果与简单的操作数一起打印到控制台).这/ /类似/解释语言,虽然很快就会崩溃
2*8 + 9接下来你是绑定func(顺便说一句是多余的;你没有绑定任何参数,所以你可以在function_Type multiplication(func);这里说),然后调用它.虽然很酷,但这与解析输入完全没有关系.
最后,你的问题是第三件事,在上面的任何地方都没有涉及到.这个问题是关于符号表和标识符查找.
x或者t,例如)问题中存在一个空洞的逻辑漏洞,你没有定义"形式参数列表"的来源(你在这里的文字中提到它:function = x*t;但解析器没有处理它,你也没有硬编码任何这样的元数据); 所以我们甚至无法开始将事物x和t事物映射到正式的参数列表(因为它不存在).
让我们假设一下,实际上参数是位置的(就像它们一样,你似乎想要这个,因为你用位置参数调用绑定函数.)所以我们不必担心一个名字因为没有人会看到一个名字.)
调用者应该在上下文中传递函数,以便在评估期间可以通过标识符名称查找值.
所以,虽然我可以试着让你坐下来,然后告诉你所有需要先创建的螺母和螺栓,然后你甚至可以梦想以你想要的方式将它粘合在一起,但不要.
这需要我太多时间,你可能会不堪重负.
我只能建议查看更简单的资源.从教程开始
如果您在此过程中遇到任何问题,可以自由地询问您是否有被卡住的风险.但至少那时我们有一个可以回答的问题和真正帮助你的答案.
现在,看看我的其他一些答案,我实际上实现了这样的语法(有点按复杂程度排序):
很适合比较:Boost :: spirit的答案如何解析和调用类似c ++函数的表达式即时解释解析的表达式(这[std::cout << "Parse multiplication: " << (qi::_1 * qi::_2)]在你自己的解析器中模仿了这个方法)
另一个答案(Boost :: spirit如何解析和调用类似c ++函数的表达式)实现了目标,但使用了专用的AST表示和单独的解释阶段.
这些答案中描述了每种方法的好处.这些解析器没有符号表,也没有评估上下文.
更多例子:
| 归档时间: |
|
| 查看次数: |
3765 次 |
| 最近记录: |