亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++?Boost?Spirit精通教程

 更新時(shí)間:2022年11月11日 15:49:53   作者:無(wú)水先生  
Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱(chēng)

rule規(guī)則

在 Boost.Spirit 中,解析器由規(guī)則組成。由于規(guī)則通?;?Boost.Spirit 提供的解析器,因此沒(méi)有明顯的區(qū)別。例如, boost::spirit::ascii::digit 既可以是解析器,也可以是規(guī)則。通常,規(guī)則指的是更復(fù)雜的表達(dá)式,例如 qi::int_ % ','。

在迄今為止的所有示例中,規(guī)則都直接傳遞給 boost::spirit::qi::parse() 或 boost::spirit::qi::phrase_parse()。通過(guò) boost::spirit::qi::rule,Boost.Spirit 提供了一個(gè)類(lèi)來(lái)定義規(guī)則變量。例如,如果應(yīng)該將規(guī)則存儲(chǔ)在類(lèi)的成員變量中,則需要 boost::spirit::qi::rule。

Example11.13.Defining rules withboost::spirit::qi::rule

#include <boost/spirit/include/qi.hpp>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>
using namespace boost::spirit;
int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  qi::rule<std::string::iterator, std::vector<int>(),
    ascii::space_type> values = qi::int_ % ',';
  std::vector<int> v;
  if (qi::phrase_parse(it, s.end(), values, ascii::space, v))
  {
    std::ostream_iterator<int> out{std::cout, ";"};
    std::copy(v.begin(), v.end(), out);
  }
}

示例 11.13 的工作方式與示例 11.12 類(lèi)似。如果您輸入多個(gè)以逗號(hào)分隔的整數(shù),它們將用分號(hào)顯示。與前面的示例相比,解析器沒(méi)有直接傳遞給 boost::spirit::qi::phrase_parse(),而是在 boost::spirit::qi::rule 變量中定義。

boost::spirit::qi::rule 是一個(gè)類(lèi)模板。唯一的強(qiáng)制參數(shù)是被解析字符串的迭代器類(lèi)型。在示例中,還傳遞了另外兩個(gè)可選模板參數(shù)。

第二個(gè)模板參數(shù)是 std::vector<int>(),它是返回 std::vector<int> 類(lèi)型向量且不需要參數(shù)的函數(shù)的簽名。該模板參數(shù)表示解析的屬性類(lèi)型為int向量。

第三個(gè)模板參數(shù)是 boost::spirit::qi::phrase_parse() 使用的 skipper 的類(lèi)型。在示例中,使用了船長(zhǎng) boost::spirit::ascii::space。該船長(zhǎng)的類(lèi)型可通過(guò) boost::spirit::ascii::space_type 獲得,并作為模板參數(shù)傳遞給 boost::spirit::qi::rule。

如果您希望您的代碼獨(dú)立于平臺(tái)并使用 C++11 開(kāi)發(fā)環(huán)境,您應(yīng)該更喜歡 boost::spirit::qi::rule 而不是關(guān)鍵字 auto。如果值是用 auto 定義的,則該示例在 GCC 和 Clang 中可以正常工作。然而,在 Visual C++ 2013 中,只有第一個(gè)數(shù)字被解析并寫(xiě)入標(biāo)準(zhǔn)輸出。

Example11.14.Nesting Rules

#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace boost::spirit;
struct print : public boost::static_visitor<>
{
  template <typename T>
  void operator()(T t) const
  {
    std::cout << std::boolalpha << t << ';';
  }
};
int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  qi::rule<std::string::iterator, boost::variant<int, bool>(),
    ascii::space_type> value = qi::int_ | qi::bool_;
  qi::rule<std::string::iterator, std::vector<boost::variant<int, bool>>(),
    ascii::space_type> values = value % ',';
  std::vector<boost::variant<int, bool>> v;
  if (qi::phrase_parse(it, s.end(), values, ascii::space, v))
  {
    for (const auto &elem : v)
      boost::apply_visitor(print{}, elem);
  }
}

Example11.14.Nesting Rules

#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace boost::spirit;
struct print : public boost::static_visitor<>
{
  template <typename T>
  void operator()(T t) const
  {
    std::cout << std::boolalpha << t << ';';
  }
};
int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  qi::rule<std::string::iterator, boost::variant<int, bool>(),
    ascii::space_type> value = qi::int_ | qi::bool_;
  qi::rule<std::string::iterator, std::vector<boost::variant<int, bool>>(),
    ascii::space_type> values = value % ',';
  std::vector<boost::variant<int, bool>> v;
  if (qi::phrase_parse(it, s.end(), values, ascii::space, v))
  {
    for (const auto &elem : v)
      boost::apply_visitor(print{}, elem);
  }
}

example11.14 定義了兩個(gè)規(guī)則,其中一個(gè)引用另一個(gè):values 定義為 value % ',',value 設(shè)置為 qi::int_ | qi::bool_。 values 表示可以解析由逗號(hào)分隔的任意數(shù)量的值。 value 將值定義為整數(shù)或布爾值??傊?,規(guī)則規(guī)定用逗號(hào)分隔的整數(shù)和布爾值可以按任何順序輸入。

為了存儲(chǔ)任意數(shù)量的值,提供了一個(gè) std::vector 類(lèi)型的容器。因?yàn)橹档念?lèi)型是 int 或 bool,所以需要一個(gè)可以存儲(chǔ) int 或 bool 值的類(lèi)。根據(jù)屬性類(lèi)型和運(yùn)算符的概述,必須使用來(lái)自 Boost.Variant 的類(lèi) boost::variant。

如果您啟動(dòng)示例并輸入以逗號(hào)分隔的整數(shù)和布爾值,則這些值將寫(xiě)入以分號(hào)分隔的標(biāo)準(zhǔn)輸出流。這是在 Boost.Variant 提供的函數(shù) boost::apply_visitor() 的幫助下完成的。這個(gè)函數(shù)需要一個(gè)訪問(wèn)者——在這個(gè)例子中是類(lèi) print 的一個(gè)對(duì)象。

請(qǐng)注意,布爾值必須輸入為 true 和 false。

語(yǔ)法

如果要解析復(fù)雜的格式,需要定義多個(gè)相互引用的規(guī)則,可以用 boost::spirit::qi::grammar 進(jìn)行分組。

Example11.15.Grouping rules in a grammar

#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <vector>
#include <iostream>
using namespace boost::spirit;
template <typename Iterator, typename Skipper>
struct my_grammar : qi::grammar<Iterator,
  std::vector<boost::variant<int, bool>>(), Skipper>
{
  my_grammar() : my_grammar::base_type{values}
  {
    value = qi::int_ | qi::bool_;
    values = value % ',';
  }
  qi::rule<Iterator, boost::variant<int, bool>(), Skipper> value;
  qi::rule<Iterator, std::vector<boost::variant<int, bool>>(), Skipper>
    values;
};
struct print : public boost::static_visitor<>
{
  template <typename T>
  void operator()(T t) const
  {
    std::cout << std::boolalpha << t << ';';
  }
};
int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  my_grammar<std::string::iterator, ascii::space_type> g;
  std::vector<boost::variant<int, bool>> v;
  if (qi::phrase_parse(it, s.end(), g, ascii::space, v))
  {
    for (const auto &elem : v)
      boost::apply_visitor(print{}, elem);
  }
}

示例 11.15 的工作方式與示例 11.14 類(lèi)似:您可以按任何順序輸入整數(shù)和布爾值,并以逗號(hào)分隔。它們將以相同的順序?qū)懭霕?biāo)準(zhǔn)輸出流,但用分號(hào)分隔。該示例使用與前一個(gè)相同的規(guī)則——值和值。然而,這一次規(guī)則被分組在一個(gè)語(yǔ)法中。語(yǔ)法在一個(gè)名為 my_grammar 的類(lèi)中定義,該類(lèi)派生自 boost::spirit::qi::grammar。

my_grammar 和 boost::spirit::qi::grammar 都是類(lèi)模板。 boost::spirit::qi::grammar 期望的模板參數(shù)與 boost::spirit::qi::rule 期望的模板參數(shù)相同。要解析的字符串的迭代器類(lèi)型必須傳遞給 boost::spirit::qi::grammar。您還可以傳遞定義屬性類(lèi)型和船長(zhǎng)類(lèi)型的函數(shù)的簽名。

在 my_grammar 中, boost::spirit::qi::rule 用于定義規(guī)則值和值。規(guī)則被定義為成員變量并在構(gòu)造函數(shù)中初始化。

請(qǐng)注意,最外層的規(guī)則必須與 base_type 一起傳遞給基類(lèi)的構(gòu)造函數(shù)。這樣,Boost.Spirit 就知道哪個(gè)規(guī)則是語(yǔ)法的入口點(diǎn)。

一旦定義了語(yǔ)法,就可以像解析器一樣使用它。在示例 11.15 中,my_grammar 在 main() 中實(shí)例化以創(chuàng)建 g。然后將 g 傳遞給 boost::spirit::qi::phrase_parse()。

Example11.16.Storing parsed values in structures

#include <boost/spirit/include/qi.hpp>
#include <boost/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
#include <vector>
#include <iostream>
using namespace boost::spirit;
typedef boost::variant<int, bool> int_or_bool;
struct int_or_bool_values
{
  int_or_bool first;
  std::vector<int_or_bool> others;
};
BOOST_FUSION_ADAPT_STRUCT(
  int_or_bool_values,
  (int_or_bool, first)
  (std::vector<int_or_bool>, others)
)
template <typename Iterator, typename Skipper>
struct my_grammar : qi::grammar<Iterator, int_or_bool_values(), Skipper>
{
  my_grammar() : my_grammar::base_type{values}
  {
    value = qi::int_ | qi::bool_;
    values = value >> ',' >> value % ',';
  }
  qi::rule<Iterator, int_or_bool(), Skipper> value;
  qi::rule<Iterator, int_or_bool_values(), Skipper> values;
};
struct print : public boost::static_visitor<>
{
  template <typename T>
  void operator()(T t) const
  {
    std::cout << std::boolalpha << t << ';';
  }
};
int main()
{
  std::string s;
  std::getline(std::cin, s);
  auto it = s.begin();
  my_grammar<std::string::iterator, ascii::space_type> g;
  int_or_bool_values v;
  if (qi::phrase_parse(it, s.end(), g, ascii::space, v))
  {
    print p;
    boost::apply_visitor(p, v.first);
    for (const auto &elem : v.others)
      boost::apply_visitor(p, elem);
  }
}

示例 11.16 基于前面的示例,但需要至少兩個(gè)值。規(guī)則值定義為 value >> ',' >> value % ','。

values 中的第一個(gè)組件是 value,第二個(gè)是 value % ','。第一個(gè)組件解析的值必須存儲(chǔ)在 boost::variant 類(lèi)型的對(duì)象中。第二個(gè)組件解析的值必須存儲(chǔ)在容器中。使用 int_or_bool_values,該示例提供了一個(gè)結(jié)構(gòu)來(lái)存儲(chǔ)由規(guī)則值的兩個(gè)組件解析的值。

要將 int_or_bool_values 與 Boost.Spirit 一起使用,必須使用宏 BOOST_FUSION_ADAPT_STRUCT。該宏由 Boost.Fusion 提供。該宏可以將 int_or_bool_values 視為具有 int_or_bool 和 std::vector<int_or_bool> 類(lèi)型的兩個(gè)值的元組。因?yàn)檫@個(gè)元組具有正確數(shù)量的正確類(lèi)型的值,所以可以使用簽名 int_or_bool_values() 定義值。 values 將在 first 中存儲(chǔ)第一個(gè)解析值,在其他中存儲(chǔ)所有其他解析值。

int_or_bool_values 類(lèi)型的對(duì)象作為屬性傳遞給 boost::spirit::qi::phrase_parse()。如果您啟動(dòng)示例并輸入至少兩個(gè)以逗號(hào)分隔的整數(shù)或布爾值,則它們都存儲(chǔ)在屬性中并寫(xiě)入標(biāo)準(zhǔn)輸出流。

解析器已從上一個(gè)示例中使用的內(nèi)容進(jìn)行了更改。如果值是用 value % ',' 定義的,則 int_or_bool_values 將只有一個(gè)成員變量,并且所有解析的值都可以存儲(chǔ)在一個(gè)向量中,如前面的示例所示。因此,int_or_bool_values 就像一個(gè)只有一個(gè)值的元組——Boost.Spirit 不支持。只有一個(gè)成員變量的結(jié)構(gòu)將導(dǎo)致編譯器錯(cuò)誤。該問(wèn)題有多種解決方法。

練習(xí)

創(chuàng)建一個(gè)可以加減整數(shù)的解析器。解析器應(yīng)該能夠處理像 1+2-5+8 這樣的輸入,并將結(jié)果(這里是 6)寫(xiě)入標(biāo)準(zhǔn)輸出。

擴(kuò)展您的解析器:它現(xiàn)在應(yīng)該也支持浮點(diǎn)數(shù)。此外,應(yīng)該可以使用分?jǐn)?shù)。新的解析器應(yīng)該能夠處理像 1.2+6/5-0.9 這樣的輸入,并且應(yīng)該將結(jié)果(這里是 1.5)寫(xiě)入標(biāo)準(zhǔn)輸出。

到此這篇關(guān)于C++ Boost Spirit精通教程的文章就介紹到這了,更多相關(guān)C++ Boost Spirit內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言利用結(jié)構(gòu)體數(shù)組實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • 詳解C++虛函數(shù)的工作原理

    詳解C++虛函數(shù)的工作原理

    這篇文章主要介紹了C++虛函數(shù)的工作原理的的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • 使用c++實(shí)現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    使用c++實(shí)現(xiàn)OpenCV繪制旋轉(zhuǎn)矩形圖形

    這篇文章主要給大家介紹了使用c++實(shí)現(xiàn)OpenCV繪制圖形旋轉(zhuǎn)矩形的方法案例,通過(guò)圖文及代碼形式進(jìn)行了詳細(xì)的描述,有需要的朋友可以參考下,希望可以有所幫助
    2021-08-08
  • C++指針與引用的異同

    C++指針與引用的異同

    這篇文章主要介紹了C++指針與引用的異同,文章以C++指針與引用的相關(guān)資料結(jié)合指針和引用的相同點(diǎn)和區(qū)別展開(kāi)詳細(xì)內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋游戲

    C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單五子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C++超詳細(xì)梳理lambda和function的使用方法

    C++超詳細(xì)梳理lambda和function的使用方法

    C++在C11標(biāo)準(zhǔn)中引入了匿名函數(shù),即沒(méi)有名字的臨時(shí)函數(shù),又稱(chēng)之為lambda表達(dá)式.lambda表達(dá)式 實(shí)質(zhì)上是創(chuàng)建一個(gè)匿名函數(shù)/對(duì)象,這篇文章主要介紹了lambda和function的使用方法
    2022-08-08
  • C++?中的類(lèi)型詳細(xì)

    C++?中的類(lèi)型詳細(xì)

    這篇文章主要介紹了C++?中的類(lèi)型,C++的類(lèi)型很復(fù)雜,往往一個(gè)類(lèi)型匹配錯(cuò)誤就會(huì)導(dǎo)致程序報(bào)錯(cuò),本篇主要講解一些常用類(lèi)型的概念以及細(xì)節(jié),需要的朋友可以參考一下,希望對(duì)你有所幫助
    2021-12-12
  • 淺談c和c++的某些小區(qū)別

    淺談c和c++的某些小區(qū)別

    下面小編就為大家?guī)?lái)一篇淺談c和c++的某些小區(qū)別。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • OnSize、OnSizing和OnGetMinMaxInfo區(qū)別分析

    OnSize、OnSizing和OnGetMinMaxInfo區(qū)別分析

    這篇文章主要介紹了OnSize、OnSizing和OnGetMinMaxInfo區(qū)別分析,需要的朋友可以參考下
    2015-01-01
  • C++之值傳遞&指針傳遞&引用傳遞的示例詳解

    C++之值傳遞&指針傳遞&引用傳遞的示例詳解

    這篇文章主要為大家詳細(xì)介紹了C++中值傳遞、指針傳遞和引用傳遞的定義與使用,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-10-10

最新評(píng)論