rules.hpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. // rules.hpp
  2. // Copyright (c) 2007-2009 Ben Hanson (http://www.benhanson.net/)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file licence_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #ifndef BOOST_LEXER_RULES_HPP
  7. #define BOOST_LEXER_RULES_HPP
  8. #include "consts.hpp"
  9. #include <deque>
  10. #include <locale>
  11. #include <map>
  12. #include "runtime_error.hpp"
  13. #include <set>
  14. #include "size_t.hpp"
  15. #include <sstream>
  16. #include <string>
  17. #include <vector>
  18. namespace boost
  19. {
  20. namespace lexer
  21. {
  22. namespace detail
  23. {
  24. // return name of initial state
  25. template <typename CharT>
  26. struct strings;
  27. template <>
  28. struct strings<char>
  29. {
  30. static const char *initial ()
  31. {
  32. return "INITIAL";
  33. }
  34. static const char *dot ()
  35. {
  36. return ".";
  37. }
  38. static const char *all_states ()
  39. {
  40. return "*";
  41. }
  42. static const char *char_name ()
  43. {
  44. return "char";
  45. }
  46. static const char *char_prefix ()
  47. {
  48. return "";
  49. }
  50. };
  51. template <>
  52. struct strings<wchar_t>
  53. {
  54. static const wchar_t *initial ()
  55. {
  56. return L"INITIAL";
  57. }
  58. static const wchar_t *dot ()
  59. {
  60. return L".";
  61. }
  62. static const wchar_t *all_states ()
  63. {
  64. return L"*";
  65. }
  66. static const char *char_name ()
  67. {
  68. return "wchar_t";
  69. }
  70. static const char *char_prefix ()
  71. {
  72. return "L";
  73. }
  74. };
  75. }
  76. template<typename CharT>
  77. class basic_rules
  78. {
  79. public:
  80. typedef std::vector<std::size_t> id_vector;
  81. typedef std::deque<id_vector> id_vector_deque;
  82. typedef std::basic_string<CharT> string;
  83. typedef std::deque<string> string_deque;
  84. typedef std::deque<string_deque> string_deque_deque;
  85. typedef std::set<string> string_set;
  86. typedef std::pair<string, string> string_pair;
  87. typedef std::deque<string_pair> string_pair_deque;
  88. typedef std::map<string, std::size_t> string_size_t_map;
  89. typedef std::pair<string, std::size_t> string_size_t_pair;
  90. basic_rules (const regex_flags flags_ = dot_not_newline,
  91. std::size_t (*counter_ptr_) () = 0) :
  92. _flags (flags_),
  93. _counter (0),
  94. _counter_ptr (counter_ptr_)
  95. {
  96. add_state (initial ());
  97. }
  98. void clear ()
  99. {
  100. _statemap.clear ();
  101. _macrodeque.clear ();
  102. _macroset.clear ();
  103. _regexes.clear ();
  104. _ids.clear ();
  105. _unique_ids.clear ();
  106. _states.clear ();
  107. _flags = dot_not_newline;
  108. _locale = std::locale ();
  109. add_state (initial ());
  110. }
  111. void clear (const CharT *state_name_)
  112. {
  113. std::size_t state_ = state (state_name_);
  114. if (state_ != npos)
  115. {
  116. _regexes[state_].clear ();
  117. _ids[state_].clear ();
  118. _unique_ids[state_].clear ();
  119. _states[state_].clear ();
  120. }
  121. }
  122. void flags (const regex_flags flags_)
  123. {
  124. _flags = flags_;
  125. }
  126. regex_flags flags () const
  127. {
  128. return _flags;
  129. }
  130. std::size_t next_unique_id ()
  131. {
  132. return _counter_ptr ? _counter_ptr () : _counter++;
  133. }
  134. std::locale imbue (std::locale &locale_)
  135. {
  136. std::locale loc_ = _locale;
  137. _locale = locale_;
  138. return loc_;
  139. }
  140. const std::locale &locale () const
  141. {
  142. return _locale;
  143. }
  144. std::size_t state (const CharT *name_) const
  145. {
  146. std::size_t state_ = npos;
  147. typename string_size_t_map::const_iterator iter_ =
  148. _statemap.find (name_);
  149. if (iter_ != _statemap.end ())
  150. {
  151. state_ = iter_->second;
  152. }
  153. return state_;
  154. }
  155. const CharT *state (const std::size_t index_) const
  156. {
  157. if (index_ == 0)
  158. {
  159. return initial ();
  160. }
  161. else
  162. {
  163. const std::size_t vec_index_ = index_ - 1;
  164. if (vec_index_ > _lexer_state_names.size () - 1)
  165. {
  166. return 0;
  167. }
  168. else
  169. {
  170. return _lexer_state_names[vec_index_].c_str ();
  171. }
  172. }
  173. }
  174. std::size_t add_state (const CharT *name_)
  175. {
  176. validate (name_);
  177. if (_statemap.insert (string_size_t_pair (name_,
  178. _statemap.size ())).second)
  179. {
  180. _regexes.push_back (string_deque ());
  181. _ids.push_back (id_vector ());
  182. _unique_ids.push_back (id_vector ());
  183. _states.push_back (id_vector ());
  184. if (string (name_) != initial ())
  185. {
  186. _lexer_state_names.push_back (name_);
  187. }
  188. }
  189. // Initial is not stored, so no need to - 1.
  190. return _lexer_state_names.size ();
  191. }
  192. void add_macro (const CharT *name_, const CharT *regex_)
  193. {
  194. add_macro (name_, string (regex_));
  195. }
  196. void add_macro (const CharT *name_, const CharT *regex_start_,
  197. const CharT *regex_end_)
  198. {
  199. add_macro (name_, string (regex_start_, regex_end_));
  200. }
  201. void add_macro (const CharT *name_, const string &regex_)
  202. {
  203. validate (name_);
  204. typename string_set::const_iterator iter_ = _macroset.find (name_);
  205. if (iter_ == _macroset.end ())
  206. {
  207. _macrodeque.push_back (string_pair (name_, regex_));
  208. _macroset.insert (name_);
  209. }
  210. else
  211. {
  212. std::basic_stringstream<CharT> ss_;
  213. std::ostringstream os_;
  214. os_ << "Attempt to redefine MACRO '";
  215. while (*name_)
  216. {
  217. os_ << ss_.narrow (*name_++, static_cast<CharT> (' '));
  218. }
  219. os_ << "'.";
  220. throw runtime_error (os_.str ());
  221. }
  222. }
  223. void add_macros (const basic_rules<CharT> &rules_)
  224. {
  225. const string_pair_deque &macros_ = rules_.macrodeque ();
  226. typename string_pair_deque::const_iterator macro_iter_ =
  227. macros_.begin ();
  228. typename string_pair_deque::const_iterator macro_end_ =
  229. macros_.end ();
  230. for (; macro_iter_ != macro_end_; ++macro_iter_)
  231. {
  232. add_macro (macro_iter_->first.c_str (),
  233. macro_iter_->second.c_str ());
  234. }
  235. }
  236. void merge_macros (const basic_rules<CharT> &rules_)
  237. {
  238. const string_pair_deque &macros_ = rules_.macrodeque ();
  239. typename string_pair_deque::const_iterator macro_iter_ =
  240. macros_.begin ();
  241. typename string_pair_deque::const_iterator macro_end_ =
  242. macros_.end ();
  243. typename string_set::const_iterator macro_dest_iter_;
  244. typename string_set::const_iterator macro_dest_end_ = _macroset.end ();
  245. for (; macro_iter_ != macro_end_; ++macro_iter_)
  246. {
  247. macro_dest_iter_ = _macroset.find (macro_iter_->first);
  248. if (macro_dest_iter_ == macro_dest_end_)
  249. {
  250. add_macro (macro_iter_->first.c_str (),
  251. macro_iter_->second.c_str ());
  252. }
  253. }
  254. }
  255. std::size_t add (const CharT *regex_, const std::size_t id_)
  256. {
  257. return add (string (regex_), id_);
  258. }
  259. std::size_t add (const CharT *regex_start_, const CharT *regex_end_,
  260. const std::size_t id_)
  261. {
  262. return add (string (regex_start_, regex_end_), id_);
  263. }
  264. std::size_t add (const string &regex_, const std::size_t id_)
  265. {
  266. const std::size_t counter_ = next_unique_id ();
  267. check_for_invalid_id (id_);
  268. _regexes.front ().push_back (regex_);
  269. _ids.front ().push_back (id_);
  270. _unique_ids.front ().push_back (counter_);
  271. _states.front ().push_back (0);
  272. return counter_;
  273. }
  274. std::size_t add (const CharT *curr_state_, const CharT *regex_,
  275. const CharT *new_state_)
  276. {
  277. return add (curr_state_, string (regex_), new_state_);
  278. }
  279. std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
  280. const CharT *regex_end_, const CharT *new_state_)
  281. {
  282. return add (curr_state_, string (regex_start_, regex_end_),
  283. new_state_);
  284. }
  285. std::size_t add (const CharT *curr_state_, const string &regex_,
  286. const CharT *new_state_)
  287. {
  288. return add (curr_state_, regex_, 0, new_state_, false);
  289. }
  290. std::size_t add (const CharT *curr_state_, const CharT *regex_,
  291. const std::size_t id_, const CharT *new_state_)
  292. {
  293. return add (curr_state_, string (regex_), id_, new_state_);
  294. }
  295. std::size_t add (const CharT *curr_state_, const CharT *regex_start_,
  296. const CharT *regex_end_, const std::size_t id_,
  297. const CharT *new_state_)
  298. {
  299. return add (curr_state_, string (regex_start_, regex_end_), id_,
  300. new_state_);
  301. }
  302. std::size_t add (const CharT *curr_state_, const string &regex_,
  303. const std::size_t id_, const CharT *new_state_)
  304. {
  305. return add (curr_state_, regex_, id_, new_state_, true);
  306. }
  307. void add (const CharT *source_, const basic_rules<CharT> &rules_,
  308. const CharT *dest_, const CharT *to_ = detail::strings<CharT>::dot ())
  309. {
  310. const bool star_ = *source_ == '*' && *(source_ + 1) == 0;
  311. const bool dest_dot_ = *dest_ == '.' && *(dest_ + 1) == 0;
  312. const bool to_dot_ = *to_ == '.' && *(to_ + 1) == 0;
  313. std::size_t state_ = 0;
  314. const string_deque_deque &all_regexes_ = rules_.regexes ();
  315. const id_vector_deque &all_ids_ = rules_.ids ();
  316. const id_vector_deque &all_unique_ids_ = rules_.unique_ids ();
  317. const id_vector_deque &all_states_ = rules_.states ();
  318. typename string_deque::const_iterator regex_iter_;
  319. typename string_deque::const_iterator regex_end_;
  320. typename id_vector::const_iterator id_iter_;
  321. typename id_vector::const_iterator uid_iter_;
  322. typename id_vector::const_iterator state_iter_;
  323. if (star_)
  324. {
  325. typename string_deque_deque::const_iterator all_regexes_iter_ =
  326. all_regexes_.begin ();
  327. typename string_deque_deque::const_iterator all_regexes_end_ =
  328. all_regexes_.end ();
  329. typename id_vector_deque::const_iterator all_ids_iter_ =
  330. all_ids_.begin ();
  331. typename id_vector_deque::const_iterator all_uids_iter_ =
  332. all_unique_ids_.begin ();
  333. typename id_vector_deque::const_iterator all_states_iter_ =
  334. all_states_.begin ();
  335. for (; all_regexes_iter_ != all_regexes_end_;
  336. ++state_, ++all_regexes_iter_, ++all_ids_iter_,
  337. ++all_uids_iter_, ++all_states_iter_)
  338. {
  339. regex_iter_ = all_regexes_iter_->begin ();
  340. regex_end_ = all_regexes_iter_->end ();
  341. id_iter_ = all_ids_iter_->begin ();
  342. uid_iter_ = all_uids_iter_->begin ();
  343. state_iter_ = all_states_iter_->begin ();
  344. for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
  345. ++uid_iter_, ++state_iter_)
  346. {
  347. // If ..._dot_ then lookup state name from rules_; otherwise
  348. // pass name through.
  349. add (dest_dot_ ? rules_.state (state_) : dest_, *regex_iter_,
  350. *id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
  351. *uid_iter_);
  352. }
  353. }
  354. }
  355. else
  356. {
  357. const CharT *start_ = source_;
  358. string state_name_;
  359. while (*source_)
  360. {
  361. while (*source_ && *source_ != ',')
  362. {
  363. ++source_;
  364. }
  365. state_name_.assign (start_, source_);
  366. if (*source_)
  367. {
  368. ++source_;
  369. start_ = source_;
  370. }
  371. state_ = rules_.state (state_name_.c_str ());
  372. if (state_ == npos)
  373. {
  374. std::basic_stringstream<CharT> ss_;
  375. std::ostringstream os_;
  376. os_ << "Unknown state name '";
  377. source_ = state_name_.c_str ();
  378. while (*source_)
  379. {
  380. os_ << ss_.narrow (*source_++, ' ');
  381. }
  382. os_ << "'.";
  383. throw runtime_error (os_.str ());
  384. }
  385. regex_iter_ = all_regexes_[state_].begin ();
  386. regex_end_ = all_regexes_[state_].end ();
  387. id_iter_ = all_ids_[state_].begin ();
  388. uid_iter_ = all_unique_ids_[state_].begin ();
  389. state_iter_ = all_states_[state_].begin ();
  390. for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
  391. ++uid_iter_, ++state_iter_)
  392. {
  393. // If ..._dot_ then lookup state name from rules_; otherwise
  394. // pass name through.
  395. add (dest_dot_ ? state_name_.c_str () : dest_, *regex_iter_,
  396. *id_iter_, to_dot_ ? rules_.state (*state_iter_) : to_, true,
  397. *uid_iter_);
  398. }
  399. }
  400. }
  401. }
  402. /*
  403. void add (const CharT *curr_state_, const basic_rules<CharT> &rules_)
  404. {
  405. const string_deque_deque &regexes_ = rules_.regexes ();
  406. const id_vector_deque &ids_ = rules_.ids ();
  407. const id_vector_deque &unique_ids_ = rules_.unique_ids ();
  408. typename string_deque_deque::const_iterator state_regex_iter_ =
  409. regexes_.begin ();
  410. typename string_deque_deque::const_iterator state_regex_end_ =
  411. regexes_.end ();
  412. typename id_vector_deque::const_iterator state_id_iter_ =
  413. ids_.begin ();
  414. typename id_vector_deque::const_iterator state_uid_iter_ =
  415. unique_ids_.begin ();
  416. typename string_deque::const_iterator regex_iter_;
  417. typename string_deque::const_iterator regex_end_;
  418. typename id_vector::const_iterator id_iter_;
  419. typename id_vector::const_iterator uid_iter_;
  420. for (; state_regex_iter_ != state_regex_end_; ++state_regex_iter_)
  421. {
  422. regex_iter_ = state_regex_iter_->begin ();
  423. regex_end_ = state_regex_iter_->end ();
  424. id_iter_ = state_id_iter_->begin ();
  425. uid_iter_ = state_uid_iter_->begin ();
  426. for (; regex_iter_ != regex_end_; ++regex_iter_, ++id_iter_,
  427. ++uid_iter_)
  428. {
  429. add (curr_state_, *regex_iter_, *id_iter_, curr_state_, true,
  430. *uid_iter_);
  431. }
  432. }
  433. }
  434. */
  435. const string_size_t_map &statemap () const
  436. {
  437. return _statemap;
  438. }
  439. const string_pair_deque &macrodeque () const
  440. {
  441. return _macrodeque;
  442. }
  443. const string_deque_deque &regexes () const
  444. {
  445. return _regexes;
  446. }
  447. const id_vector_deque &ids () const
  448. {
  449. return _ids;
  450. }
  451. const id_vector_deque &unique_ids () const
  452. {
  453. return _unique_ids;
  454. }
  455. const id_vector_deque &states () const
  456. {
  457. return _states;
  458. }
  459. bool empty () const
  460. {
  461. typename string_deque_deque::const_iterator iter_ = _regexes.begin ();
  462. typename string_deque_deque::const_iterator end_ = _regexes.end ();
  463. bool empty_ = true;
  464. for (; iter_ != end_; ++iter_)
  465. {
  466. if (!iter_->empty ())
  467. {
  468. empty_ = false;
  469. break;
  470. }
  471. }
  472. return empty_;
  473. }
  474. static const CharT *initial ()
  475. {
  476. return detail::strings<CharT>::initial ();
  477. }
  478. static const CharT *all_states ()
  479. {
  480. return detail::strings<CharT>::all_states ();
  481. }
  482. static const CharT *dot ()
  483. {
  484. return detail::strings<CharT>::dot ();
  485. }
  486. private:
  487. string_size_t_map _statemap;
  488. string_pair_deque _macrodeque;
  489. string_set _macroset;
  490. string_deque_deque _regexes;
  491. id_vector_deque _ids;
  492. id_vector_deque _unique_ids;
  493. id_vector_deque _states;
  494. regex_flags _flags;
  495. std::size_t _counter;
  496. std::size_t (*_counter_ptr) ();
  497. std::locale _locale;
  498. string_deque _lexer_state_names;
  499. std::size_t add (const CharT *curr_state_, const string &regex_,
  500. const std::size_t id_, const CharT *new_state_, const bool check_,
  501. const std::size_t uid_ = npos)
  502. {
  503. const bool star_ = *curr_state_ == '*' && *(curr_state_ + 1) == 0;
  504. const bool dot_ = *new_state_ == '.' && *(new_state_ + 1) == 0;
  505. if (check_)
  506. {
  507. check_for_invalid_id (id_);
  508. }
  509. if (!dot_)
  510. {
  511. validate (new_state_);
  512. }
  513. std::size_t new_ = string::npos;
  514. typename string_size_t_map::const_iterator iter_;
  515. typename string_size_t_map::const_iterator end_ = _statemap.end ();
  516. id_vector states_;
  517. if (!dot_)
  518. {
  519. iter_ = _statemap.find (new_state_);
  520. if (iter_ == end_)
  521. {
  522. std::basic_stringstream<CharT> ss_;
  523. std::ostringstream os_;
  524. os_ << "Unknown state name '";
  525. while (*new_state_)
  526. {
  527. os_ << ss_.narrow (*new_state_++, ' ');
  528. }
  529. os_ << "'.";
  530. throw runtime_error (os_.str ());
  531. }
  532. new_ = iter_->second;
  533. }
  534. if (star_)
  535. {
  536. const std::size_t size_ = _statemap.size ();
  537. for (std::size_t i_ = 0; i_ < size_; ++i_)
  538. {
  539. states_.push_back (i_);
  540. }
  541. }
  542. else
  543. {
  544. const CharT *start_ = curr_state_;
  545. string state_;
  546. while (*curr_state_)
  547. {
  548. while (*curr_state_ && *curr_state_ != ',')
  549. {
  550. ++curr_state_;
  551. }
  552. state_.assign (start_, curr_state_);
  553. if (*curr_state_)
  554. {
  555. ++curr_state_;
  556. start_ = curr_state_;
  557. }
  558. validate (state_.c_str ());
  559. iter_ = _statemap.find (state_.c_str ());
  560. if (iter_ == end_)
  561. {
  562. std::basic_stringstream<CharT> ss_;
  563. std::ostringstream os_;
  564. os_ << "Unknown state name '";
  565. curr_state_ = state_.c_str ();
  566. while (*curr_state_)
  567. {
  568. os_ << ss_.narrow (*curr_state_++, ' ');
  569. }
  570. os_ << "'.";
  571. throw runtime_error (os_.str ());
  572. }
  573. states_.push_back (iter_->second);
  574. }
  575. }
  576. std::size_t first_counter_ = npos;
  577. for (std::size_t i_ = 0, size_ = states_.size (); i_ < size_; ++i_)
  578. {
  579. const std::size_t curr_ = states_[i_];
  580. _regexes[curr_].push_back (regex_);
  581. _ids[curr_].push_back (id_);
  582. if (uid_ == npos)
  583. {
  584. const std::size_t counter_ = next_unique_id ();
  585. if (first_counter_ == npos)
  586. {
  587. first_counter_ = counter_;
  588. }
  589. _unique_ids[curr_].push_back (counter_);
  590. }
  591. else
  592. {
  593. if (first_counter_ == npos)
  594. {
  595. first_counter_ = uid_;
  596. }
  597. _unique_ids[curr_].push_back (uid_);
  598. }
  599. _states[curr_].push_back (dot_ ? curr_ : new_);
  600. }
  601. return first_counter_;
  602. }
  603. void validate (const CharT *name_) const
  604. {
  605. const CharT *start_ = name_;
  606. if (*name_ != '_' && !(*name_ >= 'A' && *name_ <= 'Z') &&
  607. !(*name_ >= 'a' && *name_ <= 'z'))
  608. {
  609. std::basic_stringstream<CharT> ss_;
  610. std::ostringstream os_;
  611. os_ << "Invalid name '";
  612. while (*name_)
  613. {
  614. os_ << ss_.narrow (*name_++, ' ');
  615. }
  616. os_ << "'.";
  617. throw runtime_error (os_.str ());
  618. }
  619. else if (*name_)
  620. {
  621. ++name_;
  622. }
  623. while (*name_)
  624. {
  625. if (*name_ != '_' && *name_ != '-' &&
  626. !(*name_ >= 'A' && *name_ <= 'Z') &&
  627. !(*name_ >= 'a' && *name_ <= 'z') &&
  628. !(*name_ >= '0' && *name_ <= '9'))
  629. {
  630. std::basic_stringstream<CharT> ss_;
  631. std::ostringstream os_;
  632. os_ << "Invalid name '";
  633. name_ = start_;
  634. while (*name_)
  635. {
  636. os_ << ss_.narrow (*name_++, ' ');
  637. }
  638. os_ << "'.";
  639. throw runtime_error (os_.str ());
  640. }
  641. ++name_;
  642. }
  643. if (name_ - start_ > static_cast<std::ptrdiff_t>(max_macro_len))
  644. {
  645. std::basic_stringstream<CharT> ss_;
  646. std::ostringstream os_;
  647. os_ << "Name '";
  648. name_ = start_;
  649. while (*name_)
  650. {
  651. os_ << ss_.narrow (*name_++, ' ');
  652. }
  653. os_ << "' too long.";
  654. throw runtime_error (os_.str ());
  655. }
  656. }
  657. void check_for_invalid_id (const std::size_t id_) const
  658. {
  659. switch (id_)
  660. {
  661. case 0:
  662. throw runtime_error ("id 0 is reserved for EOF.");
  663. case npos:
  664. throw runtime_error ("id npos is reserved for the "
  665. "UNKNOWN token.");
  666. default:
  667. // OK
  668. break;
  669. }
  670. }
  671. };
  672. typedef basic_rules<char> rules;
  673. typedef basic_rules<wchar_t> wrules;
  674. }
  675. }
  676. #endif