Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 提升灵气符号默认值和空值_C++_Boost Spirit Qi - Fatal编程技术网

C++ 提升灵气符号默认值和空值

C++ 提升灵气符号默认值和空值,c++,boost-spirit-qi,C++,Boost Spirit Qi,符号实现了键值对的映射:给定一个字符串的键,它可以返回一个特定的值。我的问题是: 1) 对于空白字符串,是否可以返回默认值?(代码中的Q1) 2) 对于非空字符串或键-值对映射中列出的键的字符串,是否可以返回指示键无效的值?(代码中的Q2) **以下代码基于BOOST SPIRIT文档。 **提前感谢您的建议 #include <boost/spirit/include/support_utree.hpp> #include <boost/spirit/include/qi.h

符号实现了键值对的映射:给定一个字符串的键,它可以返回一个特定的值。我的问题是:

1) 对于空白字符串,是否可以返回默认值?(代码中的Q1)

2) 对于非空字符串或键-值对映射中列出的键的字符串,是否可以返回指示键无效的值?(代码中的Q2)

**以下代码基于BOOST SPIRIT文档。 **提前感谢您的建议

#include <boost/spirit/include/support_utree.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/assert.hpp>
#include <iostream>
#include <string>
#include <cstdlib>

template <typename P, typename T>
void test_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
    using boost::spirit::qi::symbols;

    symbols<char, int> sym;
    sym.add
        ("Apple", 1)
        ("Banana", 2)
        ("Orange", 3)
    ;

    int i;
    test_parser_attr("Banana", sym, i);
    std::cout << i << std::endl;      // 2


    test_parser_attr("", sym, i);     // Q1: key is "",
    std::cout << i << std::endl;      // would like it to be 1 as default

    test_parser_attr("XXXX", sym, i); // Q2: key is other than "Apple"/"Banana"/"Orange",
    std::cout << i << std::endl;      // would like it to be 4

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
模板
无效测试\u解析器\u属性(
字符常量*输入、P常量和P、T&attr、布尔全匹配=真)
{
使用boost::spirit::qi::parse;
字符常量*f(输入);
字符常量*l(f+strlen(f));
if(解析(f,l,p,attr)&(!full_match | | |(f==l)))

std::cout仅仅使用一个
qi::symbols
是无法实现您想要的。应该可以创建一个精神终端/指令来实现所需的结果,但这样做非常复杂,需要了解
qi::symbols
和相关类的内部工作原理,所以我认为这不值得幸运的是,有一个非常简单的替代方法,使用一个解析器,它不使用任何输入,将
val
作为其属性公开,并且总是成功的

让我们看看这三种情况:

  • 如果字符串在符号表中,则返回其关联值
    ->
    ,只需使用
    sym
  • 如果字符串为空,则返回1
    ->
    只需使用
    attr(1)
  • 如果字符串不在符号表中,则返回4
    ->
    此处您需要使用
    attr(4)
    ,但这还不够,因为您还需要使用字符串。如果我们假设字符串仅由字母组成,则可以使用
    省略[+alpha]
    省略
    丢弃文本,
    +
    确保至少有一个字母)
您需要将这三个解析器放在一个适当的位置,记住在每种情况下实际使用的解析器将是第一个成功的解析器:

sym | omit[+alpha] >> attr(4) | attr(1)
可能的问题:

  • 如果不在符号表中的字符串可能更复杂,则需要适当更改
    +alpha
  • 如果您使用的是skipper,您可能需要使用
    省略[
    词素
    [+alpha]]
    来停止贪婪的
    +
全样本

#包括
#包括
#包括
模板
无效测试\u解析器\u属性(
字符常量*输入、P常量和P、T&attr、布尔全匹配=真)
{
使用boost::spirit::qi::parse;
字符常量*f(输入);
字符常量*l(f+strlen(f));
if(解析(f,l,p,attr)&(!full_match | | |(f==l)))

太棒了!完美的解决方案,详细的解释,快速的响应。非常感谢。
#include <iostream>
#include <string>

#include <boost/spirit/include/qi.hpp>


template <typename P, typename T>
void test_parser_attr(
    char const* input, P const& p, T& attr, bool full_match = true)
{
    using boost::spirit::qi::parse;

    char const* f(input);
    char const* l(f + strlen(f));
    if (parse(f, l, p, attr) && (!full_match || (f == l)))
        std::cout << "ok" << std::endl;
    else
        std::cout << "fail" << std::endl;
}

int main()
{
    using boost::spirit::qi::symbols;

    symbols<char, int> sym;
    sym.add
        ("Apple", 1)
        ("Banana", 2)
        ("Orange", 3)
    ;

    using boost::spirit::qi::attr; 
    using boost::spirit::qi::alpha;
    using boost::spirit::qi::omit;
    using boost::spirit::qi::lexeme;

    //if the text is in the symbol table return the associated value
    //else if the text is formed by letters (you could change this using for example `alnum`) and contains at least one, discard the text and return 4
    //else return 1
    boost::spirit::qi::rule<char const*,int()> symbols_with_defaults = sym | omit[+alpha] >> attr (4) | attr(1);


    int i;
    test_parser_attr("Banana", symbols_with_defaults, i);
    std::cout << i << std::endl;      // 2

    test_parser_attr("", symbols_with_defaults, i);     // Q1: key is "",
    std::cout << i << std::endl;      // would like it to be 1 as default

    test_parser_attr("XXXX", symbols_with_defaults, i); // Q2: key is other than "Apple"/"Banana"/"Orange",
    std::cout << i << std::endl;      // would like it to be 4

    std::vector<int> values;
    test_parser_attr("<Banana>,<>,<xxxx>", ('<' >> symbols_with_defaults >> '>')%',', values);
    for(int val : values)
        std::cout << val << " ";  // should be '2 1 4'
    std::cout << std::endl;

    return 0;
}