我想將這個指數運算符添加到這個boost :: spirit計算器example,其語法如下。請注意,像「-2^2^3」這樣的表達式必須被解析爲「 - (2 ^(2^3))」== -256。如何將指數運算符的支持添加到boost :: spirit計算器之一中?
expr = equality_expr.alias() ; equality_expr = relational_expr >> *(equality_op > relational_expr) ; relational_expr = logical_expr >> *(relational_op > logical_expr) ; logical_expr = additive_expr >> *(logical_op > additive_expr) ; additive_expr = multiplicative_expr >> *(additive_op > multiplicative_expr) ; multiplicative_expr = unary_expr >> *(multiplicative_op > unary_expr) ; unary_expr = primary_expr | (unary_op > primary_expr) ; primary_expr = uint_ | identifier | bool_ | '(' > expr > ')' ; identifier = !keywords >> raw[lexeme[(alpha | '_') >> *(alnum | '_')]] ;
已經閱讀文檔後,我的理解是,我要插入以下exponential_expr規則的語法爲它用正確的從右到左結合解析指數運算:
multiplicative_expr = exponential_expr >> *(multiplicative_op > exponential_expr) ; exponential_expr = unary_expr >> !(exponential_op >> exponential_expr) ;
凡規則是:
qi::rule<Iterator, ast::expression(), ascii::space_type>
expr, equality_expr, relational_expr,
logical_expr, additive_expr, multiplicative_expr, exponential_expr
;
qi::rule<Iterator, ast::operand(), ascii::space_type>
unary_expr, primary_expr
;
qi::rule<Iterator, ast::function_call(), ascii::space_type >
function_call
;
qi::rule<Iterator, std::list<ast::expression>(), ascii::space_type >
argument_list
;
qi::rule<Iterator, std::string(), ascii::space_type>
identifier
;
qi::symbols<char, ast::optoken>
equality_op, relational_op, logical_op,
additive_op, multiplicative_op, unary_op, exponential_op
;
qi::symbols<char>
keywords
;
我現在遇到的問題是,該方案無法編譯,因爲AST(ast.hpp)必須是我也相應地進行了修改,但我現在不完全如此。你有什麼主意嗎?
這是編譯器錯誤:
calculator/ExpressionDef.hpp:114:9: required from 'calculator::parser::expression::expression(calculator::error_handler&) [with Iterator = __gnu_cxx::__normal_iterator >]' Expression.cpp:4:37: required from here /usr/include/boost/spirit/home/qi/detail/assign_to.hpp:152:13: error: no matching function for call to 'calculator::ast::expression::expression(const boost::variant, boost::recursive_wrapper, boost::recursive_wrapper >&)' /usr/include/boost/spirit/home/qi/detail/assign_to.hpp:152:13: note: candidates are: In file included from ./calculator/Expression.hpp:20:0, from calculator/ExpressionDef.hpp:1, from Expression.cpp:1: ./calculator/Ast.hpp:83:12: note: calculator::ast::expression::expression() ./calculator/Ast.hpp:83:12: note: candidate expects 0 arguments, 1 provided ./calculator/Ast.hpp:83:12: note: calculator::ast::expression::expression(const calculator::ast::expression&) ./calculator/Ast.hpp:83:12: note: no known conversion for argument 1 from 'const boost::variant, boost::recursive_wrapper, boost::recursive_wrapper >' to 'const calculator::ast::expression&' ./calculator/Ast.hpp:83:12: note: calculator::ast::expression::expression(calculator::ast::expression&&) ./calculator/Ast.hpp:83:12: note: no known conversion for argument 1 from 'const boost::variant, boost::recursive_wrapper, boost::recursive_wrapper >' to 'calculator::ast::expression&&'
[這裏](HTTP:// coliru .stacked-crooked.com/a/4774f9b605937e75),你可以找到一個對calc6.cpp(最後一個編譯器例子適合在一個cpp文件中)的修改,它執行相同的操作(使用命名規則和硬編碼表達式)。 – llonesmiz
我會在一瞬間測試一下,讓我說,我似乎在工作一段時間後做了同樣的事情,並且認爲像「-2^2^3」這樣的語法表達式被解析爲(-2)^( 2^3)而不是 - (2 ^(2^3))。我會盡快確認。 – Martin
另請注意,calc6與calc8有不同的語法。後者是我需要幫助的人。基本上,expoential_expr規則出現在unary_expr之前,因此您爲calc8提出的語法錯誤地將上述示例解析爲(-2)^ [...]。 calc6似乎很好,但它是另一個計算器。順便說一句,你是不是想要寫「exponential_expr = unary_expr」*(exponential_op> exponential_expr)? – Martin