Blame view

3rdparty/boost_1_81_0/libs/spirit/doc/faq.qbk 6.62 KB
73ef4ff3   Hu Chunming   提交三方库
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  [/==============================================================================
      Copyright (C) 2001-2011 Joel de Guzman
      Copyright (C) 2001-2011 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:faq Spirit FAQ]
  
  [heading I'm getting multiple symbol definition errors while using Visual C++. Anything I could do about that?]
  
  Do you see strange multiple symbol definition linker errors mentioning 
  `boost::mpl::failed` and `boost::spirit::qi::rule`? Then this FAQ entry might 
  be for you.
  
  __mpl__ implements a macro `BOOST_MPL_ASSERT_MSG()` which essentially is a 
  more powerful version of static_assert. Unfortunately under certain 
  circumstances using this macro may lead to the aforementioned linker errors. 
  
  __spirit__ allows you to define a preprocessor constant disabling the usage
  of `BOOST_MPL_ASSERT_MSG()`, while switching to `BOOST_STATIC_ASSERT()` instead.
  For that you need define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1. Do this by 
  adding 
  
      -DBOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1
  
  on the compiler command line or by inserting a 
  
      #define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1 
  
  into your code before any Spirit headers get included.
  
  Using this trick has no adverse effects on any of the functionality of 
  __spirit__. The only change you might see while using this workaround is less
  verbose error messages generated from static_assert.
  
  
  [heading I'm very confused about the header hell in my boost/spirit directory. What's all this about?]
  
  The boost/spirit directory currently holds two versions of the Spirit library: 
  __classic__ (former V1.8.x) and SpiritV2. Both are completely independent 
  and usually not used at the same time. Do not mix these two in the same grammar.
  
  __classic__ evolved over years in a fairly complex directory structure:
  
      boost/spirit/actor
      boost/spirit/attribute
      boost/spirit/core
      boost/spirit/debug
      boost/spirit/dynamic
      boost/spirit/error_handling
      boost/spirit/iterator
      boost/spirit/meta
      boost/spirit/symbols
      boost/spirit/tree
      boost/spirit/utility
  
  While introducing Spirit V2 we restructured the directory structure in order to 
  accommodate two versions at the same time. All of __classic__ now lives in 
  the directory
  
      boost/spirit/home/classic 
  
  where the directories above contain forwarding headers to the new location 
  allowing to maintain application compatibility. The forwarding headers issue a 
  warning (starting with Boost V1.38) telling the user to change their include 
  paths. Please expect the above directories/forwarding headers to go away soon.
  
  This explains the need for the directory
  
      boost/spirit/include
  
  which contains forwarding headers as well. But this time the headers won't go 
  away. We encourage application writers to use only the includes contained in 
  this directory. This allows us to restructure the directories underneath if 
  needed without worrying application compatibility. Please use those files in 
  your application only. If it turns out that some forwarding file is missing, 
  please report this as a bug.
  
  Spirit V2 is not about parsing only anymore (as __classic__). It now consists 
  out of 3 parts (sub-libraries): __qi__, __karma__, and __lex__. The header 
  files for those live in
  
      boost/spirit/home/qi
      boost/spirit/home/karma
      boost/spirit/home/lex
  
  and have forwarding headers in
  
      boost/spirit/include
  
  __qi__ is the direct successor to __classic__ as it implements a DSEL (domain 
  specific embedded language) allowing to write parsers using the syntax of C++ 
  itself (parsers in the sense turning a sequence of bytes into an internal data 
  structure). It is not compatible with __classic__, the main concepts are 
  similar, though.
  
  __karma__ is the counterpart to __qi__. It implements a similar DSEL but for 
  writing generators (i.e. the things turning internal data structures into a 
  sequence of bytes, most of the time - strings). __karma__ is the Yang to 
  __qi__'s Yin, it's almost like a mirrored picture.
  
  __lex__ is (as the name implies) a library allowing to write lexical analyzers. 
  These are either usable stand alone or can be used as a front end for __qi__ 
  parsers. If you know flex you shouldn't have problems understanding __lex__. 
  This library actually doesn't implement the lexer itself. All it does is to 
  provide an interface to pre-existing lexical analyzers. Currently it's using 
  Ben Hansons excellent __lexertl__ library (proposed for a Boost review, BTW) as 
  its underlying workhorse.
  
  Again, don't use any of the header files underneath the boost/spirit/home 
  directory directly, always include files from the boost/spirit/include 
  directory.
  
  
  [heading Why doesn't my symbol table work in a `no_case` directive?]
  
  In order to perform case-insensitive parsing (using __qi_no_case__) with a  
  symbol table (i.e. use a __qi_symbols__
  parser in a `no_case` directive), that symbol table needs to be filled with
  all-lowercase contents. Entries containing one or more uppercase characters
  will not match any input.
  
  
  [heading I'm getting a compilation error mentioning `boost::function` and/or
           `boost::function4`. What does this mean?]
  
  If you are using Visual C++ and have an error like:
  
  [pre
  error C2664: \'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const\' :
      cannot convert parameter 4 from '...' to '...'
  ]
  
  or you are using GCC and have an error like:
  
  [pre
  error: no match for call to '(const boost::function<bool ()(...)>) (...)'
  note: candidates are: ... boost::function4<R,T1,T2,T3,T4>::operator()(T0,T1,T2,T3) const [with ...\]
  ]
  
  then this FAQ entry may help you.
  
  The definition of a __rule__ or __grammar__ may contain a skip parser type. If
  it does, it means that non-terminal can only be used with a skip parser of a
  compatible type. The error above arises when this is not the case, i.e.:
  
  * a non-terminal defined with a skip parser type is used without a skip parser;
    for example, a rule with a skip parser type is used inside a `lexeme`
    directive, or a grammar with a skip parser type is used in `parse` instead of
    `phrase_parse`,
  * or a non-terminal is used with a skip parser of an incompatible type;
    for example, a rule defined with one skip parser type calls a second rule
    defined with another, incompatible skip parser type.
  
  [note The same applies to __karma__, replacing 'skip parser' and `lexeme`
        by 'delimit generator' and `verbatim`. Similarly, corresponding error 
        messages in __karma__ reference `boost::function3` and the 3rd 
        parameter (instead of the 4th).]
  
  [endsect]