【问题标题】:Implementing ternary-type if with lazy evaluation如果使用惰性求值实现三元类型
【发布时间】:2014-06-10 15:35:15
【问题描述】:

我正在为 if 函数实现生产规则:

qi::rule<Iterator, ascii::space_type, double(void)> f_if;
f_if = qi::ascii::string("if")
            >> qi::char_('(')
            >> (comparator >> ',' >> expression >> ',' >> expression) [qi::_val = boost::phoenix::bind(&Grammar<Iterator>::function_if, this, qi::_1, qi::_2, qi::_3)]
            >> qi::char_(')')
            ;

表达式比较器声明为

qi::rule<Iterator, ascii::space_type, double(void)> expression;
qi::rule<Iterator, ascii::space_type, bool(void)> comparator;

并且绑定函数有原型

 double function_if(bool comparator, double left, double right);

有什么办法可以根据比较器的值只计算一个表达式

【问题讨论】:

    标签: boost-spirit boost-spirit-qi


    【解决方案1】:

    使用boost::phoenix::if_else,它是 C++ 三元运算符的演员公式:

    &gt;&gt; (comparator &gt;&gt; ',' &gt;&gt; expression &gt;&gt; ',' &gt;&gt; expression) [qi::_val = boost::phoenix::if_else(qi::_1, qi::_2, qi::_3)]

    (与所有其他代码行一样)。

    这意味着将只评估 qi::_2qi::_3 之一。

    【讨论】:

      【解决方案2】:

      当然可以!甚至没有说任何东西都被评估过。

      因此,您为完整的输入片段解析 AST(抽象语法树),并在评估时跳过不适用的部分。

      因此,在许多情况下,关键是分离关注点。如果您将解析与其他阶段(如评估,或者在编译器的情况下,简化、转换和代码生成)分开,编译器/解释器设计变得更容易正确执行。

      【讨论】:

      • 所以我应该完全放弃function_if 等等在语义动作中直接使用三元的东西吗?
      • @YogiBear 老实说,我想说的恰恰相反。我会说:try to do nothing in the semantic action 因为现在说需要做什么还为时过早(想想回溯规则,以及......)。如果您对不同的输入多次评估相似的表达式,它也会更有效,并且通过分离职责来降低复杂性。
      猜你喜欢
      • 2017-11-01
      • 2015-09-25
      • 1970-01-01
      • 2019-01-27
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 2019-11-16
      • 1970-01-01
      相关资源
      最近更新 更多