C++ 优化boost::spirit::qi解析器

C++ 优化boost::spirit::qi解析器,c++,boost,boost-spirit-qi,C++,Boost,Boost Spirit Qi,我有一个解析器,它基本上打印出堆栈机器的动作,并在给定某种表达式的情况下使用运算符优先级。我的目标是尽可能优化速度。我读过这本书。我理解主要文章中描述的优化要点,但是我不清楚如何将其集成到我的代码中 下面是我的解析器的一个工作示例。我已经尝试过通过使用raw[]提供基本迭代器来对其进行一些优化。phoenix操作调用必须提供字符串或迭代器,通过它们可以创建字符串;这些函数的真实版本并非微不足道,它们的功能还无法在解析时进行评估: #include <iostream> #includ

我有一个解析器,它基本上打印出堆栈机器的动作,并在给定某种表达式的情况下使用运算符优先级。我的目标是尽可能优化速度。我读过这本书。我理解主要文章中描述的优化要点,但是我不清楚如何将其集成到我的代码中

下面是我的解析器的一个工作示例。我已经尝试过通过使用
raw[]
提供基本迭代器来对其进行一些优化。phoenix操作调用必须提供字符串或迭代器,通过它们可以创建字符串;这些函数的真实版本并非微不足道,它们的功能还无法在解析时进行评估:

#include <iostream>
#include <vector>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_char.hpp>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
using std::endl;
using std::cout;
using std::string;
using std::vector;

void fPushOp(const char* op){
  cout << "PushOp: " << op << endl;
}

void fPushInt(const boost::iterator_range<string::const_iterator>& my_str){
  cout << "PushInt: " << my_str << endl;
}

template<typename Iterator, typename Skipper = qi::space_type>
struct Calculator : public qi::grammar<Iterator, Skipper> {

  qi::rule<Iterator, Skipper>  
    expression, logical_or_expression, logical_and_expression, negate_expression, series_expression,
    single_expression, inclusive_or_expression, exclusive_or_expression, and_expression, equality_expression, 
    relational_expression, shift_expression, additive_expression, multiplicative_expression, 
    term, complement_factor, factor, result, integer, variable, variable_combo, word, prefix;

  qi::rule<Iterator> number;
  Calculator() : Calculator::base_type(result)
  {
    number = 
        qi::raw[
            ("0x" >> +qi::char_("0-9a-fA-F"))     
          | ("0b" >> +qi::char_("0-1"))
          | ("0" >>  +qi::char_("0-7"))
          | (+qi::char_("0-9"))
        ] [phx::bind(&fPushInt, qi::_1)]
        ;

    integer = 
          number
        | ('-' >> number) [phx::bind(&fPushOp, "OP_UNARY_MINUS")]
        ;

    variable =
          ((qi::alpha | qi::char_('_')) 
              >> *(qi::alnum | qi::char_('_')) 
              >> '['
              >>  (+(qi::alnum | qi::char_('_') | qi::char_(',')) 
                | ('\'' >> *~qi::char_('\'') >> '\'')) 
              >> ']')
        | ((qi::alpha | qi::char_('_')) >> *(qi::alnum | qi::char_('_')))
        ;

    variable_combo =
        qi::raw [
          variable >> *(qi::char_('.') >> variable)
        ] [phx::bind(&fPushInt, qi::_1)]
        ;

    word = 
        qi::raw[
          variable
        ] [phx::bind(&fPushInt, qi::_1)]
        ;

    factor =
            ("ceil(" >> expression >> ')')                                                      [phx::bind(&fPushOp, "OP_CEIL")]
        |   ("wrap(" >> expression >> ')')                                                      [phx::bind(&fPushOp, "OP_WRAP")]
        |   ("abs(" >> expression >> ')')                                                       [phx::bind(&fPushOp, "OP_ABS")]
        |   ("count1(" >> expression >> ')')                                                    [phx::bind(&fPushOp, "OP_COUNT1")]
        |   ("pick(" >> expression >> ')')                                                      [phx::bind(&fPushOp, "OP_PICK")]
        |   ("defined(" >> expression >> ')')                                                   [phx::bind(&fPushOp, "OP_DEF")]
        |   ("string_equal(" >> word >> ',' >> word >> ')')                                     [phx::bind(&fPushOp, "OP_STREQ")]
        |   ("string_contains(" >> word >> ',' >> word >> ')')                                  [phx::bind(&fPushOp, "OP_STRCON")]
        |   ("lsl(" >> single_expression >> ',' >> single_expression >> ',' >> number >> ')')   [phx::bind(&fPushOp, "OP_LSL")]
        |   ("lsr(" >> single_expression >> ',' >> single_expression >> ')')                    [phx::bind(&fPushOp, "OP_LSR")]
        |   ("asr(" >> single_expression >> ',' >> single_expression >> ',' >> number >> ')')   [phx::bind(&fPushOp, "OP_ASR")]
        |   ("ror(" >> single_expression >> ',' >> single_expression >> ',' >> number >> ')')   [phx::bind(&fPushOp, "OP_ROR")]
        |   ("rrx(" >> single_expression >> ',' >> single_expression >> ',' >> single_expression >> ',' >> number >> ')')[phx::bind(&fPushOp, "OP_RRX")]
        |   ('(' >> expression >> ')')
        |   variable_combo
        |   integer
        ;
    complement_factor = factor
        | ('~' >> factor) [phx::bind(&fPushOp, "OP_COMPLEMENT")]
        ;
    term = complement_factor
      >> *( (".." >> complement_factor) [phx::bind(&fPushOp, "OP_LEGER")]
          | ('\\' >> complement_factor) [phx::bind(&fPushOp, "OP_MASK")]
          ); 
    multiplicative_expression = term
      >> *( ('/' >> term) [phx::bind(&fPushOp, "OP_DIV")]
          | ('%' >> term) [phx::bind(&fPushOp, "OP_MOD")]
          | ('*' >> term) [phx::bind(&fPushOp, "OP_MUL")]
          );
    additive_expression = multiplicative_expression
      >> *( ('+' >> multiplicative_expression)  [phx::bind(&fPushOp, "OP_ADD")]
          | ('-' >> multiplicative_expression)  [phx::bind(&fPushOp, "OP_SUB")]
          );
    shift_expression = additive_expression
      >> *( (">>" >> additive_expression) [phx::bind(&fPushOp, "OP_SRL")]
          | ("<<" >> additive_expression) [phx::bind(&fPushOp, "OP_SLL")]
          );
    relational_expression = shift_expression
      >> *( ('<' >> shift_expression) [phx::bind(&fPushOp, "OP_LT")]
          | ('>' >> shift_expression) [phx::bind(&fPushOp, "OP_GT")]
          | ("<=" >> shift_expression)[phx::bind(&fPushOp, "OP_LET")]
          | (">=" >> shift_expression)[phx::bind(&fPushOp, "OP_GET")]
          );
    equality_expression = relational_expression 
      >> *( ("==" >> relational_expression)[phx::bind(&fPushOp, "OP_EQ")]
          | ("!=" >> relational_expression)[phx::bind(&fPushOp, "OP_NEQ")] 
          );
    and_expression = equality_expression 
      >> *(('&' >> equality_expression)     [phx::bind(&fPushOp, "OP_AND")]); 
    exclusive_or_expression = and_expression 
      >> *(('^' >> and_expression)          [phx::bind(&fPushOp, "OP_XOR")]); 
    inclusive_or_expression = exclusive_or_expression 
      >> *(('|' >> exclusive_or_expression) [phx::bind(&fPushOp, "OP_OR")]); 
    single_expression = inclusive_or_expression;
    series_expression = inclusive_or_expression 
      >> *((',' >> inclusive_or_expression) [phx::bind(&fPushOp, "OP_SERIES")]);
    negate_expression = series_expression
        | ('!' >> series_expression)        [phx::bind(&fPushOp, "OP_NEGATE")];
    logical_and_expression = negate_expression
      >> *(("&&" >> negate_expression)      [phx::bind(&fPushOp, "OP_LOGICAL_AND")]); 
    logical_or_expression = logical_and_expression 
      >> *(("||" >> logical_and_expression) [phx::bind(&fPushOp, "OP_LOGICAL_OR")]);
    expression = logical_or_expression;

    result = expression;
  }
};

int main(){
  Calculator<string::const_iterator> calc;
  const string expr("0xff0000 >> 3 && 3 + (!9) | (0,200)");
  cout << "Expression: " << expr << endl;

  string::const_iterator it = expr.begin();
  phrase_parse(it, expr.end(), calc, qi::space);

  cout << "Remaining: " << (string(it,expr.end())) << endl;
  return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间phx=boost::phoenix;
使用std::endl;
使用std::cout;
使用std::string;
使用std::vector;
无效fPushOp(常量字符*op){
cout+qi::char(0-7)
|(+qi::char_uu0(“0-9”))
][phx::bind(&fPushInt,qi::_1)]
;
整数=
数
|('-'>>数字)[phx::bind(&fPushOp,“OP_一元数减去”)]
;
变数=
((qi::alpha | qi::char |(“|”))
>>*(qi::alnum | qi::char uu(“u”))
>> '['
>>(+(qi::alnum | qi::char"(“"”)| qi::char"(“,”))
|('\'>>*~qi::char\'>'\'>'\'')
>> ']')
|((qi::alpha | qi::char |('''))>>*(qi::alnum | qi::char |('''))
;
变量组合=
齐:生的[
变量>>*(qi::char_u('.')>>变量)
][phx::bind(&fPushInt,qi::_1)]
;
单词=
齐:生的[
变量
][phx::bind(&fPushInt,qi::_1)]
;
因素=
(“ceil(“>>表达式>>”)[phx::bind(&fPushOp,“OP_ceil”)]
|(“wrap(“>>表达式>>)”)[phx::bind(&fPushOp,“OP_wrap”)]
|(“abs(“>>表达式>>)”)[phx::bind(&fPushOp,“OP_abs”)]
|(“count1(“>>表达式>>”))[phx::bind(&fPushOp,“OP_count1”)]
|(“pick(“>>表达式>>)”)[phx::bind(&fPushOp,“OP_pick”)]
|(“已定义(“>>表达式>>”)[phx::bind(&fPushOp,“OP_DEF”)]
|(“string_equal(“>>word>>”,“>>word>>”))[phx::bind(&fPushOp,“OP_STREQ”)]
|(“字符串包含(“>>word>>”、“>>word>>”))[phx::bind(&fPushOp,“OP\u STRCON”)]
|(“lsl(“>>单个_表达式>>”、“>>单个_表达式>>”、“>>数字>>”))[phx::bind(&fPushOp,“OP_lsl”)]
|(“lsr(“>>单个_表达式>>”,“>>单个_表达式>>”))[phx::bind(&fPushOp,“OP_lsr”)]
|(“asr(“>>单个_表达式>>”、“>>单个_表达式>>”、“>>数字>>”))[phx::bind(&fPushOp,“OP_asr”)]
|(“ror(“>>单个表达式>>”、“>>单个表达式>>”、“>>数字>>”))[phx::bind(&fPushOp,“OP\ror”)]
|(“rrx(“>>单个_表达式>>”、“>>单个_表达式>>”、“>>单个_表达式>>”、“>>数字>>”))[phx::bind(&fPushOp,“OP_rrx”)]
|('('>>表达式>>'))
|变量组合
|整数
;
补码系数=系数
|('~'>>因子)[phx::bind(&fPushOp,“OP_补码”)]
;
术语=补码系数
>>*((“.”>>补码因子)[phx::bind(&fPushOp,“OP_LEGER”)]
|('\\'>>补码因子)[phx::bind(&fPushOp,“OP\u掩码”)]
); 
乘法表达式=项
>>*(('/'>>术语)[phx::bind(&fPushOp,“OP_DIV”)]
|('%'>>术语)[phx::bind(&fPushOp,“OP_MOD”)]
|('*'>>术语)[phx::bind(&fPushOp,“OP_MUL”)]
);
加法表达式=乘法表达式
>>*(('+'>>乘法_表达式)[phx::bind(&fPushOp,“OP_ADD”)]
|('-'>>乘法_表达式)[phx::bind(&fPushOp,“OP_SUB”)]
);
移位表达式=加法表达式
>>*((“>>”>>加法表达式)[phx::bind(&fPushOp,“OP\u SRL”)]
|(“=”>>shift_表达式)[phx::bind(&fPushOp,“OP_-GET”)]
);
等式表达式=关系表达式
>>*((“=”>>关系表达式)[phx::bind(&fPushOp,“OP_EQ”)]
|(!=“>>关系表达式)[phx::bind(&fPushOp,“OP\u NEQ”)]
);
和_表达式=相等_表达式
>>*(“&'>>等式表达式)[phx::bind(&fPushOp,“OP_和”)];
排他性_或_表达式=和_表达式
>>*(“^'>>和_表达式)[phx::bind(&fPushOp,“OP_XOR”)];
inclusive_或_表达式=exclusive_或_表达式
>>*((“|”>>独占_或_表达式)[phx::bind(&fPushOp,“OP_或”)];
单个_表达式=包含性_或_表达式;
级数表达式=包含式表达式或表达式
>>*((','>>包含式_或_表达式)[phx::bind(&fPushOp,“OP_系列”)];
否定表达式=系列表达式
|(“!”>>series_表达式)[phx::bind(&fPushOp,“OP_否定”);
逻辑_和_表达式=否定_表达式
>>*(“&&“>>否定_表达式)[phx::bind(&fPushOp,“OP_逻辑_和”)];
逻辑_或_表达式=逻辑_和_表达式
>>*((“||”>>逻辑_和_表达式)[phx::bind(&fPushOp,“OP|u逻辑_或”)];
表达式=逻辑_或_表达式;
结果=表达式;
}
};
int main(){
计算器计算器;
常量字符串表达式(“0xff0000>>3&&3+(!9)|(0200)”;

不能优化取决于您想要实现的目标。因此,我认为您正在优化prem
Expression: ceil(3.7)
PushInt: 3
PushInt: ceil
Remaining: (3.7)
#define BOOST_SPIRIT_DEBUG
BOOST_SPIRIT_DEBUG_NODES(
        (expression)(logical_or_expression)(logical_and_expression)(negate_expression)(series_expression)(single_expression)
        (inclusive_or_expression)(exclusive_or_expression)(and_expression)(equality_expression)(relational_expression)
        (shift_expression)(additive_expression)(multiplicative_expression)(term)(complement_factor)(factor)(result)(integer)
        (variable)(variable_combo)(word)(prefix)
qi::symbols<char,const char*> unary_function;

unary_function.add
    ("ceil",    "OP_CEIL")
    ("wrap",    "OP_WRAP")
    ("abs",     "OP_ABS")
    ("count1",  "OP_COUNT1")
    ("pick",    "OP_PICK")
    ("defined", "OP_DEF");

unary_call = (unary_function >> "(" >> expression >> ')') [phx::bind(&fPushOp, qi::_1)];