warming_up.qbk
来自「Boost provides free peer-reviewed portab」· QBK 代码 · 共 139 行
QBK
139 行
[/============================================================================== Copyright (C) 2001-2008 Joel de Guzman Copyright (C) 2001-2008 Hartmut Kaiser Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)===============================================================================/][section Warming up]We'll start by showing examples of parser expressions to give you a feel on howto build parsers from the simplest parser, building up as we go.[heading Trivial Example #1 Parsing a number]Create a parser that will parse a floating-point number. double_(You've got to admit, that's trivial!) The above code actually generates aSpirit floating point parser (a built-in parser). Spirit has many pre-definedparsers and consistent naming conventions help you keep from going insane![heading Trivial Example #2 Parsing two numbers]Create a parser that will accept a line consisting of two floating-point numbers. double_ >> double_Here you see the familiar floating-point numeric parser `double_` used twice,once for each number. What's that `>>` operator doing in there? Well, they hadto be separated by something, and this was chosen as the "followed by" sequenceoperator. The above program creates a parser from two simpler parsers, glueingthem together with the sequence operator. The result is a parser that is acomposition of smaller parsers. Whitespace between numbers can implicitly beconsumed depending on how the parser is invoked (see below).[note When we combine parsers, we end up with a "bigger" parser, but it's still a parser. Parsers can get bigger and bigger, nesting more and more, but whenever you glue two parsers together, you end up with one bigger parser. This is an important concept.][heading Trivial Example #3 Parsing one or more numbers]Create a parser that will accept one or more floating-point numbers. *double_This is like a regular-expression Kleene Star, though the syntax might look abit odd for a C++ programmer not used to seeing the `*` operator overloaded likethis. Actually, if you know regular expressions it may look odd too since thestar is before the expression it modifies. C'est la vie. Blame it on the factthat we must work with the syntax rules of C++.Any expression that evaluates to a parser may be used with the Kleene Star.Keep in mind, though, that due to C++ operator precedence rules you may needto put the expression in parentheses for complex expressions. The Kleene Staris also known as a Kleene Closure, but we call it the Star in most places.[heading Trivial Example #4 Parsing a comma-delimited list of numbers]This example will create a parser that accepts a comma-delimited list ofnumbers. double_ >> *(char_(',') >> double_)Notice `char_(',')`. It is a literal character parser that can recognize thecomma `','`. In this case, the Kleene Star is modifying a more complex parser,namely, the one generated by the expression: (char_(',') >> double_)Note that this is a case where the parentheses are necessary. The Kleene starencloses the complete expression above.[heading Let's Parse!]We're done with defining the parser. So the next step is now invoking thisparser to do its work. There are a couple of ways to do this. For now, we willuse the `phrase_parse` function. One overload of this function accepts fourarguments:# An iterator pointing to the start of the input# An iterator pointing to one past the end of the input# The parser object# Another parser called the skip parserIn our example, we wish to skip spaces and tabs. Another parser named `space`is included in Spirit's repertoire of predefined parsers. It is a very simpleparser that simply recognizes whitespace. We will use `space` as our skipparser. The skip parser is the one responsible for skipping characters inbetween parser elements such as the `double_` and `char_`.Ok, so now let's parse![import ../../example/qi/num_list1.cpp][tutorial_numlist1]The parse function returns `true` or `false` depending on the result of theparse. The first iterator is passed by reference. On a successful parse,this iterator is repositioned to the rightmost position consumed by theparser. If this becomes equal to str.end(), then we have a full match.If not, then we have a partial match. A partial match happens when theparser is only able to parse a portion of the input.Note that we inlined the parser directly in the call to parse. Upon callingparse, the expression evaluates into a temporary, unnamed parser which is passedinto the parse() function, used, and then destroyed.Here, we opted to make the parser generic by making it a template, parameterizedby the iterator type. By doing so, it can take in data coming from any STLconforming sequence as long as the iterators conform to a forward iterator.You can find the full cpp file here: [@../../example/qi/num_list1.cpp][note `char` and `wchar_t` operandsThe careful reader may notice that the parser expression has `','` instead of`char_(',')` as the previous examples did. This is ok due to C++ syntax rules ofconversion. There are `>>` operators that are overloaded to accept a `char` or`wchar_t` argument on its left or right (but not both). An operator may beoverloaded if at least one of its parameters is a user-defined type. In thiscase, the `double_` is the 2nd argument to `operator>>`, and so the properoverload of `>>` is used, converting `','` into a character literal parser.The problem with omiting the `char_` should be obvious: `'a' >> 'b'` is not aspirit parser, it is a numeric expression, right-shifting the ASCII (or anotherencoding) value of `'a'` by the ASCII value of `'b'`. However, both`char_('a') >> 'b'` and `'a' >> char_('b')` are Spirit sequence parsersfor the letter `'a'` followed by `'b'`. You'll get used to it, sooner or later.]Finally, take note that we test for a full match (i.e. the parser fully parsedthe input) by checking if the first iterator, after parsing, is equal to the enditerator. You may strike out this part if partial matches are to be allowed.[endsect] [/ Warming up]
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?