goflat.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /*
  2. * Copyright 2004-2006 Adrian Thurston <thurston@complang.org>
  3. * 2004 Erich Ocean <eric.ocean@ampede.com>
  4. * 2005 Alan West <alan@alanz.com>
  5. */
  6. /* This file is part of Ragel.
  7. *
  8. * Ragel is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * Ragel is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with Ragel; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22. #include "ragel.h"
  23. #include "goflat.h"
  24. #include "redfsm.h"
  25. #include "gendata.h"
  26. using std::endl;
  27. std::ostream &GoFlatCodeGen::TO_STATE_ACTION( RedStateAp *state )
  28. {
  29. int act = 0;
  30. if ( state->toStateAction != 0 )
  31. act = state->toStateAction->location+1;
  32. out << act;
  33. return out;
  34. }
  35. std::ostream &GoFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state )
  36. {
  37. int act = 0;
  38. if ( state->fromStateAction != 0 )
  39. act = state->fromStateAction->location+1;
  40. out << act;
  41. return out;
  42. }
  43. std::ostream &GoFlatCodeGen::EOF_ACTION( RedStateAp *state )
  44. {
  45. int act = 0;
  46. if ( state->eofAction != 0 )
  47. act = state->eofAction->location+1;
  48. out << act;
  49. return out;
  50. }
  51. std::ostream &GoFlatCodeGen::TRANS_ACTION( RedTransAp *trans )
  52. {
  53. /* If there are actions, emit them. Otherwise emit zero. */
  54. int act = 0;
  55. if ( trans->action != 0 )
  56. act = trans->action->location+1;
  57. out << act;
  58. return out;
  59. }
  60. std::ostream &GoFlatCodeGen::TO_STATE_ACTION_SWITCH( int level )
  61. {
  62. /* Walk the list of functions, printing the cases. */
  63. for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  64. /* Write out referenced actions. */
  65. if ( act->numToStateRefs > 0 ) {
  66. /* Write the case label, the action and the case break */
  67. out << TABS(level) << "case " << act->actionId << ":" << endl;
  68. ACTION( out, act, 0, false, false );
  69. }
  70. }
  71. genLineDirective( out );
  72. return out;
  73. }
  74. std::ostream &GoFlatCodeGen::FROM_STATE_ACTION_SWITCH( int level )
  75. {
  76. /* Walk the list of functions, printing the cases. */
  77. for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  78. /* Write out referenced actions. */
  79. if ( act->numFromStateRefs > 0 ) {
  80. /* Write the case label, the action and the case break */
  81. out << TABS(level) << "case " << act->actionId << ":" << endl;
  82. ACTION( out, act, 0, false, false );
  83. }
  84. }
  85. genLineDirective( out );
  86. return out;
  87. }
  88. std::ostream &GoFlatCodeGen::EOF_ACTION_SWITCH( int level )
  89. {
  90. /* Walk the list of functions, printing the cases. */
  91. for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  92. /* Write out referenced actions. */
  93. if ( act->numEofRefs > 0 ) {
  94. /* Write the case label, the action and the case break */
  95. out << TABS(level) << "case " << act->actionId << ":" << endl;
  96. ACTION( out, act, 0, true, false );
  97. }
  98. }
  99. genLineDirective( out );
  100. return out;
  101. }
  102. std::ostream &GoFlatCodeGen::ACTION_SWITCH( int level )
  103. {
  104. /* Walk the list of functions, printing the cases. */
  105. for ( GenActionList::Iter act = actionList; act.lte(); act++ ) {
  106. /* Write out referenced actions. */
  107. if ( act->numTransRefs > 0 ) {
  108. /* Write the case label, the action and the case break */
  109. out << TABS(level) << "case " << act->actionId << ":" << endl;
  110. ACTION( out, act, 0, false, false );
  111. }
  112. }
  113. genLineDirective( out );
  114. return out;
  115. }
  116. std::ostream &GoFlatCodeGen::FLAT_INDEX_OFFSET()
  117. {
  118. out << " ";
  119. int totalStateNum = 0, curIndOffset = 0;
  120. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  121. /* Write the index offset. */
  122. out << curIndOffset << ", ";
  123. if ( !st.last() ) {
  124. if ( ++totalStateNum % IALL == 0 )
  125. out << endl << " ";
  126. }
  127. /* Move the index offset ahead. */
  128. if ( st->transList != 0 )
  129. curIndOffset += keyOps->span( st->lowKey, st->highKey );
  130. if ( st->defTrans != 0 )
  131. curIndOffset += 1;
  132. }
  133. out << endl;
  134. return out;
  135. }
  136. std::ostream &GoFlatCodeGen::KEY_SPANS()
  137. {
  138. out << " ";
  139. int totalStateNum = 0;
  140. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  141. /* Write singles length. */
  142. unsigned long long span = 0;
  143. if ( st->transList != 0 )
  144. span = keyOps->span( st->lowKey, st->highKey );
  145. out << span << ", ";
  146. if ( !st.last() ) {
  147. if ( ++totalStateNum % IALL == 0 )
  148. out << endl << " ";
  149. }
  150. }
  151. out << endl;
  152. return out;
  153. }
  154. std::ostream &GoFlatCodeGen::TO_STATE_ACTIONS()
  155. {
  156. out << " ";
  157. int totalStateNum = 0;
  158. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  159. /* Write any eof action. */
  160. TO_STATE_ACTION(st);
  161. out << ", ";
  162. if ( !st.last() ) {
  163. if ( ++totalStateNum % IALL == 0 )
  164. out << endl << " ";
  165. }
  166. }
  167. out << endl;
  168. return out;
  169. }
  170. std::ostream &GoFlatCodeGen::FROM_STATE_ACTIONS()
  171. {
  172. out << " ";
  173. int totalStateNum = 0;
  174. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  175. /* Write any eof action. */
  176. FROM_STATE_ACTION(st);
  177. out << ", ";
  178. if ( !st.last() ) {
  179. if ( ++totalStateNum % IALL == 0 )
  180. out << endl << " ";
  181. }
  182. }
  183. out << endl;
  184. return out;
  185. }
  186. std::ostream &GoFlatCodeGen::EOF_ACTIONS()
  187. {
  188. out << " ";
  189. int totalStateNum = 0;
  190. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  191. /* Write any eof action. */
  192. EOF_ACTION(st);
  193. out << ", ";
  194. if ( !st.last() ) {
  195. if ( ++totalStateNum % IALL == 0 )
  196. out << endl << " ";
  197. }
  198. }
  199. out << endl;
  200. return out;
  201. }
  202. std::ostream &GoFlatCodeGen::EOF_TRANS()
  203. {
  204. out << " ";
  205. int totalStateNum = 0;
  206. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  207. /* Write any eof action. */
  208. long trans = 0;
  209. if ( st->eofTrans != 0 ) {
  210. assert( st->eofTrans->pos >= 0 );
  211. trans = st->eofTrans->pos+1;
  212. }
  213. out << trans << ", ";
  214. if ( !st.last() ) {
  215. if ( ++totalStateNum % IALL == 0 )
  216. out << endl << " ";
  217. }
  218. }
  219. out << endl;
  220. return out;
  221. }
  222. std::ostream &GoFlatCodeGen::COND_KEYS()
  223. {
  224. out << " ";
  225. int totalStateNum = 0;
  226. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  227. /* Emit just cond low key and cond high key. */
  228. out << KEY( st->condLowKey ) << ", ";
  229. out << KEY( st->condHighKey ) << ", ";
  230. if ( !st.last() ) {
  231. if ( ++totalStateNum % IALL == 0 )
  232. out << endl << " ";
  233. }
  234. }
  235. out << endl;
  236. return out;
  237. }
  238. std::ostream &GoFlatCodeGen::COND_KEY_SPANS()
  239. {
  240. out << " ";
  241. int totalStateNum = 0;
  242. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  243. /* Write singles length. */
  244. unsigned long long span = 0;
  245. if ( st->condList != 0 )
  246. span = keyOps->span( st->condLowKey, st->condHighKey );
  247. out << span << ", ";
  248. if ( !st.last() ) {
  249. if ( ++totalStateNum % IALL == 0 )
  250. out << endl << " ";
  251. }
  252. }
  253. out << endl;
  254. return out;
  255. }
  256. std::ostream &GoFlatCodeGen::CONDS()
  257. {
  258. out << " ";
  259. int totalStateNum = 0;
  260. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  261. if ( st->condList != 0 ) {
  262. /* Walk the singles. */
  263. unsigned long long span = keyOps->span( st->condLowKey, st->condHighKey );
  264. for ( unsigned long long pos = 0; pos < span; pos++ ) {
  265. if ( st->condList[pos] != 0 )
  266. out << st->condList[pos]->condSpaceId + 1 << ", ";
  267. else
  268. out << "0, ";
  269. if ( !st.last() ) {
  270. if ( ++totalStateNum % IALL == 0 )
  271. out << endl << " ";
  272. }
  273. }
  274. }
  275. }
  276. out << endl;
  277. return out;
  278. }
  279. std::ostream &GoFlatCodeGen::COND_INDEX_OFFSET()
  280. {
  281. out << " ";
  282. int totalStateNum = 0;
  283. int curIndOffset = 0;
  284. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  285. /* Write the index offset. */
  286. out << curIndOffset << ", ";
  287. if ( !st.last() ) {
  288. if ( ++totalStateNum % IALL == 0 )
  289. out << endl << " ";
  290. }
  291. /* Move the index offset ahead. */
  292. if ( st->condList != 0 )
  293. curIndOffset += keyOps->span( st->condLowKey, st->condHighKey );
  294. }
  295. out << endl;
  296. return out;
  297. }
  298. std::ostream &GoFlatCodeGen::KEYS()
  299. {
  300. out << " ";
  301. int totalStateNum = 0;
  302. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  303. /* Emit just low key and high key. */
  304. out << KEY( st->lowKey ) << ", ";
  305. out << KEY( st->highKey ) << ", ";
  306. if ( !st.last() ) {
  307. if ( ++totalStateNum % IALL == 0 )
  308. out << endl << " ";
  309. }
  310. }
  311. out << endl;
  312. return out;
  313. }
  314. std::ostream &GoFlatCodeGen::INDICIES()
  315. {
  316. out << " ";
  317. int totalStateNum = 0;
  318. for ( RedStateList::Iter st = redFsm->stateList; st.lte(); st++ ) {
  319. if ( st->transList != 0 ) {
  320. /* Walk the singles. */
  321. unsigned long long span = keyOps->span( st->lowKey, st->highKey );
  322. for ( unsigned long long pos = 0; pos < span; pos++ ) {
  323. out << st->transList[pos]->id << ", ";
  324. if ( ++totalStateNum % IALL == 0 )
  325. out << endl << " ";
  326. }
  327. }
  328. /* The state's default index goes next. */
  329. if ( st->defTrans != 0 ) {
  330. out << st->defTrans->id << ", ";
  331. if ( ++totalStateNum % IALL == 0 )
  332. out << endl << " ";
  333. }
  334. }
  335. out << endl;
  336. return out;
  337. }
  338. std::ostream &GoFlatCodeGen::TRANS_TARGS()
  339. {
  340. /* Transitions must be written ordered by their id. */
  341. RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  342. for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  343. transPtrs[trans->id] = trans;
  344. /* Keep a count of the num of items in the array written. */
  345. out << " ";
  346. int totalStates = 0;
  347. for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  348. /* Save the position. Needed for eofTargs. */
  349. RedTransAp *trans = transPtrs[t];
  350. trans->pos = t;
  351. /* Write out the target state. */
  352. out << trans->targ->id << ", ";
  353. if ( t < redFsm->transSet.length()-1 ) {
  354. if ( ++totalStates % IALL == 0 )
  355. out << endl << " ";
  356. }
  357. }
  358. out << endl;
  359. delete[] transPtrs;
  360. return out;
  361. }
  362. std::ostream &GoFlatCodeGen::TRANS_ACTIONS()
  363. {
  364. /* Transitions must be written ordered by their id. */
  365. RedTransAp **transPtrs = new RedTransAp*[redFsm->transSet.length()];
  366. for ( TransApSet::Iter trans = redFsm->transSet; trans.lte(); trans++ )
  367. transPtrs[trans->id] = trans;
  368. /* Keep a count of the num of items in the array written. */
  369. out << " ";
  370. int totalAct = 0;
  371. for ( int t = 0; t < redFsm->transSet.length(); t++ ) {
  372. /* Write the function for the transition. */
  373. RedTransAp *trans = transPtrs[t];
  374. TRANS_ACTION( trans );
  375. out << ", ";
  376. if ( t < redFsm->transSet.length()-1 ) {
  377. if ( ++totalAct % IALL == 0 )
  378. out << endl << " ";
  379. }
  380. }
  381. out << endl;
  382. delete[] transPtrs;
  383. return out;
  384. }
  385. void GoFlatCodeGen::LOCATE_TRANS()
  386. {
  387. out <<
  388. " _keys = " << CAST(INT(), vCS() + " << 1") << endl <<
  389. " _inds = " << CAST(INT(), IO() + "[" + vCS() + "]") << endl <<
  390. endl <<
  391. " _slen = " << CAST(INT(), SP() + "[" + vCS() + "]") << endl <<
  392. " if _slen > 0 && " << K() << "[_keys] <= " << GET_WIDE_KEY() << " && " <<
  393. GET_WIDE_KEY() << " <= " << K() << "[_keys + 1]" << " {" << endl <<
  394. " _trans = " << CAST(INT(), I() + "[_inds + " + CAST(INT(), GET_WIDE_KEY() + " - " + K() + "[_keys]") + "]") << endl <<
  395. " } else {" << endl <<
  396. " _trans = " << CAST(INT(), I() + "[_inds + _slen]") << endl <<
  397. " }" << endl <<
  398. endl;
  399. }
  400. void GoFlatCodeGen::writeData()
  401. {
  402. /* If there are any transtion functions then output the array. If there
  403. * are none, don't bother emitting an empty array that won't be used. */
  404. if ( redFsm->anyActions() ) {
  405. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActArrItem), A() );
  406. ACTIONS_ARRAY();
  407. CLOSE_ARRAY() <<
  408. endl;
  409. }
  410. if ( redFsm->anyConditions() ) {
  411. OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
  412. COND_KEYS();
  413. CLOSE_ARRAY() <<
  414. endl;
  415. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
  416. COND_KEY_SPANS();
  417. CLOSE_ARRAY() <<
  418. endl;
  419. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
  420. CONDS();
  421. CLOSE_ARRAY() <<
  422. endl;
  423. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
  424. COND_INDEX_OFFSET();
  425. CLOSE_ARRAY() <<
  426. endl;
  427. }
  428. OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
  429. KEYS();
  430. CLOSE_ARRAY() <<
  431. endl;
  432. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
  433. KEY_SPANS();
  434. CLOSE_ARRAY() <<
  435. endl;
  436. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
  437. FLAT_INDEX_OFFSET();
  438. CLOSE_ARRAY() <<
  439. endl;
  440. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
  441. INDICIES();
  442. CLOSE_ARRAY() <<
  443. endl;
  444. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
  445. TRANS_TARGS();
  446. CLOSE_ARRAY() <<
  447. endl;
  448. if ( redFsm->anyActions() ) {
  449. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TA() );
  450. TRANS_ACTIONS();
  451. CLOSE_ARRAY() <<
  452. endl;
  453. }
  454. if ( redFsm->anyToStateActions() ) {
  455. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
  456. TO_STATE_ACTIONS();
  457. CLOSE_ARRAY() <<
  458. endl;
  459. }
  460. if ( redFsm->anyFromStateActions() ) {
  461. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
  462. FROM_STATE_ACTIONS();
  463. CLOSE_ARRAY() <<
  464. endl;
  465. }
  466. if ( redFsm->anyEofActions() ) {
  467. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), EA() );
  468. EOF_ACTIONS();
  469. CLOSE_ARRAY() <<
  470. endl;
  471. }
  472. if ( redFsm->anyEofTrans() ) {
  473. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
  474. EOF_TRANS();
  475. CLOSE_ARRAY() <<
  476. endl;
  477. }
  478. STATE_IDS();
  479. }
  480. void GoFlatCodeGen::COND_TRANSLATE()
  481. {
  482. out <<
  483. " _widec = " << CAST(WIDE_ALPH_TYPE(), GET_KEY()) << endl;
  484. out <<
  485. " _keys = " << CAST(INT(), vCS() + " << 1") << endl <<
  486. " _conds = " << CAST(INT(), CO() + "[" + vCS() + "]") << endl <<
  487. endl <<
  488. " _slen = " << CAST(INT(), CSP() + "[" + vCS() + "]") << endl <<
  489. " if _slen > 0 && " << CK() << "[_keys]" << " <= " << GET_WIDE_KEY() << " && " <<
  490. GET_WIDE_KEY() << " <= " << CK() << "[_keys + 1] {" << endl <<
  491. " _cond = " << CAST(INT(), C() + "[_conds + " + CAST(INT(), GET_WIDE_KEY() + " - " + CK() + "[_keys]") + "]") << endl <<
  492. " } else {" << endl <<
  493. " _cond = 0" << endl <<
  494. " }" << endl <<
  495. endl;
  496. out <<
  497. " switch _cond {" << endl;
  498. for ( CondSpaceList::Iter csi = condSpaceList; csi.lte(); csi++ ) {
  499. GenCondSpace *condSpace = csi;
  500. out << " case " << condSpace->condSpaceId + 1 << ":" << endl;
  501. out << TABS(2) << "_widec = " <<
  502. KEY(condSpace->baseKey) << " + (" << CAST(WIDE_ALPH_TYPE(), GET_KEY()) <<
  503. " - " << KEY(keyOps->minKey) << ")" << endl;
  504. for ( GenCondSet::Iter csi = condSpace->condSet; csi.lte(); csi++ ) {
  505. out << TABS(2) << "if ";
  506. CONDITION( out, *csi );
  507. Size condValOffset = ((1 << csi.pos()) * keyOps->alphSize());
  508. out << " {" << endl <<
  509. " _widec += " << condValOffset << endl <<
  510. " }" << endl;
  511. }
  512. }
  513. out <<
  514. " }" << endl;
  515. }
  516. void GoFlatCodeGen::writeExec()
  517. {
  518. testEofUsed = false;
  519. outLabelUsed = false;
  520. out <<
  521. " {" << endl <<
  522. " var _slen " << INT() << endl;
  523. if ( redFsm->anyRegCurStateRef() )
  524. out << " var _ps " << INT() << endl;
  525. out <<
  526. " var _trans " << INT() << endl;
  527. if ( redFsm->anyConditions() )
  528. out << " var _cond " << INT() << endl;
  529. if ( redFsm->anyToStateActions() ||
  530. redFsm->anyRegActions() || redFsm->anyFromStateActions() )
  531. {
  532. out <<
  533. " var _acts " << INT() << endl <<
  534. " var _nacts " << UINT() << endl;
  535. }
  536. out <<
  537. " var _keys " << INT() << endl <<
  538. " var _inds " << INT() << endl;
  539. if ( redFsm->anyConditions() ) {
  540. out <<
  541. " var _conds " << INT() << endl <<
  542. " var _widec " << WIDE_ALPH_TYPE() << endl;
  543. }
  544. out << endl;
  545. if ( !noEnd ) {
  546. testEofUsed = true;
  547. out <<
  548. " if " << P() << " == " << PE() << " {" << endl <<
  549. " goto _test_eof" << endl <<
  550. " }" << endl;
  551. }
  552. if ( redFsm->errState != 0 ) {
  553. outLabelUsed = true;
  554. out <<
  555. " if " << vCS() << " == " << redFsm->errState->id << " {" << endl <<
  556. " goto _out" << endl <<
  557. " }" << endl;
  558. }
  559. out << "_resume:" << endl;
  560. if ( redFsm->anyFromStateActions() ) {
  561. out <<
  562. " _acts = " << CAST(INT(), FSA() + "[" + vCS() + "]") << endl <<
  563. " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl <<
  564. " for ; _nacts > 0; _nacts-- {" << endl <<
  565. " _acts++" << endl <<
  566. " switch " << A() << "[_acts - 1]" << " {" << endl;
  567. FROM_STATE_ACTION_SWITCH(2);
  568. out <<
  569. " }" << endl <<
  570. " }" << endl <<
  571. endl;
  572. }
  573. if ( redFsm->anyConditions() )
  574. COND_TRANSLATE();
  575. LOCATE_TRANS();
  576. if ( redFsm->anyEofTrans() )
  577. out << "_eof_trans:" << endl;
  578. if ( redFsm->anyRegCurStateRef() )
  579. out << " _ps = " << vCS() << endl;
  580. out <<
  581. " " << vCS() << " = " << CAST(INT(), TT() + "[_trans]") << endl <<
  582. endl;
  583. if ( redFsm->anyRegActions() ) {
  584. out <<
  585. " if " << TA() << "[_trans] == 0 {" << endl <<
  586. " goto _again" << endl <<
  587. " }" << endl <<
  588. endl <<
  589. " _acts = " << CAST(INT(), TA() + "[_trans]") << endl <<
  590. " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl <<
  591. " for ; _nacts > 0; _nacts-- {" << endl <<
  592. " _acts++" << endl <<
  593. " switch " << A() << "[_acts - 1]" << " {" << endl;
  594. ACTION_SWITCH(2);
  595. out <<
  596. " }" << endl <<
  597. " }" << endl <<
  598. endl;
  599. }
  600. if ( redFsm->anyRegActions() || redFsm->anyActionGotos() ||
  601. redFsm->anyActionCalls() || redFsm->anyActionRets() )
  602. out << "_again:" << endl;
  603. if ( redFsm->anyToStateActions() ) {
  604. out <<
  605. " _acts = " << CAST(INT(), TSA() + "[" + vCS() + "]") << endl <<
  606. " _nacts = " << CAST(UINT(), A() + "[_acts]") << "; _acts++" << endl <<
  607. " for ; _nacts > 0; _nacts-- {" << endl <<
  608. " _acts++" << endl <<
  609. " switch " << A() << "[_acts - 1]" << " {" << endl;
  610. TO_STATE_ACTION_SWITCH(2);
  611. out <<
  612. " }" << endl <<
  613. " }" << endl <<
  614. endl;
  615. }
  616. if ( redFsm->errState != 0 ) {
  617. outLabelUsed = true;
  618. out <<
  619. " if " << vCS() << " == " << redFsm->errState->id << " {" << endl <<
  620. " goto _out" << endl <<
  621. " }" << endl;
  622. }
  623. if ( !noEnd ) {
  624. out <<
  625. " if " << P() << "++; " << P() << " != " << PE() << " {" << endl <<
  626. " goto _resume" << endl <<
  627. " }" << endl;
  628. }
  629. else {
  630. out <<
  631. " " << P() << "++" << endl <<
  632. " goto _resume" << endl;
  633. }
  634. if ( testEofUsed )
  635. out << " _test_eof: {}" << endl;
  636. if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
  637. out <<
  638. " if " << P() << " == " << vEOF() << " {" << endl;
  639. if ( redFsm->anyEofTrans() ) {
  640. out <<
  641. " if " << ET() << "[" << vCS() << "] > 0 {" << endl <<
  642. " _trans = " << CAST(INT(), ET() + "[" + vCS() + "] - 1") << endl <<
  643. " goto _eof_trans" << endl <<
  644. " }" << endl;
  645. }
  646. if ( redFsm->anyEofActions() ) {
  647. out <<
  648. " __acts := " << CAST(INT(), EA() + "[" + vCS() + "]") << endl <<
  649. " __nacts := " << CAST(UINT(), A() + "[__acts]") << "; __acts++" << endl <<
  650. " for ; __nacts > 0; __nacts-- {" << endl <<
  651. " __acts++" << endl <<
  652. " switch " << A() << "[__acts - 1]" << " {" << endl;
  653. EOF_ACTION_SWITCH(3);
  654. out <<
  655. " }" << endl <<
  656. " }" << endl;
  657. }
  658. out <<
  659. " }" << endl <<
  660. endl;
  661. }
  662. if ( outLabelUsed )
  663. out << " _out: {}" << endl;
  664. out << " }" << endl;
  665. }