cdfflat.cpp 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  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 "cdfflat.h"
  24. #include "redfsm.h"
  25. #include "gendata.h"
  26. std::ostream &FFlatCodeGen::TO_STATE_ACTION( RedStateAp *state )
  27. {
  28. int act = 0;
  29. if ( state->toStateAction != 0 )
  30. act = state->toStateAction->actListId+1;
  31. out << act;
  32. return out;
  33. }
  34. std::ostream &FFlatCodeGen::FROM_STATE_ACTION( RedStateAp *state )
  35. {
  36. int act = 0;
  37. if ( state->fromStateAction != 0 )
  38. act = state->fromStateAction->actListId+1;
  39. out << act;
  40. return out;
  41. }
  42. std::ostream &FFlatCodeGen::EOF_ACTION( RedStateAp *state )
  43. {
  44. int act = 0;
  45. if ( state->eofAction != 0 )
  46. act = state->eofAction->actListId+1;
  47. out << act;
  48. return out;
  49. }
  50. /* Write out the function for a transition. */
  51. std::ostream &FFlatCodeGen::TRANS_ACTION( RedTransAp *trans )
  52. {
  53. int action = 0;
  54. if ( trans->action != 0 )
  55. action = trans->action->actListId+1;
  56. out << action;
  57. return out;
  58. }
  59. /* Write out the function switch. This switch is keyed on the values
  60. * of the func index. */
  61. std::ostream &FFlatCodeGen::TO_STATE_ACTION_SWITCH()
  62. {
  63. /* Loop the actions. */
  64. for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
  65. if ( redAct->numToStateRefs > 0 ) {
  66. /* Write the entry label. */
  67. out << "\tcase " << redAct->actListId+1 << ":\n";
  68. /* Write each action in the list of action items. */
  69. for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
  70. ACTION( out, item->value, 0, false, false );
  71. out << "\tbreak;\n";
  72. }
  73. }
  74. genLineDirective( out );
  75. return out;
  76. }
  77. /* Write out the function switch. This switch is keyed on the values
  78. * of the func index. */
  79. std::ostream &FFlatCodeGen::FROM_STATE_ACTION_SWITCH()
  80. {
  81. /* Loop the actions. */
  82. for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
  83. if ( redAct->numFromStateRefs > 0 ) {
  84. /* Write the entry label. */
  85. out << "\tcase " << redAct->actListId+1 << ":\n";
  86. /* Write each action in the list of action items. */
  87. for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
  88. ACTION( out, item->value, 0, false, false );
  89. out << "\tbreak;\n";
  90. }
  91. }
  92. genLineDirective( out );
  93. return out;
  94. }
  95. std::ostream &FFlatCodeGen::EOF_ACTION_SWITCH()
  96. {
  97. /* Loop the actions. */
  98. for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
  99. if ( redAct->numEofRefs > 0 ) {
  100. /* Write the entry label. */
  101. out << "\tcase " << redAct->actListId+1 << ":\n";
  102. /* Write each action in the list of action items. */
  103. for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
  104. ACTION( out, item->value, 0, true, false );
  105. out << "\tbreak;\n";
  106. }
  107. }
  108. genLineDirective( out );
  109. return out;
  110. }
  111. /* Write out the function switch. This switch is keyed on the values
  112. * of the func index. */
  113. std::ostream &FFlatCodeGen::ACTION_SWITCH()
  114. {
  115. /* Loop the actions. */
  116. for ( GenActionTableMap::Iter redAct = redFsm->actionMap; redAct.lte(); redAct++ ) {
  117. if ( redAct->numTransRefs > 0 ) {
  118. /* Write the entry label. */
  119. out << "\tcase " << redAct->actListId+1 << ":\n";
  120. /* Write each action in the list of action items. */
  121. for ( GenActionTable::Iter item = redAct->key; item.lte(); item++ )
  122. ACTION( out, item->value, 0, false, false );
  123. out << "\tbreak;\n";
  124. }
  125. }
  126. genLineDirective( out );
  127. return out;
  128. }
  129. void FFlatCodeGen::writeData()
  130. {
  131. if ( redFsm->anyConditions() ) {
  132. OPEN_ARRAY( WIDE_ALPH_TYPE(), CK() );
  133. COND_KEYS();
  134. CLOSE_ARRAY() <<
  135. "\n";
  136. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondSpan), CSP() );
  137. COND_KEY_SPANS();
  138. CLOSE_ARRAY() <<
  139. "\n";
  140. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCond), C() );
  141. CONDS();
  142. CLOSE_ARRAY() <<
  143. "\n";
  144. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxCondIndexOffset), CO() );
  145. COND_INDEX_OFFSET();
  146. CLOSE_ARRAY() <<
  147. "\n";
  148. }
  149. OPEN_ARRAY( WIDE_ALPH_TYPE(), K() );
  150. KEYS();
  151. CLOSE_ARRAY() <<
  152. "\n";
  153. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxSpan), SP() );
  154. KEY_SPANS();
  155. CLOSE_ARRAY() <<
  156. "\n";
  157. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxFlatIndexOffset), IO() );
  158. FLAT_INDEX_OFFSET();
  159. CLOSE_ARRAY() <<
  160. "\n";
  161. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndex), I() );
  162. INDICIES();
  163. CLOSE_ARRAY() <<
  164. "\n";
  165. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxState), TT() );
  166. TRANS_TARGS();
  167. CLOSE_ARRAY() <<
  168. "\n";
  169. if ( redFsm->anyActions() ) {
  170. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), TA() );
  171. TRANS_ACTIONS();
  172. CLOSE_ARRAY() <<
  173. "\n";
  174. }
  175. if ( redFsm->anyToStateActions() ) {
  176. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), TSA() );
  177. TO_STATE_ACTIONS();
  178. CLOSE_ARRAY() <<
  179. "\n";
  180. }
  181. if ( redFsm->anyFromStateActions() ) {
  182. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActionLoc), FSA() );
  183. FROM_STATE_ACTIONS();
  184. CLOSE_ARRAY() <<
  185. "\n";
  186. }
  187. if ( redFsm->anyEofActions() ) {
  188. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxActListId), EA() );
  189. EOF_ACTIONS();
  190. CLOSE_ARRAY() <<
  191. "\n";
  192. }
  193. if ( redFsm->anyEofTrans() ) {
  194. OPEN_ARRAY( ARRAY_TYPE(redFsm->maxIndexOffset+1), ET() );
  195. EOF_TRANS();
  196. CLOSE_ARRAY() <<
  197. "\n";
  198. }
  199. STATE_IDS();
  200. }
  201. void FFlatCodeGen::writeExec()
  202. {
  203. testEofUsed = false;
  204. outLabelUsed = false;
  205. out <<
  206. " {\n"
  207. " int _slen";
  208. if ( redFsm->anyRegCurStateRef() )
  209. out << ", _ps";
  210. out << ";\n";
  211. out << " int _trans";
  212. if ( redFsm->anyConditions() )
  213. out << ", _cond";
  214. out << ";\n";
  215. out <<
  216. " " << PTR_CONST() << WIDE_ALPH_TYPE() << PTR_CONST_END() << POINTER() << "_keys;\n"
  217. " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << PTR_CONST_END() << POINTER() << "_inds;\n";
  218. if ( redFsm->anyConditions() ) {
  219. out <<
  220. " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxCond) << PTR_CONST_END() << POINTER() << "_conds;\n"
  221. " " << WIDE_ALPH_TYPE() << " _widec;\n";
  222. }
  223. if ( !noEnd ) {
  224. testEofUsed = true;
  225. out <<
  226. " if ( " << P() << " == " << PE() << " )\n"
  227. " goto _test_eof;\n";
  228. }
  229. if ( redFsm->errState != 0 ) {
  230. outLabelUsed = true;
  231. out <<
  232. " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  233. " goto _out;\n";
  234. }
  235. out << "_resume:\n";
  236. if ( redFsm->anyFromStateActions() ) {
  237. out <<
  238. " switch ( " << FSA() << "[" << vCS() << "] ) {\n";
  239. FROM_STATE_ACTION_SWITCH();
  240. SWITCH_DEFAULT() <<
  241. " }\n"
  242. "\n";
  243. }
  244. if ( redFsm->anyConditions() )
  245. COND_TRANSLATE();
  246. LOCATE_TRANS();
  247. if ( redFsm->anyEofTrans() )
  248. out << "_eof_trans:\n";
  249. if ( redFsm->anyRegCurStateRef() )
  250. out << " _ps = " << vCS() << ";\n";
  251. out <<
  252. " " << vCS() << " = " << TT() << "[_trans];\n\n";
  253. if ( redFsm->anyRegActions() ) {
  254. out <<
  255. " if ( " << TA() << "[_trans] == 0 )\n"
  256. " goto _again;\n"
  257. "\n"
  258. " switch ( " << TA() << "[_trans] ) {\n";
  259. ACTION_SWITCH();
  260. SWITCH_DEFAULT() <<
  261. " }\n"
  262. "\n";
  263. }
  264. if ( redFsm->anyRegActions() || redFsm->anyActionGotos() ||
  265. redFsm->anyActionCalls() || redFsm->anyActionRets() )
  266. out << "_again:\n";
  267. if ( redFsm->anyToStateActions() ) {
  268. out <<
  269. " switch ( " << TSA() << "[" << vCS() << "] ) {\n";
  270. TO_STATE_ACTION_SWITCH();
  271. SWITCH_DEFAULT() <<
  272. " }\n"
  273. "\n";
  274. }
  275. if ( redFsm->errState != 0 ) {
  276. outLabelUsed = true;
  277. out <<
  278. " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  279. " goto _out;\n";
  280. }
  281. if ( !noEnd ) {
  282. out <<
  283. " if ( ++" << P() << " != " << PE() << " )\n"
  284. " goto _resume;\n";
  285. }
  286. else {
  287. out <<
  288. " " << P() << " += 1;\n"
  289. " goto _resume;\n";
  290. }
  291. if ( testEofUsed )
  292. out << " _test_eof: {}\n";
  293. if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
  294. out <<
  295. " if ( " << P() << " == " << vEOF() << " )\n"
  296. " {\n";
  297. if ( redFsm->anyEofTrans() ) {
  298. out <<
  299. " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
  300. " _trans = " << ET() << "[" << vCS() << "] - 1;\n"
  301. " goto _eof_trans;\n"
  302. " }\n";
  303. }
  304. if ( redFsm->anyEofActions() ) {
  305. out <<
  306. " switch ( " << EA() << "[" << vCS() << "] ) {\n";
  307. EOF_ACTION_SWITCH();
  308. SWITCH_DEFAULT() <<
  309. " }\n";
  310. }
  311. out <<
  312. " }\n"
  313. "\n";
  314. }
  315. if ( outLabelUsed )
  316. out << " _out: {}\n";
  317. out << " }\n";
  318. }