csfflat.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  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 "csfflat.h"
  24. #include "redfsm.h"
  25. #include "gendata.h"
  26. std::ostream &CSharpFFlatCodeGen::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 &CSharpFFlatCodeGen::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 &CSharpFFlatCodeGen::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 &CSharpFFlatCodeGen::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 &CSharpFFlatCodeGen::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 );
  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 &CSharpFFlatCodeGen::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 );
  89. out << "\tbreak;\n";
  90. }
  91. }
  92. genLineDirective( out );
  93. return out;
  94. }
  95. std::ostream &CSharpFFlatCodeGen::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 );
  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 &CSharpFFlatCodeGen::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 );
  123. out << "\tbreak;\n";
  124. }
  125. }
  126. genLineDirective( out );
  127. return out;
  128. }
  129. void CSharpFFlatCodeGen::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 CSharpFFlatCodeGen::writeExec()
  202. {
  203. testEofUsed = false;
  204. outLabelUsed = false;
  205. initVarTypes();
  206. out <<
  207. " {\n"
  208. " " << slenType << " _slen";
  209. if ( redFsm->anyRegCurStateRef() )
  210. out << ", _ps";
  211. out << ";\n";
  212. out << " " << transType << " _trans";
  213. if ( redFsm->anyConditions() )
  214. out << ", _cond";
  215. out << ";\n";
  216. out <<
  217. " " << "int _keys;\n"
  218. " " << indsType << " _inds;\n";
  219. /*
  220. " " << PTR_CONST() << WIDE_ALPH_TYPE() << POINTER() << "_keys;\n"
  221. " " << PTR_CONST() << ARRAY_TYPE(redFsm->maxIndex) << POINTER() << "_inds;\n";*/
  222. if ( redFsm->anyConditions() ) {
  223. out <<
  224. " " << condsType << " _conds;\n"
  225. " " << WIDE_ALPH_TYPE() << " _widec;\n";
  226. }
  227. if ( !noEnd ) {
  228. testEofUsed = true;
  229. out <<
  230. " if ( " << P() << " == " << PE() << " )\n"
  231. " goto _test_eof;\n";
  232. }
  233. if ( redFsm->errState != 0 ) {
  234. outLabelUsed = true;
  235. out <<
  236. " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  237. " goto _out;\n";
  238. }
  239. out << "_resume:\n";
  240. if ( redFsm->anyFromStateActions() ) {
  241. out <<
  242. " switch ( " << FSA() << "[" << vCS() << "] ) {\n";
  243. FROM_STATE_ACTION_SWITCH();
  244. SWITCH_DEFAULT() <<
  245. " }\n"
  246. "\n";
  247. }
  248. if ( redFsm->anyConditions() )
  249. COND_TRANSLATE();
  250. LOCATE_TRANS();
  251. if ( redFsm->anyEofTrans() )
  252. out << "_eof_trans:\n";
  253. if ( redFsm->anyRegCurStateRef() )
  254. out << " _ps = " << vCS() << ";\n";
  255. out <<
  256. " " << vCS() << " = " << TT() << "[_trans];\n\n";
  257. if ( redFsm->anyRegActions() ) {
  258. out <<
  259. " if ( " << TA() << "[_trans] == 0 )\n"
  260. " goto _again;\n"
  261. "\n"
  262. " switch ( " << TA() << "[_trans] ) {\n";
  263. ACTION_SWITCH();
  264. SWITCH_DEFAULT() <<
  265. " }\n"
  266. "\n";
  267. }
  268. if ( redFsm->anyRegActions() || redFsm->anyActionGotos() ||
  269. redFsm->anyActionCalls() || redFsm->anyActionRets() )
  270. out << "_again:\n";
  271. if ( redFsm->anyToStateActions() ) {
  272. out <<
  273. " switch ( " << TSA() << "[" << vCS() << "] ) {\n";
  274. TO_STATE_ACTION_SWITCH();
  275. SWITCH_DEFAULT() <<
  276. " }\n"
  277. "\n";
  278. }
  279. if ( redFsm->errState != 0 ) {
  280. outLabelUsed = true;
  281. out <<
  282. " if ( " << vCS() << " == " << redFsm->errState->id << " )\n"
  283. " goto _out;\n";
  284. }
  285. if ( !noEnd ) {
  286. out <<
  287. " if ( ++" << P() << " != " << PE() << " )\n"
  288. " goto _resume;\n";
  289. }
  290. else {
  291. out <<
  292. " " << P() << " += 1;\n"
  293. " goto _resume;\n";
  294. }
  295. if ( testEofUsed )
  296. out << " _test_eof: {}\n";
  297. if ( redFsm->anyEofTrans() || redFsm->anyEofActions() ) {
  298. out <<
  299. " if ( " << P() << " == " << vEOF() << " )\n"
  300. " {\n";
  301. if ( redFsm->anyEofTrans() ) {
  302. out <<
  303. " if ( " << ET() << "[" << vCS() << "] > 0 ) {\n"
  304. " _trans = " << CAST(transType) << " (" << ET() <<
  305. "[" << vCS() << "] - 1);\n"
  306. " goto _eof_trans;\n"
  307. " }\n";
  308. }
  309. if ( redFsm->anyEofActions() ) {
  310. out <<
  311. " switch ( " << EA() << "[" << vCS() << "] ) {\n";
  312. EOF_ACTION_SWITCH();
  313. SWITCH_DEFAULT() <<
  314. " }\n";
  315. }
  316. out <<
  317. " }\n"
  318. "\n";
  319. }
  320. if ( outLabelUsed )
  321. out << " _out: {}\n";
  322. out << " }\n";
  323. }