lexer.hpp 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Spirit based lexer
  4. http://www.boost.org/
  5. Copyright (c) 2001, Daniel C. Nuffer.
  6. Copyright (c) 2001-2012 Hartmut Kaiser.
  7. Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. TODO List:
  10. X callback objects (called when a match is made.)
  11. X callback passed first & last iterator, and
  12. a reference to a lexercontrol object that supports some
  13. operations on the lexer.
  14. set state
  15. terminate
  16. state stack (push, pop, top)
  17. set new token return value
  18. ignore the current token
  19. yymore
  20. get length of matched token
  21. get current lexer state
  22. X DFA serialization to save recomputing the DFA.
  23. lexer states.
  24. organize the file into hpp and ipp. arrange the classes in a logical order.
  25. use buffering - iterator only needs be an input iterator,
  26. lexer & callback are not templatized on iterator type, but char type.
  27. next_token is templatized on iterator type.
  28. beginning/ending contexts.
  29. ^ and $
  30. DFA minimization.
  31. DFA table compression.
  32. =============================================================================*/
  33. #ifndef BOOST_SPIRIT_LEXER_HPP
  34. #define BOOST_SPIRIT_LEXER_HPP
  35. ///////////////////////////////////////////////////////////////////////////////
  36. #include <boost/config.hpp>
  37. #include <boost/throw_exception.hpp>
  38. #include <boost/spirit/include/classic_core.hpp>
  39. #include <boost/spirit/include/classic_symbols.hpp>
  40. #include <boost/spirit/include/classic_chset.hpp>
  41. #include <boost/spirit/include/classic_escape_char.hpp>
  42. #include <set>
  43. #include <map>
  44. #include <memory> // for auto_ptr/unique_ptr
  45. #include <vector>
  46. #include <stack>
  47. #include <utility> // for pair
  48. #include <iostream>
  49. #include <fstream>
  50. #include <boost/assert.hpp>
  51. #include <boost/limits.hpp>
  52. #if defined(BOOST_NO_STD_ITERATOR_TRAITS)
  53. #define BOOST_SPIRIT_IT_NS impl
  54. #else
  55. #define BOOST_SPIRIT_IT_NS std
  56. #endif
  57. ///////////////////////////////////////////////////////////////////////////////
  58. namespace boost {
  59. namespace spirit {
  60. namespace classic {
  61. typedef unsigned char uchar;
  62. typedef unsigned int node_id_t;
  63. const node_id_t invalid_node = node_id_t(-1);
  64. typedef std::set<node_id_t> node_set;
  65. typedef std::vector<uchar> uchar_vector;
  66. typedef std::map<node_id_t, node_set> followpos_t;
  67. typedef std::vector<uchar_vector> state_match_t;
  68. template <typename TokenT>
  69. class lexer_control;
  70. class bad_regex : public std::exception
  71. {
  72. };
  73. namespace lexerimpl
  74. {
  75. class node
  76. {
  77. public:
  78. virtual ~node() {}
  79. virtual node* clone() const = 0;
  80. virtual bool nullable() const = 0;
  81. virtual node_set firstpos() const = 0;
  82. virtual node_set lastpos() const = 0;
  83. virtual void compute_followpos(followpos_t& followpos) const = 0;
  84. virtual void compute_state_match(state_match_t& state_match) const = 0;
  85. virtual void get_eof_ids(node_set& eof_set) const = 0;
  86. virtual void assign_node_ids(node_id_t& node_count) = 0;
  87. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  88. virtual void dump(std::ostream& out) const = 0;
  89. #endif
  90. };
  91. class char_node : public node
  92. {
  93. public:
  94. char_node(const uchar c);
  95. char_node(const char_node& x);
  96. virtual ~char_node(){}
  97. virtual node* clone() const;
  98. virtual bool nullable() const;
  99. virtual node_set firstpos() const;
  100. virtual node_set lastpos() const;
  101. virtual void compute_followpos(followpos_t& followpos) const;
  102. virtual void compute_state_match(state_match_t& state_match ) const;
  103. virtual void get_eof_ids(node_set& eof_set) const;
  104. virtual void assign_node_ids(node_id_t& node_count);
  105. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  106. virtual void dump(std::ostream& out) const;
  107. #endif
  108. private:
  109. uchar m_char;
  110. node_id_t m_node_num;
  111. };
  112. inline
  113. char_node::char_node(const uchar c)
  114. : node()
  115. , m_char(c)
  116. , m_node_num(0)
  117. {
  118. }
  119. inline
  120. char_node::char_node(const char_node& x)
  121. : node(x)
  122. , m_char(x.m_char)
  123. , m_node_num(x.m_node_num)
  124. {
  125. }
  126. inline node *
  127. char_node::clone() const
  128. {
  129. return new char_node(*this);
  130. }
  131. inline bool
  132. char_node::nullable() const
  133. {
  134. return false;
  135. }
  136. inline node_set
  137. char_node::firstpos() const
  138. {
  139. node_set rval;
  140. rval.insert(m_node_num);
  141. return rval;
  142. }
  143. inline node_set
  144. char_node::lastpos() const
  145. {
  146. return firstpos();
  147. }
  148. inline void
  149. char_node::compute_followpos(followpos_t&) const
  150. {
  151. return;
  152. }
  153. inline void
  154. char_node::compute_state_match(state_match_t& state_match) const
  155. {
  156. if (state_match.size() < m_node_num + 1)
  157. state_match.resize(m_node_num + 1);
  158. state_match[m_node_num].resize(256);
  159. state_match[m_node_num][m_char] = 1;
  160. }
  161. inline void
  162. char_node::get_eof_ids(node_set&) const
  163. {
  164. return;
  165. }
  166. inline void
  167. char_node::assign_node_ids(node_id_t& node_count)
  168. {
  169. m_node_num = node_count++;
  170. }
  171. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  172. inline void
  173. char_node::dump(std::ostream& out) const
  174. {
  175. out << "\nchar_node m_char = " << m_char;
  176. out << " m_node_num = " << m_node_num;
  177. out << " nullable() = " << (nullable() ? "true" : "false");
  178. out << " firstpos() = ";
  179. node_set fp = firstpos();
  180. std::copy(fp.begin(), fp.end(),
  181. std::ostream_iterator<node_id_t>(out, ","));
  182. out << " lastpos() = ";
  183. node_set lp = lastpos();
  184. std::copy(lp.begin(), lp.end(),
  185. std::ostream_iterator<node_id_t>(out, ","));
  186. }
  187. #endif
  188. class epsilon_node : public node
  189. {
  190. public:
  191. epsilon_node();
  192. epsilon_node(const epsilon_node& x);
  193. virtual ~epsilon_node(){}
  194. virtual node* clone() const;
  195. virtual bool nullable() const;
  196. virtual node_set firstpos() const;
  197. virtual node_set lastpos() const;
  198. virtual void compute_followpos(followpos_t& followpos) const;
  199. virtual void compute_state_match(state_match_t& state_match ) const;
  200. virtual void get_eof_ids(node_set& eof_set) const;
  201. virtual void assign_node_ids(node_id_t& node_count);
  202. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  203. virtual void dump(std::ostream& out) const;
  204. #endif
  205. private:
  206. node_id_t m_node_num;
  207. };
  208. inline
  209. epsilon_node::epsilon_node()
  210. : node()
  211. , m_node_num(0)
  212. {
  213. }
  214. inline
  215. epsilon_node::epsilon_node(const epsilon_node& x)
  216. : node(x)
  217. , m_node_num(x.m_node_num)
  218. {
  219. }
  220. inline node *
  221. epsilon_node::clone() const
  222. {
  223. return new epsilon_node(*this);
  224. }
  225. inline bool
  226. epsilon_node::nullable() const
  227. {
  228. return true;
  229. }
  230. inline node_set
  231. epsilon_node::firstpos() const
  232. {
  233. return node_set();
  234. }
  235. inline node_set
  236. epsilon_node::lastpos() const
  237. {
  238. return node_set();
  239. }
  240. inline void
  241. epsilon_node::compute_followpos(followpos_t&) const
  242. {
  243. return;
  244. }
  245. inline void
  246. epsilon_node::compute_state_match(state_match_t& state_match) const
  247. {
  248. if (state_match.size() < m_node_num + 1)
  249. state_match.resize(m_node_num + 1);
  250. state_match[m_node_num].resize(256, 1);
  251. }
  252. inline void
  253. epsilon_node::get_eof_ids(node_set&) const
  254. {
  255. return;
  256. }
  257. inline void
  258. epsilon_node::assign_node_ids(node_id_t& node_count)
  259. {
  260. m_node_num = node_count++;
  261. }
  262. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  263. inline void
  264. epsilon_node::dump(std::ostream& out) const
  265. {
  266. out << "\nepsilon_node";
  267. out << " m_node_num = " << m_node_num;
  268. out << " nullable() = " << (nullable() ? "true" : "false");
  269. out << " firstpos() = ";
  270. node_set fp = firstpos();
  271. std::copy(fp.begin(), fp.end(),
  272. std::ostream_iterator<node_id_t>(out, ","));
  273. out << " lastpos() = ";
  274. node_set lp = lastpos();
  275. std::copy(lp.begin(), lp.end(),
  276. std::ostream_iterator<node_id_t>(out, ","));
  277. }
  278. #endif
  279. class or_node : public node
  280. {
  281. public:
  282. or_node(node* left, node* right);
  283. or_node(const or_node& x);
  284. virtual ~or_node(){}
  285. virtual node* clone() const;
  286. virtual bool nullable() const;
  287. virtual node_set firstpos() const;
  288. virtual node_set lastpos() const;
  289. virtual void compute_followpos(followpos_t& followpos) const;
  290. virtual void compute_state_match(state_match_t& state_match ) const;
  291. virtual void get_eof_ids(node_set& eof_set) const;
  292. virtual void assign_node_ids(node_id_t& node_count);
  293. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  294. virtual void dump(std::ostream& out) const;
  295. #endif
  296. private:
  297. #ifndef BOOST_NO_CXX11_SMART_PTR
  298. std::unique_ptr<node> m_left;
  299. std::unique_ptr<node> m_right;
  300. #else
  301. std::auto_ptr<node> m_left;
  302. std::auto_ptr<node> m_right;
  303. #endif
  304. };
  305. inline
  306. or_node::or_node(node* left, node* right)
  307. : node()
  308. , m_left(left)
  309. , m_right(right)
  310. {
  311. }
  312. inline
  313. or_node::or_node(const or_node& x)
  314. : node(x)
  315. , m_left(x.m_left->clone())
  316. , m_right(x.m_right->clone())
  317. {
  318. }
  319. inline node *
  320. or_node::clone() const
  321. {
  322. return new or_node(m_left->clone(), m_right->clone());
  323. }
  324. inline bool
  325. or_node::nullable() const
  326. {
  327. return m_left->nullable() || m_right->nullable();
  328. }
  329. inline node_set
  330. or_node::firstpos() const
  331. {
  332. node_set rval;
  333. node_set l = m_left->firstpos();
  334. node_set r = m_right->firstpos();
  335. std::set_union(l.begin(), l.end(), r.begin(), r.end(),
  336. std::inserter(rval, rval.begin()));
  337. return rval;
  338. }
  339. inline node_set
  340. or_node::lastpos() const
  341. {
  342. node_set rval;
  343. node_set l = m_left->lastpos();
  344. node_set r = m_right->lastpos();
  345. std::set_union(l.begin(), l.end(), r.begin(), r.end(),
  346. std::inserter(rval, rval.begin()));
  347. return rval;
  348. }
  349. inline void
  350. or_node::compute_followpos(followpos_t& followpos) const
  351. {
  352. m_left->compute_followpos(followpos);
  353. m_right->compute_followpos(followpos);
  354. }
  355. inline void
  356. or_node::compute_state_match(state_match_t& state_match) const
  357. {
  358. m_left->compute_state_match(state_match);
  359. m_right->compute_state_match(state_match);
  360. }
  361. inline void
  362. or_node::get_eof_ids(node_set& eof_nodes) const
  363. {
  364. m_left->get_eof_ids(eof_nodes);
  365. m_right->get_eof_ids(eof_nodes);
  366. }
  367. inline void
  368. or_node::assign_node_ids(node_id_t& node_count)
  369. {
  370. m_left->assign_node_ids(node_count);
  371. m_right->assign_node_ids(node_count);
  372. }
  373. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  374. inline void
  375. or_node::dump(std::ostream& out) const
  376. {
  377. m_left->dump(out);
  378. out << "\nor_node";
  379. out << " nullable() = " << (nullable() ? "true" : "false");
  380. out << " firstpos() = ";
  381. node_set fp = firstpos();
  382. std::copy(fp.begin(), fp.end(),
  383. std::ostream_iterator<node_id_t>(out, ","));
  384. out << " lastpos() = ";
  385. node_set lp = lastpos();
  386. std::copy(lp.begin(), lp.end(),
  387. std::ostream_iterator<node_id_t>(out, ","));
  388. m_right->dump(out);
  389. }
  390. #endif
  391. class cat_node : public node
  392. {
  393. public:
  394. cat_node(node* left, node* right);
  395. cat_node(const cat_node& x);
  396. virtual ~cat_node(){}
  397. virtual node* clone() const;
  398. virtual bool nullable() const;
  399. virtual node_set firstpos() const;
  400. virtual node_set lastpos() const;
  401. virtual void compute_followpos(followpos_t& followpos) const;
  402. virtual void compute_state_match(state_match_t& state_match ) const;
  403. virtual void get_eof_ids(node_set& eof_set) const;
  404. virtual void assign_node_ids(node_id_t& node_count);
  405. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  406. virtual void dump(std::ostream& out) const;
  407. #endif
  408. private:
  409. #ifndef BOOST_NO_CXX11_SMART_PTR
  410. std::unique_ptr<node> m_left;
  411. std::unique_ptr<node> m_right;
  412. #else
  413. std::auto_ptr<node> m_left;
  414. std::auto_ptr<node> m_right;
  415. #endif
  416. };
  417. inline
  418. cat_node::cat_node(node* left, node* right)
  419. : node()
  420. , m_left(left)
  421. , m_right(right)
  422. {
  423. }
  424. inline
  425. cat_node::cat_node(const cat_node& x)
  426. : node(x)
  427. , m_left(x.m_left->clone())
  428. , m_right(x.m_right->clone())
  429. {
  430. }
  431. inline node *
  432. cat_node::clone() const
  433. {
  434. return new cat_node(m_left->clone(), m_right->clone());
  435. }
  436. inline bool
  437. cat_node::nullable() const
  438. {
  439. return m_left->nullable() && m_right->nullable();
  440. }
  441. inline node_set
  442. cat_node::firstpos() const
  443. {
  444. if (m_left->nullable())
  445. {
  446. node_set rval;
  447. node_set l = m_left->firstpos();
  448. node_set r = m_right->firstpos();
  449. std::set_union(l.begin(), l.end(), r.begin(), r.end(),
  450. std::inserter(rval, rval.begin()));
  451. return rval;
  452. }
  453. else
  454. {
  455. return m_left->firstpos();
  456. }
  457. }
  458. inline node_set
  459. cat_node::lastpos() const
  460. {
  461. if (m_right->nullable())
  462. {
  463. node_set rval;
  464. node_set l = m_left->lastpos();
  465. node_set r = m_right->lastpos();
  466. std::set_union(l.begin(), l.end(), r.begin(), r.end(),
  467. std::inserter(rval, rval.begin()));
  468. return rval;
  469. }
  470. else
  471. {
  472. return m_right->lastpos();
  473. }
  474. }
  475. inline void
  476. cat_node::compute_followpos(followpos_t& followpos) const
  477. {
  478. node_set l = m_left->lastpos();
  479. for (node_set::iterator i = l.begin();
  480. i != l.end();
  481. ++i)
  482. {
  483. node_set rf = m_right->firstpos();
  484. followpos[*i].insert(rf.begin(), rf.end());
  485. }
  486. m_left->compute_followpos(followpos);
  487. m_right->compute_followpos(followpos);
  488. }
  489. inline void
  490. cat_node::compute_state_match(state_match_t& state_match) const
  491. {
  492. m_left->compute_state_match(state_match);
  493. m_right->compute_state_match(state_match);
  494. }
  495. inline void
  496. cat_node::get_eof_ids(node_set& eof_nodes) const
  497. {
  498. m_left->get_eof_ids(eof_nodes);
  499. m_right->get_eof_ids(eof_nodes);
  500. }
  501. inline void
  502. cat_node::assign_node_ids(node_id_t& node_count)
  503. {
  504. m_left->assign_node_ids(node_count);
  505. m_right->assign_node_ids(node_count);
  506. }
  507. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  508. inline void
  509. cat_node::dump(std::ostream& out) const
  510. {
  511. m_left->dump(out);
  512. out << "\ncat_node";
  513. out << " nullable() = " << (nullable() ? "true" : "false");
  514. out << " firstpos() = ";
  515. node_set fp = firstpos();
  516. std::copy(fp.begin(), fp.end(),
  517. std::ostream_iterator<node_id_t>(out, ","));
  518. out << " lastpos() = ";
  519. node_set lp = lastpos();
  520. std::copy(lp.begin(), lp.end(),
  521. std::ostream_iterator<node_id_t>(out, ","));
  522. m_right->dump(out);
  523. }
  524. #endif
  525. class star_node : public node
  526. {
  527. public:
  528. star_node(node* left);
  529. star_node(const star_node& x);
  530. virtual ~star_node(){}
  531. virtual node* clone() const;
  532. virtual bool nullable() const;
  533. virtual node_set firstpos() const;
  534. virtual node_set lastpos() const;
  535. virtual void compute_followpos(followpos_t& followpos) const;
  536. virtual void compute_state_match(state_match_t& state_match ) const;
  537. virtual void get_eof_ids(node_set& eof_set) const;
  538. virtual void assign_node_ids(node_id_t& node_count);
  539. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  540. virtual void dump(std::ostream& out) const;
  541. #endif
  542. private:
  543. #ifndef BOOST_NO_CXX11_SMART_PTR
  544. std::unique_ptr<node> m_left;
  545. #else
  546. std::auto_ptr<node> m_left;
  547. #endif
  548. };
  549. inline
  550. star_node::star_node(node* left)
  551. : node()
  552. , m_left(left)
  553. {
  554. }
  555. inline
  556. star_node::star_node(const star_node& x)
  557. : node(x)
  558. , m_left(x.m_left->clone())
  559. {
  560. }
  561. inline node *
  562. star_node::clone() const
  563. {
  564. return new star_node(m_left->clone());
  565. }
  566. inline bool
  567. star_node::nullable() const
  568. {
  569. return true;
  570. }
  571. inline node_set
  572. star_node::firstpos() const
  573. {
  574. return m_left->firstpos();
  575. }
  576. inline node_set
  577. star_node::lastpos() const
  578. {
  579. return m_left->lastpos();
  580. }
  581. inline void
  582. star_node::compute_followpos(followpos_t& followpos) const
  583. {
  584. node_set lp = this->lastpos();
  585. for (node_set::iterator i = lp.begin();
  586. i != lp.end();
  587. ++i)
  588. {
  589. node_set fp = this->firstpos();
  590. followpos[*i].insert(fp.begin(), fp.end());
  591. }
  592. m_left->compute_followpos(followpos);
  593. }
  594. inline void
  595. star_node::compute_state_match(state_match_t& state_match) const
  596. {
  597. m_left->compute_state_match(state_match);
  598. }
  599. inline void
  600. star_node::get_eof_ids(node_set& eof_nodes) const
  601. {
  602. m_left->get_eof_ids(eof_nodes);
  603. }
  604. inline void
  605. star_node::assign_node_ids(node_id_t& node_count)
  606. {
  607. m_left->assign_node_ids(node_count);
  608. }
  609. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  610. inline void
  611. star_node::dump(std::ostream& out) const
  612. {
  613. m_left->dump(out);
  614. out << "\nstar_node";
  615. out << " nullable() = " << (nullable() ? "true" : "false");
  616. out << " firstpos() = ";
  617. node_set fp = firstpos();
  618. std::copy(fp.begin(), fp.end(),
  619. std::ostream_iterator<node_id_t>(out, ","));
  620. out << " lastpos() = ";
  621. node_set lp = lastpos();
  622. std::copy(lp.begin(), lp.end(),
  623. std::ostream_iterator<node_id_t>(out, ","));
  624. }
  625. #endif
  626. class eof_node : public node
  627. {
  628. public:
  629. eof_node();
  630. eof_node(const eof_node& x);
  631. virtual ~eof_node(){}
  632. virtual node* clone() const;
  633. virtual bool nullable() const;
  634. virtual node_set firstpos() const;
  635. virtual node_set lastpos() const;
  636. virtual void compute_followpos(followpos_t& followpos) const;
  637. virtual void compute_state_match(state_match_t& state_match ) const;
  638. virtual void get_eof_ids(node_set& eof_set) const;
  639. virtual void assign_node_ids(node_id_t& node_count);
  640. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  641. virtual void dump(std::ostream& out) const;
  642. #endif
  643. private:
  644. node_id_t m_node_num;
  645. };
  646. inline
  647. eof_node::eof_node()
  648. : node()
  649. , m_node_num(0)
  650. {
  651. }
  652. inline
  653. eof_node::eof_node(const eof_node& x)
  654. : node(x)
  655. , m_node_num(x.m_node_num)
  656. {
  657. }
  658. inline node *
  659. eof_node::clone() const
  660. {
  661. return new eof_node(*this);
  662. }
  663. inline bool
  664. eof_node::nullable() const
  665. {
  666. return false;
  667. }
  668. inline node_set
  669. eof_node::firstpos() const
  670. {
  671. node_set rval;
  672. rval.insert(m_node_num);
  673. return rval;
  674. }
  675. inline node_set
  676. eof_node::lastpos() const
  677. {
  678. node_set rval;
  679. rval.insert(m_node_num);
  680. return rval;
  681. }
  682. inline void
  683. eof_node::compute_followpos(followpos_t&) const
  684. {
  685. return;
  686. }
  687. inline void
  688. eof_node::compute_state_match(state_match_t& state_match) const
  689. {
  690. if (state_match.size() < m_node_num + 1)
  691. state_match.resize(m_node_num + 1);
  692. state_match[m_node_num].resize(256, 0);
  693. }
  694. inline void
  695. eof_node::get_eof_ids(node_set& eof_nodes) const
  696. {
  697. eof_nodes.insert(m_node_num);
  698. }
  699. inline void
  700. eof_node::assign_node_ids(node_id_t& node_count)
  701. {
  702. m_node_num = node_count++;
  703. }
  704. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  705. inline void
  706. eof_node::dump(std::ostream& out) const
  707. {
  708. out << "\neof_node";
  709. out << " m_node_num = " << m_node_num;
  710. out << " nullable() = " << (nullable() ? "true" : "false");
  711. out << " firstpos() = ";
  712. node_set fp = firstpos();
  713. std::copy(fp.begin(), fp.end(),
  714. std::ostream_iterator<node_id_t>(out, ","));
  715. out << " lastpos() = ";
  716. node_set lp = lastpos();
  717. std::copy(lp.begin(), lp.end(),
  718. std::ostream_iterator<node_id_t>(out, ","));
  719. }
  720. #endif
  721. class ccl_node : public node
  722. {
  723. public:
  724. ccl_node(const std::vector<uchar>& v);
  725. ccl_node(const uchar c1, const uchar c2);
  726. ccl_node(const ccl_node& x);
  727. virtual ~ccl_node(){}
  728. virtual node* clone() const;
  729. virtual bool nullable() const;
  730. virtual node_set firstpos() const;
  731. virtual node_set lastpos() const;
  732. virtual void compute_followpos(followpos_t& followpos) const;
  733. virtual void compute_state_match(state_match_t& state_match ) const;
  734. virtual void get_eof_ids(node_set& eof_set) const;
  735. virtual void assign_node_ids(node_id_t& node_count);
  736. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  737. virtual void dump(std::ostream& out) const;
  738. #endif
  739. private:
  740. std::vector<uchar> m_match;
  741. node_id_t m_node_num;
  742. };
  743. inline
  744. ccl_node::ccl_node(const std::vector<uchar>& v)
  745. : node()
  746. , m_match(v)
  747. , m_node_num(0)
  748. {
  749. m_match.resize(256); // make sure it's the right size
  750. }
  751. inline
  752. ccl_node::ccl_node(const uchar c1, const uchar c2)
  753. : node()
  754. , m_match(256, uchar(0))
  755. , m_node_num(0)
  756. {
  757. BOOST_ASSERT(c1 < c2);
  758. for (std::size_t i = c1; i <= std::size_t(c2); ++i)
  759. {
  760. m_match[i] = 1;
  761. }
  762. }
  763. inline
  764. ccl_node::ccl_node(const ccl_node& x)
  765. : node(x)
  766. , m_match(x.m_match)
  767. , m_node_num(x.m_node_num)
  768. {
  769. }
  770. inline node *
  771. ccl_node::clone() const
  772. {
  773. return new ccl_node(*this);
  774. }
  775. inline bool
  776. ccl_node::nullable() const
  777. {
  778. return false;
  779. }
  780. inline node_set
  781. ccl_node::firstpos() const
  782. {
  783. node_set rval;
  784. rval.insert(m_node_num);
  785. return rval;
  786. }
  787. inline node_set
  788. ccl_node::lastpos() const
  789. {
  790. return firstpos();
  791. }
  792. inline void
  793. ccl_node::compute_followpos(followpos_t&) const
  794. {
  795. return;
  796. }
  797. inline void
  798. ccl_node::compute_state_match(state_match_t& state_match) const
  799. {
  800. if (state_match.size() < m_node_num + 1)
  801. state_match.resize(m_node_num + 1);
  802. state_match[m_node_num] = m_match;
  803. }
  804. inline void
  805. ccl_node::get_eof_ids(node_set&) const
  806. {
  807. return;
  808. }
  809. inline void
  810. ccl_node::assign_node_ids(node_id_t& node_count)
  811. {
  812. m_node_num = node_count++;
  813. }
  814. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  815. inline void
  816. ccl_node::dump(std::ostream& out) const
  817. {
  818. out << "\nccl_node m_match = ";
  819. for (std::size_t i = 0; i < m_match.size(); ++i)
  820. {
  821. if (m_match[i])
  822. out << i << ", ";
  823. }
  824. out << " m_node_num = " << m_node_num;
  825. out << " nullable() = " << (nullable() ? "true" : "false");
  826. out << " firstpos() = ";
  827. node_set fp = firstpos();
  828. std::copy(fp.begin(), fp.end(),
  829. std::ostream_iterator<node_id_t>(out, ","));
  830. out << " lastpos() = ";
  831. node_set lp = lastpos();
  832. std::copy(lp.begin(), lp.end(),
  833. std::ostream_iterator<node_id_t>(out, ","));
  834. }
  835. #endif
  836. template <typename ScannerT>
  837. class make_concat
  838. {
  839. typedef typename ScannerT::iterator_t iterator_type;
  840. public:
  841. make_concat(std::stack<node*>& the_stack)
  842. : m_stack(the_stack)
  843. {}
  844. void operator()(iterator_type const &, iterator_type const &) const
  845. {
  846. node* right = m_stack.top();
  847. m_stack.pop();
  848. node* left = m_stack.top();
  849. m_stack.pop();
  850. node* newnode = new cat_node(left, right);
  851. m_stack.push(newnode);
  852. }
  853. std::stack<node*>& m_stack;
  854. };
  855. template <int CharTSize>
  856. struct get_byte_aux;
  857. template<>
  858. struct get_byte_aux<1>
  859. {
  860. template <typename CharT>
  861. unsigned char operator()(CharT c, unsigned int byte)
  862. {
  863. BOOST_ASSERT(byte == 0);
  864. return c;
  865. }
  866. };
  867. template<>
  868. struct get_byte_aux<2>
  869. {
  870. template <typename CharT>
  871. unsigned char operator()(CharT c, unsigned int byte)
  872. {
  873. static unsigned long mask[] =
  874. {
  875. 0xFF00,
  876. 0x00FF
  877. };
  878. BOOST_ASSERT(byte < 2);
  879. return (c & mask[byte]) >> ((sizeof(c) - 1 - byte) * 8);
  880. }
  881. };
  882. template<>
  883. struct get_byte_aux<4>
  884. {
  885. template <typename CharT>
  886. unsigned char operator()(CharT c, unsigned int byte)
  887. {
  888. static unsigned long mask[] =
  889. {
  890. 0xFF000000,
  891. 0x00FF0000,
  892. 0x0000FF00,
  893. 0x000000FF
  894. };
  895. BOOST_ASSERT(byte < 4);
  896. return (c & mask[byte]) >> ((sizeof(c) - 1 - byte) * 8);
  897. }
  898. };
  899. template <typename CharT>
  900. inline unsigned char
  901. get_byte(CharT c, unsigned int byte)
  902. {
  903. return get_byte_aux<sizeof(c)>()(c, byte);
  904. }
  905. template <typename ScannerT>
  906. class make_star
  907. {
  908. typedef typename ScannerT::iterator_t iterator_type;
  909. public:
  910. typedef
  911. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  912. char_t;
  913. make_star(std::stack<node*>& the_stack)
  914. : m_stack(the_stack)
  915. {}
  916. void operator()(const char_t) const
  917. {
  918. node* left = m_stack.top();
  919. m_stack.pop();
  920. node* newnode = new star_node(left);
  921. m_stack.push(newnode);
  922. }
  923. std::stack<node*>& m_stack;
  924. };
  925. template <typename ScannerT>
  926. class make_or
  927. {
  928. typedef typename ScannerT::iterator_t iterator_type;
  929. public:
  930. make_or(std::stack<node*>& the_stack)
  931. : m_stack(the_stack)
  932. {}
  933. void operator()(iterator_type const&, iterator_type const&) const
  934. {
  935. node* right = m_stack.top();
  936. m_stack.pop();
  937. node* left = m_stack.top();
  938. m_stack.pop();
  939. node* newnode = new or_node(left, right);
  940. m_stack.push(newnode);
  941. }
  942. std::stack<node*>& m_stack;
  943. };
  944. template <typename ScannerT>
  945. class make_plus
  946. {
  947. typedef typename ScannerT::iterator_t iterator_type;
  948. public:
  949. typedef
  950. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  951. char_t;
  952. make_plus(std::stack<node*>& the_stack)
  953. : m_stack(the_stack)
  954. {}
  955. void operator()(const char_t) const
  956. {
  957. node* left = m_stack.top();
  958. m_stack.pop();
  959. node* copy = left->clone();
  960. node* new_star = new star_node(copy);
  961. node* new_cat = new cat_node(left, new_star);
  962. m_stack.push(new_cat);
  963. }
  964. std::stack<node*>& m_stack;
  965. };
  966. template <typename ScannerT>
  967. class make_optional
  968. {
  969. typedef typename ScannerT::iterator_t iterator_type;
  970. public:
  971. typedef
  972. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  973. char_t;
  974. make_optional(std::stack<node*>& the_stack)
  975. : m_stack(the_stack)
  976. {}
  977. void operator()(const char_t) const
  978. {
  979. node* left = m_stack.top();
  980. m_stack.pop();
  981. node* new_or = new or_node(left, new epsilon_node());
  982. m_stack.push(new_or);
  983. }
  984. std::stack<node*>& m_stack;
  985. };
  986. ///////////////////////////////////////////////////////////////////////////////
  987. // utility function
  988. template <typename CharT>
  989. inline utility::impl::range<CharT> const&
  990. full_range()
  991. {
  992. static utility::impl::range<CharT> full((std::numeric_limits<CharT>::min)(),
  993. (std::numeric_limits<CharT>::max)());
  994. return full;
  995. }
  996. namespace ccl_utils
  997. {
  998. template <typename char_t>
  999. inline utility::impl::range_run<char_t>
  1000. negate_range_run(
  1001. const utility::impl::range_run<char_t>& rr)
  1002. {
  1003. utility::impl::range_run<char_t> newrr;
  1004. newrr.set(full_range<char_t>());
  1005. for (typename utility::impl::range_run<char_t>::const_iterator iter = rr.begin();
  1006. iter != rr.end(); ++iter)
  1007. newrr.clear(*iter);
  1008. return newrr;
  1009. }
  1010. template <typename char_t>
  1011. inline node*
  1012. create_mb_node_seq(char_t c)
  1013. {
  1014. node* newnode = new char_node(get_byte(c, 0));
  1015. for (unsigned int i = 1; i < sizeof(c); ++i)
  1016. {
  1017. node* cnode = new char_node(get_byte(c, i));
  1018. node* top_node = new cat_node(newnode, cnode);
  1019. newnode = top_node;
  1020. }
  1021. return newnode;
  1022. }
  1023. template <typename char_t>
  1024. inline void
  1025. handle_mb_char(char_t c, bool first_time,
  1026. std::stack<node*>& stack)
  1027. {
  1028. node* newnode = create_mb_node_seq(c);
  1029. if (first_time)
  1030. {
  1031. stack.push(newnode);
  1032. }
  1033. else
  1034. {
  1035. node* top = stack.top();
  1036. stack.pop();
  1037. node* newtop = new or_node(top, newnode);
  1038. stack.push(newtop);
  1039. }
  1040. }
  1041. // forward decl only
  1042. template <typename char_t>
  1043. inline void
  1044. handle_mb_range(char_t c1, char_t c2, bool first_time,
  1045. std::stack<node*>& stack);
  1046. template <typename char_t>
  1047. inline void
  1048. create_nodes(const utility::impl::range_run<char_t>& rr,
  1049. std::stack<node*>& stack)
  1050. {
  1051. if (sizeof(char_t) == 1)
  1052. {
  1053. std::vector<uchar> ccl;
  1054. ccl.resize(256);
  1055. for (typename utility::impl::range_run<char_t>::const_iterator iter = rr.begin();
  1056. iter != rr.end(); ++iter)
  1057. {
  1058. for (int i = iter->first; i <= iter->last; ++i)
  1059. {
  1060. // this is always true because of the limited datatype
  1061. // BOOST_ASSERT(uchar(i) < 256 && ccl.size() == 256);
  1062. ccl[uchar(i)] = 1;
  1063. }
  1064. }
  1065. node* new_ccl = new ccl_node(ccl);
  1066. stack.push(new_ccl);
  1067. }
  1068. else
  1069. {
  1070. bool mb_first_time = true;
  1071. for (typename utility::impl::range_run<char_t>::const_iterator iter = rr.begin();
  1072. iter != rr.end(); ++iter)
  1073. {
  1074. if (iter->first == iter->last)
  1075. {
  1076. handle_mb_char(iter->first, mb_first_time, stack);
  1077. }
  1078. else
  1079. {
  1080. handle_mb_range(iter->first, iter->last, mb_first_time, stack);
  1081. }
  1082. mb_first_time = false;
  1083. }
  1084. }
  1085. }
  1086. template <typename char_t>
  1087. inline std::size_t
  1088. compute_differing_byte(char_t c1, char_t c2)
  1089. {
  1090. std::size_t rval = 0;
  1091. while (rval < sizeof(c1) &&
  1092. get_byte(c1, (unsigned int)rval) == get_byte(c2, (unsigned int)rval))
  1093. {
  1094. ++rval;
  1095. }
  1096. return rval;
  1097. }
  1098. template <typename char_t>
  1099. inline node*
  1100. create_mb_node_type1(std::size_t j, char_t c1, char_t c2)
  1101. {
  1102. std::size_t diff = get_byte(c2, (unsigned int)j) -
  1103. get_byte(c1, (unsigned int)j);
  1104. if (diff == 1) {
  1105. return 0;
  1106. }
  1107. else if (diff == 2) {
  1108. return new char_node(get_byte(c1, (unsigned int)j)+1);
  1109. }
  1110. else {
  1111. return new ccl_node(get_byte(c1, (unsigned int)j)+1,
  1112. get_byte(c2, (unsigned int)j)-1);
  1113. }
  1114. }
  1115. template <typename char_t>
  1116. inline node *
  1117. create_mb_node_for_byte(std::size_t i, std::size_t j, std::size_t sizem1,
  1118. std::size_t differing_byte, char_t c1, char_t c2, node* newnode)
  1119. {
  1120. node* cnode;
  1121. if (i == sizem1 && j == differing_byte && j != sizem1)
  1122. {
  1123. node* tmp = create_mb_node_type1(j, c1, c2);
  1124. if (tmp == 0)
  1125. {
  1126. delete newnode;
  1127. return 0;
  1128. }
  1129. else
  1130. cnode = tmp;
  1131. }
  1132. else if (i == differing_byte && j == sizem1)
  1133. {
  1134. if (i != sizem1) {
  1135. cnode = new ccl_node(get_byte(c1, (unsigned int)j), 0xFF);
  1136. }
  1137. else {
  1138. cnode = new ccl_node(get_byte(c1, (unsigned int)j),
  1139. get_byte(c2, (unsigned int)j));
  1140. }
  1141. }
  1142. else if (i != differing_byte && i != sizem1 &&
  1143. j == (sizem1 - i + differing_byte))
  1144. {
  1145. cnode = new ccl_node(get_byte(c1, (unsigned int)j)+1, 0xFF);
  1146. }
  1147. else if (i + j - differing_byte > sizem1) {
  1148. cnode = new ccl_node(0, 0xFF);
  1149. }
  1150. else {//if (is plain)
  1151. cnode = new char_node(get_byte(c1, (unsigned int)j));
  1152. }
  1153. node* top_node = new cat_node(newnode, cnode);
  1154. return top_node;
  1155. }
  1156. // On platforms, where wchar_t is a typedef for unsigned short, the
  1157. // comparision for a negative value is pointless
  1158. template <bool is_signed>
  1159. struct correct_char_aux {
  1160. };
  1161. template <>
  1162. struct correct_char_aux<true> {
  1163. template <typename char_t>
  1164. static char_t correct(char_t c) { if (c < 0) c = 0; return c; }
  1165. };
  1166. template <>
  1167. struct correct_char_aux<false> {
  1168. template <typename char_t>
  1169. static char_t correct(char_t c) { return c; }
  1170. };
  1171. template <typename char_t>
  1172. struct correct_char
  1173. {
  1174. static char_t correct(char_t c)
  1175. {
  1176. return correct_char_aux<std::numeric_limits<char_t>::is_signed >::
  1177. correct(c);
  1178. }
  1179. };
  1180. template <typename char_t>
  1181. inline void
  1182. handle_mb_range(char_t c1, char_t c2, bool first_time,
  1183. std::stack<node*>& stack)
  1184. {
  1185. // The algorithm can't handle negative value chars, which don't make
  1186. // much sense anyway. This comparision is pointless for wchar_t's on
  1187. // platforms, where wchar_t is a typedef for unsigned short
  1188. c1 = correct_char<char_t>::correct(c1);
  1189. //if (c1 < 0)
  1190. // c1 = 0;
  1191. BOOST_ASSERT(c1 < c2);
  1192. node* newnode = 0;
  1193. node* savednode = 0;
  1194. const std::size_t differing_byte = compute_differing_byte(c1, c2);
  1195. const std::size_t sizem1 = sizeof(c1) - 1;
  1196. const std::size_t ndb = sizem1 - differing_byte;
  1197. for (std::size_t i = differing_byte; i < sizeof(c1); ++i)
  1198. {
  1199. // generate node for the first byte
  1200. if (differing_byte == 0 && i == ndb)
  1201. {
  1202. node* tmp = create_mb_node_type1(0, c1, c2);
  1203. if (tmp == 0)
  1204. continue;
  1205. else
  1206. newnode = tmp;
  1207. }
  1208. else
  1209. {
  1210. newnode = new char_node(get_byte(c1, 0));
  1211. }
  1212. for (std::size_t j = 1; j < sizeof(c1); ++j)
  1213. {
  1214. newnode = create_mb_node_for_byte(i, j, sizem1, differing_byte,
  1215. c1, c2, newnode);
  1216. if (newnode == 0)
  1217. goto end_outer_for;
  1218. }
  1219. // or together the various parts
  1220. if (savednode)
  1221. {
  1222. node* top_node = new or_node(savednode, newnode);
  1223. savednode = top_node;
  1224. }
  1225. else
  1226. {
  1227. savednode = newnode;
  1228. }
  1229. end_outer_for:
  1230. continue;
  1231. }
  1232. for (std::size_t k = 0; k < ndb; ++k)
  1233. {
  1234. newnode = new char_node(get_byte(c2, 0));
  1235. for (std::size_t j = 1; j < sizeof(c2); ++j)
  1236. {
  1237. node* cnode;
  1238. if (k == differing_byte && j == sizem1 && k != sizem1)
  1239. cnode = new ccl_node(0, get_byte(c2, (unsigned int)j));
  1240. else if (k != differing_byte && k != sizem1 &&
  1241. j == (sizem1 - k + differing_byte))
  1242. cnode = new ccl_node(0, get_byte(c2, (unsigned int)j)-1);
  1243. else if (k + j - differing_byte > sizem1)
  1244. cnode = new ccl_node(0, 0xFF);
  1245. else //if (is plain)
  1246. cnode = new char_node(get_byte(c2, (unsigned int)j));
  1247. node* top_node = new cat_node(newnode, cnode);
  1248. newnode = top_node;
  1249. }
  1250. // or together the various parts
  1251. if (savednode)
  1252. {
  1253. node* top_node = new or_node(savednode, newnode);
  1254. savednode = top_node;
  1255. }
  1256. else
  1257. {
  1258. savednode = newnode;
  1259. }
  1260. }
  1261. if (first_time)
  1262. {
  1263. stack.push(savednode);
  1264. }
  1265. else
  1266. {
  1267. node* top = stack.top();
  1268. stack.pop();
  1269. node* newtop = new or_node(top, savednode);
  1270. stack.push(newtop);
  1271. }
  1272. }
  1273. } // namespace ccl_utils
  1274. template <typename ScannerT>
  1275. class make_char
  1276. {
  1277. typedef typename ScannerT::iterator_t iterator_type;
  1278. public:
  1279. typedef
  1280. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1281. char_t;
  1282. make_char(std::stack<node*>& the_stack)
  1283. : m_stack(the_stack)
  1284. {}
  1285. void operator()(iterator_type const& first, iterator_type const& last) const
  1286. {
  1287. const escape_char_parser<lex_escapes, char_t> lex_escape_ch =
  1288. escape_char_parser<lex_escapes, char_t>();
  1289. char_t the_char;
  1290. iterator_type first_ = first;
  1291. ScannerT scan(first_, last);
  1292. lex_escape_ch[assign(the_char)].parse(scan);
  1293. node* newnode = ccl_utils::create_mb_node_seq(the_char);
  1294. m_stack.push(newnode);
  1295. }
  1296. std::stack<node*>& m_stack;
  1297. };
  1298. template <typename ScannerT>
  1299. class make_ccl
  1300. {
  1301. typedef typename ScannerT::iterator_t iterator_type;
  1302. public:
  1303. typedef
  1304. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1305. char_t;
  1306. make_ccl(std::stack<node*>& the_stack)
  1307. : m_stack(the_stack)
  1308. {}
  1309. static bool is_equal_to_string(iterator_type first,
  1310. iterator_type const & last, const char* str)
  1311. {
  1312. while (first != last &&*str &&*first ==*str)
  1313. {
  1314. ++first;
  1315. ++str;
  1316. }
  1317. return*str == 0;
  1318. }
  1319. template <typename ParserT>
  1320. static void fill_ccl(utility::impl::range_run<char_t>& rr, const ParserT& parser)
  1321. {
  1322. for (int i = 0; i < 256; ++i)
  1323. {
  1324. if (parser.test(static_cast<char_t>(uchar(i))))
  1325. rr.set(utility::impl::range<char_t>(char_t(i), char_t(i)));
  1326. }
  1327. }
  1328. void operator()(iterator_type const& first_, iterator_type const& last) const
  1329. {
  1330. BOOST_ASSERT(*first_ == '[');
  1331. iterator_type first = first_;
  1332. ++first; // skip over '['
  1333. bool negated_ccl = false;
  1334. if (*first == '^')
  1335. {
  1336. negated_ccl = true;
  1337. ++first;
  1338. }
  1339. utility::impl::range_run<char_t> rr;
  1340. while (first != last &&*first != ']')
  1341. {
  1342. if (*first == '[') // it's a ccl_expr like [:space:]
  1343. {
  1344. // check for [:space:], etc.
  1345. if (is_equal_to_string(first, last, "[:alnum:]"))
  1346. {
  1347. fill_ccl(rr, alnum_p);
  1348. }
  1349. else if (is_equal_to_string(first, last, "[:alpha:]"))
  1350. {
  1351. fill_ccl(rr, alpha_p);
  1352. }
  1353. else if (is_equal_to_string(first, last, "[:blank:]"))
  1354. {
  1355. fill_ccl(rr, blank_p);
  1356. }
  1357. else if (is_equal_to_string(first, last, "[:cntrl:]"))
  1358. {
  1359. fill_ccl(rr, cntrl_p);
  1360. }
  1361. else if (is_equal_to_string(first, last, "[:digit:]"))
  1362. {
  1363. fill_ccl(rr, digit_p);
  1364. }
  1365. else if (is_equal_to_string(first, last, "[:graph:]"))
  1366. {
  1367. fill_ccl(rr, graph_p);
  1368. }
  1369. else if (is_equal_to_string(first, last, "[:lower:]"))
  1370. {
  1371. fill_ccl(rr, lower_p);
  1372. }
  1373. else if (is_equal_to_string(first, last, "[:print:]"))
  1374. {
  1375. fill_ccl(rr, print_p);
  1376. }
  1377. else if (is_equal_to_string(first, last, "[:punct:]"))
  1378. {
  1379. fill_ccl(rr, punct_p);
  1380. }
  1381. else if (is_equal_to_string(first, last, "[:space:]"))
  1382. {
  1383. fill_ccl(rr, space_p);
  1384. }
  1385. else if (is_equal_to_string(first, last, "[:upper:]"))
  1386. {
  1387. fill_ccl(rr, upper_p);
  1388. }
  1389. else if (is_equal_to_string(first, last, "[:xdigit:]"))
  1390. {
  1391. fill_ccl(rr, xdigit_p);
  1392. }
  1393. // this can't happen, because it's parsed before we get here.
  1394. //else
  1395. // throw bad_regex();
  1396. // Advance past the character class expression
  1397. while (first != last &&*first != ']')
  1398. ++first;
  1399. BOOST_ASSERT(*first == ']');
  1400. ++first;
  1401. }
  1402. else {
  1403. const escape_char_parser<lex_escapes, char_t> lex_escape_ch =
  1404. escape_char_parser<lex_escapes, char_t>();
  1405. char_t c1;
  1406. ScannerT scan(first, last);
  1407. lex_escape_ch[assign(c1)].parse(scan);
  1408. if (*scan.first == '-') // insert a range
  1409. {
  1410. ++scan.first;
  1411. char_t c2;
  1412. lex_escape_ch[assign(c2)].parse(scan);
  1413. BOOST_ASSERT(c1 < c2); // Throw exception?
  1414. rr.set(utility::impl::range<char_t>(c1, c2));
  1415. }
  1416. else // insert 1 char
  1417. {
  1418. rr.set(utility::impl::range<char_t>(c1, c1));
  1419. }
  1420. }
  1421. }
  1422. if (negated_ccl)
  1423. {
  1424. rr = ccl_utils::negate_range_run(rr);
  1425. }
  1426. ccl_utils::create_nodes(rr, m_stack);
  1427. }
  1428. std::stack<node*>& m_stack;
  1429. };
  1430. template <typename ScannerT>
  1431. class make_any_char
  1432. {
  1433. typedef typename ScannerT::iterator_t iterator_type;
  1434. public:
  1435. typedef
  1436. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1437. char_t;
  1438. std::stack<node*>& m_stack;
  1439. make_any_char(std::stack<node*>& the_stack)
  1440. : m_stack(the_stack)
  1441. {}
  1442. void operator()(const char_t c) const
  1443. {
  1444. BOOST_ASSERT(c == '.');
  1445. do_any_char();
  1446. }
  1447. void do_any_char() const
  1448. {
  1449. static utility::impl::range_run<char_t> rr;
  1450. rr.set(full_range<char_t>());
  1451. char_t newline = '\n';
  1452. rr.clear(utility::impl::range<char_t>(newline, newline));
  1453. ccl_utils::create_nodes(rr, m_stack);
  1454. }
  1455. };
  1456. template <typename ScannerT>
  1457. class make_string
  1458. {
  1459. typedef typename ScannerT::iterator_t iterator_type;
  1460. public:
  1461. typedef
  1462. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1463. char_t;
  1464. std::stack<node*>& m_stack;
  1465. make_string(std::stack<node*>& the_stack)
  1466. : m_stack(the_stack)
  1467. {}
  1468. void operator()(iterator_type const& first, iterator_type const& last) const
  1469. {
  1470. BOOST_ASSERT(*first == '"');
  1471. iterator_type first_ = first;
  1472. ScannerT scan(first_, last);
  1473. ++scan.first; // skip over '"'
  1474. // empty string not allowed
  1475. if (*scan.first == '"')
  1476. {
  1477. boost::throw_exception(bad_regex());
  1478. }
  1479. const escape_char_parser<lex_escapes, char_t> lex_escape_ch =
  1480. escape_char_parser<lex_escapes, char_t>();
  1481. char_t c;
  1482. lex_escape_ch[assign(c)].parse(scan);
  1483. node* top_node = ccl_utils::create_mb_node_seq(c);
  1484. while (*scan.first != '"' && scan.first != scan.last)
  1485. {
  1486. lex_escape_ch[assign(c)].parse(scan);
  1487. node* cur_node = ccl_utils::create_mb_node_seq(c);
  1488. top_node = new cat_node(top_node, cur_node);
  1489. }
  1490. m_stack.push(top_node);
  1491. }
  1492. };
  1493. inline
  1494. node* repeat_node(node* n, int num)
  1495. {
  1496. node* list_of_nodes = n;
  1497. for (int i = 1; i < num; ++i)
  1498. {
  1499. list_of_nodes = new cat_node(list_of_nodes, n->clone());
  1500. }
  1501. return list_of_nodes;
  1502. }
  1503. inline
  1504. node* optional_node(node* n)
  1505. {
  1506. return new or_node(n, new epsilon_node());
  1507. }
  1508. template <typename ScannerT>
  1509. class make_rep1
  1510. {
  1511. typedef typename ScannerT::iterator_t iterator_type;
  1512. public:
  1513. typedef
  1514. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1515. char_t;
  1516. std::stack<node*>& m_stack;
  1517. make_rep1(std::stack<node*>& the_stack)
  1518. : m_stack(the_stack)
  1519. {}
  1520. void operator()(iterator_type const& first, iterator_type const& last) const
  1521. {
  1522. BOOST_ASSERT(*first == '{');
  1523. iterator_type first_ = first;
  1524. ScannerT scan(first_, last);
  1525. ++scan.first; // skip over '{'
  1526. unsigned int count;
  1527. uint_p[assign(count)].parse(scan);
  1528. if (count == 0)
  1529. boost::throw_exception(bad_regex());
  1530. node* top_node = m_stack.top();
  1531. m_stack.pop();
  1532. top_node = repeat_node(top_node, count);
  1533. m_stack.push(top_node);
  1534. }
  1535. };
  1536. template <typename ScannerT>
  1537. class make_rep2
  1538. {
  1539. typedef typename ScannerT::iterator_t iterator_type;
  1540. public:
  1541. typedef
  1542. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1543. char_t;
  1544. std::stack<node*>& m_stack;
  1545. make_rep2(std::stack<node*>& the_stack)
  1546. : m_stack(the_stack)
  1547. {}
  1548. void operator()(iterator_type const& first, iterator_type const& last) const
  1549. {
  1550. BOOST_ASSERT(*first == '{');
  1551. iterator_type first_ = first;
  1552. ScannerT scan (first_, last);
  1553. ++scan.first; // skip over '{'
  1554. unsigned int count;
  1555. uint_p[assign(count)].parse(scan);
  1556. if (count == 0)
  1557. boost::throw_exception(bad_regex());
  1558. node* top_node = m_stack.top();
  1559. m_stack.pop();
  1560. top_node = new cat_node(repeat_node(top_node, count),
  1561. new star_node(top_node->clone()));
  1562. m_stack.push(top_node);
  1563. }
  1564. };
  1565. template <typename ScannerT>
  1566. class make_rep3
  1567. {
  1568. typedef typename ScannerT::iterator_t iterator_type;
  1569. public:
  1570. typedef
  1571. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1572. char_t;
  1573. std::stack<node*>& m_stack;
  1574. make_rep3(std::stack<node*>& the_stack)
  1575. : m_stack(the_stack)
  1576. {}
  1577. void operator()(iterator_type const& first, iterator_type const& last) const
  1578. {
  1579. BOOST_ASSERT(*first == '{');
  1580. iterator_type first_ = first;
  1581. ScannerT scan(first_, last);
  1582. ++scan.first; // skip over '{'
  1583. unsigned int count1, count2;
  1584. uint_p[assign(count1)].parse(scan);
  1585. if (count1 == 0)
  1586. boost::throw_exception(bad_regex());
  1587. ++scan.first; // skip over ','
  1588. uint_p[assign(count2)].parse(scan);
  1589. if (count2 <= count1)
  1590. boost::throw_exception(bad_regex());
  1591. node* top_node = m_stack.top();
  1592. m_stack.pop();
  1593. node* repeats = repeat_node(top_node, count1);
  1594. top_node = new cat_node(repeats,
  1595. repeat_node(optional_node(top_node->clone()),
  1596. count2 - count1));
  1597. m_stack.push(top_node);
  1598. }
  1599. };
  1600. ///////////////////////////////////////////////////////////////////////////////
  1601. //
  1602. // Lexer grammar
  1603. //
  1604. // Defines the grammar, which mandates the syntax of the understood
  1605. // lexeme definitions passed to lexer::register_regex.
  1606. //
  1607. ///////////////////////////////////////////////////////////////////////////////
  1608. class lexer_grammar : public boost::spirit::classic::grammar<lexer_grammar>
  1609. {
  1610. public:
  1611. lexer_grammar(std::stack<node*> &node_stack_)
  1612. : node_stack(node_stack_) {}
  1613. template <typename ScannerT>
  1614. struct definition
  1615. {
  1616. typedef rule<ScannerT> rule_t;
  1617. typedef typename ScannerT::iterator_t iterator_type;
  1618. typedef
  1619. typename BOOST_SPIRIT_IT_NS::iterator_traits<iterator_type>::value_type
  1620. char_t;
  1621. rule_t regex, re, series, singleton, singleton2, fullccl, ccl, string,
  1622. escseq, ccl_char;
  1623. symbols<> ccl_expr;
  1624. definition(lexer_grammar const &self)
  1625. {
  1626. regex =
  1627. re >> !('/' >> re) >> !ch_p('$')
  1628. ;
  1629. re =
  1630. series
  1631. >>*( ('|' >> series)[make_or<ScannerT>(self.node_stack)] )
  1632. ;
  1633. series =
  1634. singleton
  1635. >>*( singleton[make_concat<ScannerT>(self.node_stack)] )
  1636. ;
  1637. singleton =
  1638. ch_p('.')[make_any_char<ScannerT>(self.node_stack)]
  1639. >> singleton2
  1640. | fullccl
  1641. >> singleton2
  1642. | ('"' >> string >> '"')
  1643. [
  1644. make_string<ScannerT>(self.node_stack)
  1645. ]
  1646. >> singleton2
  1647. | '(' >> re >> ')'
  1648. >> singleton2
  1649. | ((anychar_p - chset<>("/|*+?.(){}\\")) | escseq)
  1650. [
  1651. make_char<ScannerT>(self.node_stack)
  1652. ]
  1653. >> singleton2
  1654. ;
  1655. singleton2 =
  1656. ch_p('*')[make_star<ScannerT>(self.node_stack)]
  1657. >> singleton2
  1658. | ch_p('+')[make_plus<ScannerT>(self.node_stack)]
  1659. >> singleton2
  1660. | ch_p('?')[make_optional<ScannerT>(self.node_stack)]
  1661. >> singleton2
  1662. | ('{' >> uint_p >> '}')
  1663. [
  1664. make_rep1<ScannerT>(self.node_stack)
  1665. ]
  1666. >> singleton2
  1667. | ('{' >> uint_p >> ',' >> '}')
  1668. [
  1669. make_rep2<ScannerT>(self.node_stack)
  1670. ]
  1671. >> singleton2
  1672. | ('{' >> uint_p >> ',' >> uint_p >> '}')
  1673. [
  1674. make_rep3<ScannerT>(self.node_stack)
  1675. ]
  1676. >> singleton2
  1677. | epsilon_p
  1678. ;
  1679. fullccl =
  1680. ('[' >> !ch_p('^') >> ccl >> ']')
  1681. [
  1682. make_ccl<ScannerT>(self.node_stack)
  1683. ]
  1684. ;
  1685. ccl =
  1686. *(ccl_expr | (ccl_char >> !('-' >> ccl_char)))
  1687. ;
  1688. ccl_char =
  1689. ( (anychar_p - chset<>("\\\n]")) | escseq )
  1690. ;
  1691. ccl_expr =
  1692. "[:alnum:]",
  1693. "[:alpha:]",
  1694. "[:blank:]",
  1695. "[:cntrl:]",
  1696. "[:digit:]",
  1697. "[:graph:]",
  1698. "[:lower:]",
  1699. "[:print:]",
  1700. "[:punct:]",
  1701. "[:space:]",
  1702. "[:upper:]",
  1703. "[:xdigit:]"
  1704. ;
  1705. string =
  1706. +( (anychar_p - chset<>("\"\\")) | escseq )
  1707. ;
  1708. typedef
  1709. uint_parser<char_t, 8, 1,
  1710. std::numeric_limits<char_t>::digits / 3 + 1
  1711. > oct_parser_t;
  1712. typedef
  1713. uint_parser<char_t, 16, 1,
  1714. std::numeric_limits<char_t>::digits / 4 + 1
  1715. > hex_parser_t;
  1716. escseq =
  1717. ch_p('\\')
  1718. >> (
  1719. oct_parser_t()
  1720. | as_lower_d['x'] >> hex_parser_t()
  1721. | (anychar_p - chset<>('\n'))
  1722. )
  1723. ;
  1724. #define BOOST_SLEX_DEBUG (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  1725. BOOST_SPIRIT_DEBUG_TRACE_RULE(regex, BOOST_SLEX_DEBUG);
  1726. BOOST_SPIRIT_DEBUG_TRACE_RULE(re, BOOST_SLEX_DEBUG);
  1727. BOOST_SPIRIT_DEBUG_TRACE_RULE(series, BOOST_SLEX_DEBUG);
  1728. BOOST_SPIRIT_DEBUG_TRACE_RULE(singleton, BOOST_SLEX_DEBUG);
  1729. BOOST_SPIRIT_DEBUG_TRACE_RULE(singleton2, BOOST_SLEX_DEBUG);
  1730. BOOST_SPIRIT_DEBUG_TRACE_RULE(fullccl, BOOST_SLEX_DEBUG);
  1731. BOOST_SPIRIT_DEBUG_TRACE_RULE(ccl, BOOST_SLEX_DEBUG);
  1732. BOOST_SPIRIT_DEBUG_TRACE_RULE(string, BOOST_SLEX_DEBUG);
  1733. BOOST_SPIRIT_DEBUG_TRACE_RULE(escseq, BOOST_SLEX_DEBUG);
  1734. BOOST_SPIRIT_DEBUG_TRACE_RULE(ccl_char, BOOST_SLEX_DEBUG);
  1735. #undef BOOST_SLEX_DEBUG
  1736. }
  1737. rule<ScannerT> const&
  1738. start() const { return regex; }
  1739. };
  1740. std::stack<node*> &node_stack;
  1741. }; // class lexer_grammar
  1742. template <typename StringT>
  1743. inline node *
  1744. parse(lexer_grammar& g, StringT const& str)
  1745. {
  1746. typedef
  1747. scanner<typename StringT::const_iterator, scanner_policies<> >
  1748. scanner_t;
  1749. typedef typename rule<scanner_t>::template result<scanner_t>::type
  1750. result_t;
  1751. typename StringT::const_iterator first = str.begin();
  1752. typename StringT::const_iterator last = str.end();
  1753. scanner_t scan(first, last);
  1754. // typename rule<scanner_t>::result_t hit = g.parse(scan);
  1755. result_t hit = g.parse(scan);
  1756. if (!hit || !scan.at_end())
  1757. {
  1758. while (g.node_stack.size())
  1759. {
  1760. delete g.node_stack.top();
  1761. g.node_stack.pop();
  1762. }
  1763. return 0;
  1764. }
  1765. BOOST_ASSERT(g.node_stack.size() == 1);
  1766. node* rval = g.node_stack.top();
  1767. g.node_stack.pop();
  1768. node* an_eof_node = new eof_node();
  1769. rval = new cat_node(rval, an_eof_node);
  1770. return rval;
  1771. }
  1772. inline
  1773. void make_case_insensitive(state_match_t& state_match)
  1774. {
  1775. // TODO: Fix this.
  1776. // This doesn't take into account foreign languages, figure out how to
  1777. // do that. Also this approach is broken for this implementation of
  1778. // wide chars.
  1779. for (state_match_t::iterator iter = state_match.begin();
  1780. iter != state_match.end(); ++iter)
  1781. {
  1782. int i, j;
  1783. for (i = 'A', j = 'a'; i <= 'Z'; ++i, ++j)
  1784. {
  1785. // if either is set, turn them both on
  1786. (*iter)[i] = (*iter)[j] = uchar((*iter)[i] | (*iter)[j]);
  1787. }
  1788. }
  1789. }
  1790. template<bool wide_char>
  1791. struct regex_match_helper;
  1792. template<>
  1793. struct regex_match_helper<false> // single byte char
  1794. {
  1795. template <typename DfaT, typename IteratorT>
  1796. static bool
  1797. do_match(DfaT const& dfa, IteratorT &first, IteratorT const& last,
  1798. int& regex_index,
  1799. std::basic_string<
  1800. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1801. > *token)
  1802. {
  1803. typedef std::basic_string<
  1804. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1805. > string_type;
  1806. typedef typename string_type::size_type size_type;
  1807. node_id_t s = 0;
  1808. node_id_t last_accepting_index = invalid_node;
  1809. IteratorT p = first;
  1810. IteratorT last_accepting_cpos = first;
  1811. while (p != last)
  1812. {
  1813. s = dfa.transition_table[s][(uchar)*p];
  1814. if (s == invalid_node)
  1815. break;
  1816. if (token) token->append((size_type)1, *p);
  1817. ++p;
  1818. if (dfa.acceptance_index[s] != invalid_node)
  1819. {
  1820. last_accepting_index = s;
  1821. last_accepting_cpos = p;
  1822. }
  1823. }
  1824. if (last_accepting_index != invalid_node)
  1825. {
  1826. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  1827. std::cout << "dfa.acceptance_index[" << last_accepting_index << "] = " <<
  1828. dfa.acceptance_index[last_accepting_index] << '\n';
  1829. #endif
  1830. first = last_accepting_cpos;
  1831. regex_index = dfa.acceptance_index[last_accepting_index];
  1832. return true;
  1833. }
  1834. else
  1835. return false;
  1836. }
  1837. };
  1838. template<>
  1839. struct regex_match_helper<true> // wide char
  1840. {
  1841. template <typename DfaT, typename IteratorT>
  1842. static bool
  1843. do_match(DfaT const& dfa, IteratorT &first, IteratorT const& last,
  1844. int& regex_index,
  1845. std::basic_string<
  1846. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1847. > *token)
  1848. {
  1849. typedef
  1850. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1851. char_t;
  1852. typedef std::basic_string<char_t> string_type;
  1853. typedef typename string_type::size_type size_type;
  1854. node_id_t s = 0;
  1855. node_id_t last_accepting_index = invalid_node;
  1856. IteratorT wp = first;
  1857. IteratorT last_accepting_cpos = first;
  1858. while (wp != last)
  1859. {
  1860. for (unsigned int i = 0; i < sizeof(char_t); ++i)
  1861. {
  1862. s = dfa.transition_table[s][get_byte(*wp,i)];
  1863. if (s == invalid_node)
  1864. {
  1865. goto break_while;
  1866. }
  1867. }
  1868. if (token) token->append((size_type)1, *wp);
  1869. ++wp;
  1870. if (dfa.acceptance_index[s] != invalid_node)
  1871. {
  1872. last_accepting_index = s;
  1873. last_accepting_cpos = wp;
  1874. }
  1875. }
  1876. break_while:
  1877. if (last_accepting_index != invalid_node)
  1878. {
  1879. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  1880. std::cout << "dfa.acceptance_index[" << last_accepting_index << "] = " <<
  1881. dfa.acceptance_index[last_accepting_index] << '\n';
  1882. #endif
  1883. first = last_accepting_cpos;
  1884. regex_index = dfa.acceptance_index[last_accepting_index];
  1885. return true;
  1886. }
  1887. else
  1888. return false;
  1889. }
  1890. };
  1891. template <typename DfaT, typename IteratorT, bool wide_char>
  1892. struct regex_match
  1893. {
  1894. static bool
  1895. do_match(DfaT const& dfa, IteratorT &first, IteratorT const& last,
  1896. int& regex_index,
  1897. std::basic_string<
  1898. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1899. > *token)
  1900. {
  1901. return regex_match_helper<wide_char>::do_match(
  1902. dfa, first, last, regex_index, token);
  1903. }
  1904. };
  1905. } // namespace lexerimpl
  1906. ///////////////////////////////////////////////////////////////////////////////
  1907. //
  1908. template <typename IteratorT = char const*, typename TokenT = int,
  1909. typename CallbackT = void(*)(IteratorT const &,
  1910. IteratorT &,
  1911. IteratorT const&,
  1912. TokenT const&,
  1913. lexer_control<TokenT> &)>
  1914. class lexer
  1915. {
  1916. public:
  1917. typedef CallbackT callback_t;
  1918. typedef
  1919. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  1920. char_t;
  1921. struct regex_info
  1922. {
  1923. std::basic_string<char_t> str;
  1924. TokenT token;
  1925. CallbackT callback;
  1926. regex_info(const std::basic_string<char_t>& _str,
  1927. const TokenT& _token,
  1928. const CallbackT& _callback)
  1929. : str(_str)
  1930. , token(_token)
  1931. , callback(_callback)
  1932. {}
  1933. };
  1934. struct dfa_table
  1935. {
  1936. std::vector<std::vector<node_id_t> > transition_table;
  1937. std::vector<node_id_t> acceptance_index;
  1938. };
  1939. typedef std::vector<node_id_t> node_table_t;
  1940. typedef std::vector<node_table_t> transition_table_t;
  1941. typedef std::vector<dfa_table> dfa_t;
  1942. lexer(unsigned int states = 1);
  1943. void register_regex(const std::basic_string<char_t>& regex,
  1944. const TokenT& id, const CallbackT& cb = CallbackT(),
  1945. unsigned int state = 0);
  1946. TokenT next_token(IteratorT &first, IteratorT const &last,
  1947. std::basic_string<char_t> *token = 0);
  1948. void create_dfa();
  1949. bool has_compiled_dfa() { return m_compiled_dfa; }
  1950. void set_case_insensitive(bool insensitive);
  1951. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  1952. void dump(std::ostream& out);
  1953. #endif
  1954. typedef std::vector<std::vector<regex_info> > regex_list_t;
  1955. bool load (std::ifstream &in, long unique_id = 0);
  1956. bool save (std::ofstream &out, long unique_id = 0);
  1957. enum {
  1958. SLEX_SIGNATURE = 0x58454C53, // "SLEX"
  1959. SLEX_VERSION_100 = 0x0100, // persistance version
  1960. SLEX_LAST_KNOWN_VERSION = SLEX_VERSION_100,
  1961. SLEX_MINOR_VERSION_MASK = 0xFF
  1962. };
  1963. private:
  1964. void create_dfa_for_state(int state);
  1965. static bool regex_match(const dfa_t& dfa, IteratorT& first,
  1966. IteratorT& last, int& regex_index);
  1967. mutable std::stack<lexerimpl::node*> node_stack;
  1968. lexerimpl::lexer_grammar g;
  1969. mutable bool m_compiled_dfa;
  1970. mutable dfa_t m_dfa;
  1971. regex_list_t m_regex_list;
  1972. bool m_case_insensitive;
  1973. unsigned int m_state;
  1974. std::stack<unsigned int> m_state_stack;
  1975. unsigned int m_num_states;
  1976. };
  1977. template <typename IteratorT, typename TokenT, typename CallbackT>
  1978. inline
  1979. lexer<IteratorT, TokenT, CallbackT>::lexer(unsigned int states)
  1980. : g(node_stack)
  1981. , m_compiled_dfa(false)
  1982. , m_regex_list(states)
  1983. , m_case_insensitive(false)
  1984. , m_state(0)
  1985. , m_state_stack()
  1986. , m_num_states(states)
  1987. {
  1988. BOOST_SPIRIT_DEBUG_TRACE_NODE_NAME(g, "slex::lexer",
  1989. BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX);
  1990. }
  1991. template <typename IteratorT, typename TokenT, typename CallbackT>
  1992. inline void
  1993. lexer<IteratorT, TokenT, CallbackT>::register_regex(
  1994. const std::basic_string<char_t>& regex, const TokenT& id,
  1995. const CallbackT& callback, unsigned int state)
  1996. {
  1997. if (state > m_num_states) {
  1998. m_regex_list.resize(state);
  1999. m_num_states = state;
  2000. }
  2001. m_regex_list[state].push_back(regex_info(regex, id, callback));
  2002. }
  2003. template <typename IteratorT, typename TokenT, typename CallbackT>
  2004. inline TokenT
  2005. lexer<IteratorT, TokenT, CallbackT>::next_token(
  2006. IteratorT &first, IteratorT const& last,
  2007. std::basic_string<
  2008. typename BOOST_SPIRIT_IT_NS::iterator_traits<IteratorT>::value_type
  2009. > *token)
  2010. {
  2011. if (!m_compiled_dfa)
  2012. {
  2013. create_dfa();
  2014. }
  2015. IteratorT saved = first;
  2016. int regex_index;
  2017. if (!lexerimpl::regex_match<dfa_table, IteratorT, (sizeof(char_t) > 1)>::
  2018. do_match(m_dfa[m_state], first, last, regex_index, token))
  2019. return -1; // TODO: can't return -1, need to return some invalid token.
  2020. // how to figure this out? We can use traits I guess.
  2021. else
  2022. {
  2023. regex_info regex = m_regex_list[m_state][regex_index];
  2024. TokenT rval = regex.token;
  2025. if (regex.callback)
  2026. {
  2027. // execute corresponding callback
  2028. lexer_control<TokenT> controller(rval, m_state, m_state_stack);
  2029. regex.callback(saved, first, last, regex.token, controller);
  2030. if (controller.ignore_current_token_set()) {
  2031. if (token)
  2032. token->erase();
  2033. return next_token(first, last, token);
  2034. }
  2035. }
  2036. return rval;
  2037. }
  2038. }
  2039. namespace lexerimpl
  2040. {
  2041. inline
  2042. bool find_acceptance_state(const node_set& eof_node_ids,
  2043. const node_set& current_set,
  2044. node_id_t& acceptance_node_id)
  2045. {
  2046. for(node_set::const_iterator nsi = eof_node_ids.begin();
  2047. nsi != eof_node_ids.end(); ++nsi)
  2048. {
  2049. node_id_t eof_node_id =*nsi;
  2050. if (current_set.end() != current_set.find(eof_node_id))
  2051. {
  2052. // store the first one we come to as the
  2053. // matched pattern
  2054. acceptance_node_id = eof_node_id;
  2055. // don't bother searching for more
  2056. return true;
  2057. }
  2058. }
  2059. return false;
  2060. }
  2061. template <typename RegexListT, typename GrammarT>
  2062. #ifndef BOOST_NO_CXX11_SMART_PTR
  2063. inline std::unique_ptr<node>
  2064. #else
  2065. inline std::auto_ptr<node>
  2066. #endif
  2067. parse_regexes(const RegexListT& regex_list, GrammarT& g)
  2068. {
  2069. // parse the expressions into a tree
  2070. if (regex_list.begin() == regex_list.end())
  2071. boost::throw_exception(bad_regex());
  2072. typename RegexListT::const_iterator ri = regex_list.begin();
  2073. #ifndef BOOST_NO_CXX11_SMART_PTR
  2074. std::unique_ptr<node> tree(lexerimpl::parse(g, (*ri).str));
  2075. #else
  2076. std::auto_ptr<node> tree(lexerimpl::parse(g, (*ri).str));
  2077. #endif
  2078. if (tree.get() == 0)
  2079. boost::throw_exception(bad_regex());
  2080. ++ri;
  2081. for (/**/; ri != regex_list.end(); ++ri)
  2082. {
  2083. #ifndef BOOST_NO_CXX11_SMART_PTR
  2084. std::unique_ptr<node> next_tree(lexerimpl::parse(g, (*ri).str));
  2085. #else
  2086. std::auto_ptr<node> next_tree(lexerimpl::parse(g, (*ri).str));
  2087. #endif
  2088. if (next_tree.get() == 0)
  2089. boost::throw_exception(bad_regex());
  2090. #ifndef BOOST_NO_CXX11_SMART_PTR
  2091. tree = std::unique_ptr<node>(new or_node(tree.release(), next_tree.release()));
  2092. #else
  2093. tree = std::auto_ptr<node>(new or_node(tree.release(), next_tree.release()));
  2094. #endif
  2095. }
  2096. return tree;
  2097. }
  2098. } //namespace lexerimpl
  2099. template <typename IteratorT, typename TokenT, typename CallbackT>
  2100. inline void
  2101. lexer<IteratorT, TokenT, CallbackT>::create_dfa()
  2102. {
  2103. m_dfa.resize(m_num_states);
  2104. for (unsigned int i = 0; i < m_num_states; ++i)
  2105. create_dfa_for_state(i);
  2106. }
  2107. // Algorithm from Compilers: Principles, Techniques, and Tools p. 141
  2108. template <typename IteratorT, typename TokenT, typename CallbackT>
  2109. inline void
  2110. lexer<IteratorT, TokenT, CallbackT>::create_dfa_for_state(int state)
  2111. {
  2112. using lexerimpl::node;
  2113. #ifndef BOOST_NO_CXX11_SMART_PTR
  2114. std::unique_ptr<node> tree = lexerimpl::parse_regexes(m_regex_list[state], g);
  2115. #else
  2116. std::auto_ptr<node> tree = lexerimpl::parse_regexes(m_regex_list[state], g);
  2117. #endif
  2118. node_id_t dummy = 0;
  2119. tree->assign_node_ids(dummy);
  2120. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  2121. tree->dump(std::cout);
  2122. #endif
  2123. // compute followpos(root)
  2124. followpos_t followpos;
  2125. tree->compute_followpos(followpos);
  2126. // the dfa states <-> nfa state groups
  2127. std::map<node_set, node_id_t> dstates1;
  2128. std::map<node_id_t, node_set> dstates2;
  2129. // the dfa transitions
  2130. m_dfa[state].transition_table.push_back(
  2131. std::vector<node_id_t>(256, invalid_node));
  2132. m_dfa[state].acceptance_index.push_back(invalid_node);
  2133. // whether the dfa state has been processed yet
  2134. std::vector<node_id_t> marked;
  2135. // used to give a unique id to each dfa state
  2136. node_id_t num_states = 0;
  2137. // initially, the only unmarked state in Dstates is firstpos(root).
  2138. marked.push_back(0);
  2139. node_set fpr = tree->firstpos();
  2140. dstates1[fpr] = 0;
  2141. dstates2[0] = fpr;
  2142. state_match_t state_match;
  2143. tree->compute_state_match(state_match);
  2144. if (m_case_insensitive)
  2145. lexerimpl::make_case_insensitive(state_match);
  2146. node_set eof_node_ids;
  2147. tree->get_eof_ids(eof_node_ids);
  2148. // translate the eof_node_ids into a 0-based index
  2149. std::map<node_id_t, node_id_t> eof_node_id_map;
  2150. unsigned int x = 0;
  2151. for (node_set::iterator node_id_it = eof_node_ids.begin();
  2152. node_id_it != eof_node_ids.end();
  2153. ++node_id_it)
  2154. {
  2155. eof_node_id_map[*node_id_it] = x++;
  2156. }
  2157. // figure out if this is an acceptance state
  2158. node_id_t eof_node_id;
  2159. if (lexerimpl::find_acceptance_state(eof_node_ids, fpr, eof_node_id))
  2160. {
  2161. m_dfa[state].acceptance_index[0] = eof_node_id_map[eof_node_id];
  2162. }
  2163. std::vector<node_id_t>::iterator i = std::find(marked.begin(), marked.end(),
  2164. node_id_t(0));
  2165. while (marked.end() != i)
  2166. {
  2167. *i = 1;
  2168. node_id_t T = node_id_t(std::distance(marked.begin(), i));
  2169. BOOST_ASSERT(T < dstates2.size());
  2170. node_set Tstates = dstates2[T];
  2171. for (node_id_t j = 0; j < 256; ++j)
  2172. {
  2173. node_set U;
  2174. for (node_set::iterator k = Tstates.begin();
  2175. k != Tstates.end(); ++k)
  2176. {
  2177. node_id_t p =*k;
  2178. BOOST_ASSERT(p < state_match.size());
  2179. BOOST_ASSERT(j < state_match[p].size());
  2180. if (state_match[p][j])
  2181. {
  2182. node_set fpp = followpos[p];
  2183. U.insert(fpp.begin(), fpp.end());
  2184. }
  2185. }
  2186. if (U.size() > 0)
  2187. {
  2188. std::map<node_set, node_id_t>::iterator l = dstates1.find(U);
  2189. node_id_t target_state;
  2190. if (l == dstates1.end()) // not in the states yet
  2191. {
  2192. ++num_states;
  2193. dstates1[U] = target_state = num_states;
  2194. dstates2[target_state] = U;
  2195. marked.push_back(0);
  2196. m_dfa[state].transition_table.push_back(
  2197. std::vector<node_id_t>(256, invalid_node));
  2198. m_dfa[state].acceptance_index.push_back(invalid_node);
  2199. // figure out if this is an acceptance state
  2200. node_id_t eof_node_id;
  2201. if (lexerimpl::find_acceptance_state(eof_node_ids, U, eof_node_id))
  2202. {
  2203. m_dfa[state].acceptance_index[target_state] =
  2204. eof_node_id_map[eof_node_id];
  2205. }
  2206. }
  2207. else
  2208. {
  2209. target_state = dstates1[U];
  2210. }
  2211. BOOST_ASSERT(T < m_dfa[state].transition_table.size());
  2212. BOOST_ASSERT(j < m_dfa[state].transition_table[T].size());
  2213. m_dfa[state].transition_table[T][j] = target_state;
  2214. }
  2215. }
  2216. i = std::find(marked.begin(), marked.end(), node_id_t(0));
  2217. }
  2218. m_compiled_dfa = true;
  2219. }
  2220. template <typename IteratorT, typename TokenT, typename CallbackT>
  2221. inline void
  2222. lexer<IteratorT, TokenT, CallbackT>::set_case_insensitive(bool insensitive)
  2223. {
  2224. m_case_insensitive = insensitive;
  2225. }
  2226. #if defined(BOOST_SPIRIT_DEBUG) && (BOOST_SPIRIT_DEBUG_FLAGS & BOOST_SPIRIT_DEBUG_FLAGS_SLEX)
  2227. template <typename IteratorT, typename TokenT, typename CallbackT>
  2228. inline void
  2229. lexer<IteratorT, TokenT, CallbackT>::dump(std::ostream& out)
  2230. {
  2231. for (unsigned x = 0; x < m_dfa.size(); ++x)
  2232. {
  2233. out << "\nm_dfa[" << x << "] has " << m_dfa[x].transition_table.size() << " states\n";
  2234. for (node_id_t i = 0; i < m_dfa[x].transition_table.size(); ++i)
  2235. {
  2236. out << "state " << i << ":";
  2237. for (node_id_t j = 0; j < m_dfa[x].transition_table[i].size(); ++j)
  2238. {
  2239. if (m_dfa[x].transition_table[i][j] != invalid_node)
  2240. out << j << "->" << m_dfa[x].transition_table[i][j] << " ";
  2241. }
  2242. out << "\n";
  2243. }
  2244. out << "acceptance states: ";
  2245. for(unsigned int k = 0; k < m_dfa[x].acceptance_index.size(); ++k)
  2246. {
  2247. if (m_dfa[x].acceptance_index[k] != invalid_node)
  2248. out << '<' << k << ',' << m_dfa[x].acceptance_index[k] << "> ";
  2249. }
  2250. out << endl;
  2251. }
  2252. }
  2253. #endif
  2254. ///////////////////////////////////////////////////////////////////////////////
  2255. // load the lexer tables
  2256. #define slex_in(strm, val) \
  2257. strm.read((char*)&val, sizeof(val)); \
  2258. if (std::ios::goodbit != strm.rdstate()) return false
  2259. template <typename IteratorT, typename TokenT, typename CallbackT>
  2260. inline bool
  2261. lexer<IteratorT, TokenT, CallbackT>::load (std::ifstream &in, long unique_id)
  2262. {
  2263. // ensure correct signature and version
  2264. long signature = 0;
  2265. slex_in (in, signature);
  2266. if (signature != SLEX_SIGNATURE)
  2267. return false; // not for us
  2268. long version = 0;
  2269. slex_in (in, version);
  2270. if ((version & ~SLEX_MINOR_VERSION_MASK) > SLEX_LAST_KNOWN_VERSION)
  2271. return false; // to new for us
  2272. long uid = 0;
  2273. slex_in (in, uid);
  2274. if (uid != unique_id)
  2275. return false; // not saved by us
  2276. // load auxiliary members
  2277. int num_states = 0;
  2278. slex_in (in, num_states);
  2279. // load the dfa tables
  2280. dfa_t in_dfa;
  2281. std::size_t dfa_size = 0;
  2282. slex_in (in, dfa_size);
  2283. in_dfa.resize(dfa_size);
  2284. for (std::size_t dfa = 0; dfa < dfa_size; ++dfa)
  2285. {
  2286. // load the transition tables
  2287. std::size_t tt_size = 0;
  2288. transition_table_t &tt_table = in_dfa[dfa].transition_table;
  2289. slex_in (in, tt_size);
  2290. tt_table.resize(tt_size);
  2291. for (std::size_t tt = 0; tt < tt_size; ++tt)
  2292. {
  2293. std::size_t nt_size = 0;
  2294. node_table_t &nt_table = tt_table[tt];
  2295. slex_in (in, nt_size);
  2296. nt_table.resize(nt_size);
  2297. for (std::size_t nt = 0; nt < nt_size; ++nt)
  2298. {
  2299. slex_in (in, nt_table[nt]);
  2300. }
  2301. }
  2302. // load the acceptance index table
  2303. std::size_t ai_size = 0;
  2304. node_table_t &ai_table = in_dfa[dfa].acceptance_index;
  2305. slex_in (in, ai_size);
  2306. ai_table.resize(ai_size);
  2307. for (std::size_t ai = 0; ai < ai_size; ++ai)
  2308. {
  2309. slex_in (in, ai_table[ai]);
  2310. }
  2311. }
  2312. m_dfa.swap(in_dfa); // success, swap in the read values
  2313. m_num_states = num_states;
  2314. m_compiled_dfa = true;
  2315. return true;
  2316. }
  2317. #undef slex_in
  2318. ///////////////////////////////////////////////////////////////////////////////
  2319. // save the lexer tables
  2320. #define slex_out(strm, val) \
  2321. strm.write((char*)&val, sizeof(val)); \
  2322. if (std::ios::goodbit != strm.rdstate()) return false
  2323. template <typename IteratorT, typename TokenT, typename CallbackT>
  2324. inline bool
  2325. lexer<IteratorT, TokenT, CallbackT>::save (std::ofstream &out, long unique_id)
  2326. {
  2327. // save signature and version information
  2328. long out_long = SLEX_SIGNATURE;
  2329. slex_out(out, out_long);
  2330. out_long = SLEX_VERSION_100;
  2331. slex_out(out, out_long);
  2332. slex_out(out, unique_id);
  2333. // save auxiliary members
  2334. slex_out(out, m_num_states);
  2335. // save the dfa tables
  2336. typedef typename dfa_t::const_iterator dfa_iter_t;
  2337. typedef transition_table_t::const_iterator transition_table_iter_t;
  2338. typedef node_table_t::const_iterator node_table_iter_t;
  2339. std::size_t out_size_t = m_dfa.size();
  2340. slex_out(out, out_size_t);
  2341. dfa_iter_t end = m_dfa.end();
  2342. for (dfa_iter_t it = m_dfa.begin(); it != end; ++it)
  2343. {
  2344. // save the transition table
  2345. out_size_t = (*it).transition_table.size();
  2346. slex_out(out, out_size_t);
  2347. transition_table_iter_t tt_end = (*it).transition_table.end();
  2348. for (transition_table_iter_t tt_it = (*it).transition_table.begin();
  2349. tt_it != tt_end;
  2350. ++tt_it)
  2351. {
  2352. out_size_t = (*tt_it).size();
  2353. slex_out(out, out_size_t);
  2354. node_table_iter_t nt_end = (*tt_it).end();
  2355. for (node_table_iter_t nt_it = (*tt_it).begin();
  2356. nt_it != nt_end;
  2357. ++nt_it)
  2358. {
  2359. slex_out(out, (*nt_it));
  2360. }
  2361. }
  2362. // save the acceptance index table
  2363. out_size_t = (*it).acceptance_index.size();
  2364. slex_out(out, out_size_t);
  2365. node_table_iter_t nt_end = (*it).acceptance_index.end();
  2366. for (node_table_iter_t nt_it = (*it).acceptance_index.begin();
  2367. nt_it != nt_end;
  2368. ++nt_it)
  2369. {
  2370. slex_out(out, (*nt_it));
  2371. }
  2372. }
  2373. return true;
  2374. }
  2375. #undef slex_out
  2376. /*
  2377. a lexer_control object supports some operations on the lexer.
  2378. get current lexer state
  2379. set state
  2380. terminate
  2381. state stack (push, pop, top)
  2382. set new token return value
  2383. ignore the current token
  2384. yymore
  2385. get length of matched token
  2386. */
  2387. template <typename TokenT>
  2388. class lexer_control
  2389. {
  2390. public:
  2391. lexer_control(TokenT& token, unsigned int& current_state,
  2392. std::stack<unsigned int>& state_stack);
  2393. // functions dealing with the lexer state
  2394. // set the state to state
  2395. void set_state(unsigned int state);
  2396. // get the current state
  2397. unsigned int get_state();
  2398. // pushes the current state onto the top of the state stack and
  2399. // switches to new_state
  2400. void push_state(unsigned int new_state);
  2401. // pops the top of the state stack and switches to it.
  2402. void pop_state();
  2403. // returns the top of the stack without altering the stack's contents.
  2404. unsigned int top_state();
  2405. // functions dealing with the token returned.
  2406. // set a new TokenT return value, overriding that one that was
  2407. // registered via. register_regex()
  2408. void set_token(const TokenT& token);
  2409. // tell the lexer to return an invalid token, signifying termination.
  2410. void terminate();
  2411. // ignore the current token, and move on to the next one. The current
  2412. // token will NOT be returned from next_token()
  2413. void ignore_current_token();
  2414. // returns true if ignore_current_token() has been called,
  2415. // false otherwise.
  2416. bool ignore_current_token_set();
  2417. private:
  2418. TokenT& m_token;
  2419. bool m_ignore_current_token;
  2420. unsigned int& m_current_state;
  2421. std::stack<unsigned int>& m_state_stack;
  2422. };
  2423. template <typename TokenT>
  2424. inline
  2425. lexer_control<TokenT>::lexer_control(TokenT& token, unsigned int& current_state,
  2426. std::stack<unsigned int>& state_stack)
  2427. : m_token(token)
  2428. , m_ignore_current_token(false)
  2429. , m_current_state(current_state)
  2430. , m_state_stack(state_stack)
  2431. {
  2432. }
  2433. template <typename TokenT>
  2434. inline void
  2435. lexer_control<TokenT>::set_state(unsigned int state)
  2436. {
  2437. m_current_state = state;
  2438. }
  2439. template <typename TokenT>
  2440. inline unsigned int
  2441. lexer_control<TokenT>::get_state()
  2442. {
  2443. return m_current_state;
  2444. }
  2445. template <typename TokenT>
  2446. inline void
  2447. lexer_control<TokenT>::push_state(unsigned int new_state)
  2448. {
  2449. m_state_stack.push(m_current_state);
  2450. m_current_state = new_state;
  2451. }
  2452. template <typename TokenT>
  2453. inline void
  2454. lexer_control<TokenT>::pop_state()
  2455. {
  2456. m_current_state = m_state_stack.top();
  2457. m_state_stack.pop();
  2458. }
  2459. template <typename TokenT>
  2460. inline unsigned int
  2461. lexer_control<TokenT>::top_state()
  2462. {
  2463. return m_state_stack.top();
  2464. }
  2465. template <typename TokenT>
  2466. inline void
  2467. lexer_control<TokenT>::set_token(const TokenT& token)
  2468. {
  2469. m_token = token;
  2470. }
  2471. template <typename TokenT>
  2472. inline void
  2473. lexer_control<TokenT>::terminate()
  2474. {
  2475. m_token = -1; // TOOD: fix this, need to be determined by traits
  2476. }
  2477. template <typename TokenT>
  2478. inline void
  2479. lexer_control<TokenT>::ignore_current_token()
  2480. {
  2481. m_ignore_current_token = true;
  2482. }
  2483. template <typename TokenT>
  2484. inline bool
  2485. lexer_control<TokenT>::ignore_current_token_set()
  2486. {
  2487. return m_ignore_current_token;
  2488. }
  2489. } // namespace classic
  2490. } // namespace spirit
  2491. } // namespace boost
  2492. #undef BOOST_SPIRIT_IT_NS
  2493. #endif