output.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296
  1. /*++
  2. Copyright (c) 2016 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. output.c
  9. Abstract:
  10. This module supports outputting the final data from the grammar generator.
  11. Author:
  12. Evan Green 25-Apr-2016
  13. Environment:
  14. Build
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "yygenp.h"
  20. #include <assert.h>
  21. #include <ctype.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <time.h>
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. #define YY_DEFAULT_SOURCE_FILE_HEADER \
  29. "/*++\n\n" \
  30. "Copyright (c) %Y Minoca Corp. All Rights Reserved\n\n" \
  31. "Module Name:\n\n" \
  32. " %f\n\n" \
  33. "Abstract:\n\n" \
  34. " This module implements grammar data. This file is machine " \
  35. "generated.\n\n" \
  36. "Author:\n\n" \
  37. " Minoca yygen %d-%b-%Y\n\n" \
  38. "Environment\n\n" \
  39. " YY\n\n" \
  40. "--*/\n\n" \
  41. "//\n" \
  42. "// -------------------------------------------------------------------" \
  43. "Includes\n" \
  44. "//\n\n" \
  45. "#include <minoca/lib/types.h>\n" \
  46. "#include <minoca/lib/status.h>\n" \
  47. "#include <minoca/lib/yy.h>\n\n" \
  48. "//\n" \
  49. "// --------------------------------------------------------------------" \
  50. "Globals\n" \
  51. "//\n\n" \
  52. #define YY_VALUES_PER_LINES 10
  53. #define YYGEN_VECTORS_PER_STATE 2
  54. //
  55. // Define how far to rebase token values (except EOF and Error, which are
  56. // always 0 and 1. Set this to 255 for compatibility mode, or 0 normally.
  57. //
  58. #define YYGEN_TOKEN_OUTPUT_BASE 0
  59. //
  60. // ------------------------------------------------------ Data Type Definitions
  61. //
  62. /*++
  63. Structure Description:
  64. This structure contains the working state for action output code.
  65. Members:
  66. VectorCount - Stores the length of the from, to, tally, and width arrays.
  67. From - Stores the array of source state arrays. This is really two
  68. consecutive arrays: the first containing the array of shift symbols for
  69. each state, and the second containing the source reduction states for
  70. each state.
  71. To - Stores the array of destination states, running parallel to the from
  72. arrays.
  73. Tally - Stores the tally array. This is really two consecutive arrays: the
  74. first containing the number of shifts for a state and the second
  75. containing the number of reductions.
  76. Width - Stores the width array. This runs parallel to the from
  77. arrays, and indicates the symbol range/size defined by the action.
  78. Order - Stores an array of the sorted order of the from/to/tally/width
  79. arrays, sorted on width.
  80. EntryCount - Stores the number of elements in the order array. This is the
  81. final number of elements, as it culls elements with a zero tally.
  82. Base - Stores an array of indices into the table, indexed parallel to the
  83. from arrays.
  84. Position - Stores an array of indices into the table, indexed by final
  85. order.
  86. Table - Stores the packed table of complete destination states.
  87. Check - Stores the packed table of source states or shift symbols, indexed
  88. parallel to the table.
  89. TableCapacity - Stores the capacity of the table and check arrays before
  90. they must be reallocated.
  91. Low - Stores the lowest table index in use.
  92. High - Stores the highest table index in use.
  93. --*/
  94. typedef struct _YYGEN_ACTION_CONTEXT {
  95. YY_VALUE VectorCount;
  96. PYY_VALUE *From;
  97. PYY_VALUE *To;
  98. PYY_VALUE Tally;
  99. PYY_VALUE Width;
  100. PYY_VALUE Order;
  101. YY_VALUE EntryCount;
  102. PYY_VALUE Base;
  103. PYY_VALUE Position;
  104. PYY_VALUE Table;
  105. PYY_VALUE Check;
  106. YY_VALUE TableCapacity;
  107. YY_VALUE Low;
  108. YY_VALUE High;
  109. } YYGEN_ACTION_CONTEXT, *PYYGEN_ACTION_CONTEXT;
  110. //
  111. // ----------------------------------------------- Internal Function Prototypes
  112. //
  113. VOID
  114. YypOutputFileHeader (
  115. PYYGEN_CONTEXT Context,
  116. FILE *File
  117. );
  118. VOID
  119. YypOutputRuleData (
  120. PYYGEN_CONTEXT Context,
  121. FILE *File
  122. );
  123. VOID
  124. YypOutputDefaultReductions (
  125. PYYGEN_CONTEXT Context,
  126. FILE *File
  127. );
  128. YY_STATUS
  129. YypOutputActions (
  130. PYYGEN_CONTEXT Context,
  131. FILE *File,
  132. PYY_VALUE TableSize
  133. );
  134. YY_STATUS
  135. YypCreateTokenActions (
  136. PYYGEN_CONTEXT Context,
  137. PYYGEN_ACTION_CONTEXT ActionContext
  138. );
  139. YY_STATUS
  140. YypOutputDefaultGotos (
  141. PYYGEN_CONTEXT Context,
  142. PYYGEN_ACTION_CONTEXT ActionContext,
  143. FILE *File
  144. );
  145. YY_STATE_INDEX
  146. YypFindDefaultGoto (
  147. PYYGEN_CONTEXT Context,
  148. PYY_STATE_INDEX StateCounts,
  149. YY_VALUE Symbol
  150. );
  151. YY_STATUS
  152. YypSaveColumn (
  153. PYYGEN_CONTEXT Context,
  154. PYYGEN_ACTION_CONTEXT ActionContext,
  155. YY_VALUE Symbol,
  156. YY_STATE_INDEX DefaultGoto
  157. );
  158. YY_STATUS
  159. YypSortActions (
  160. PYYGEN_CONTEXT Context,
  161. PYYGEN_ACTION_CONTEXT ActionContext
  162. );
  163. YY_STATUS
  164. YypPackOutputTable (
  165. PYYGEN_CONTEXT Context,
  166. PYYGEN_ACTION_CONTEXT ActionContext
  167. );
  168. YY_STATUS
  169. YypPackVector (
  170. PYYGEN_ACTION_CONTEXT ActionContext,
  171. YY_VALUE EntryIndex,
  172. PYY_VALUE TableIndex
  173. );
  174. YY_STATE_INDEX
  175. YypFindMatchingVector (
  176. PYYGEN_CONTEXT Context,
  177. PYYGEN_ACTION_CONTEXT ActionContext,
  178. YY_VALUE EntryIndex
  179. );
  180. YY_STATUS
  181. YypOutputDebug (
  182. PYYGEN_CONTEXT Context,
  183. FILE *File,
  184. PYY_VALUE UndefinedToken
  185. );
  186. VOID
  187. YypOutputArray (
  188. PYYGEN_CONTEXT Context,
  189. FILE *File,
  190. PSTR Name,
  191. PYY_VALUE Array,
  192. YY_VALUE Size
  193. );
  194. VOID
  195. YypOutputArrayBeginning (
  196. PYYGEN_CONTEXT Context,
  197. FILE *File,
  198. PSTR Name
  199. );
  200. VOID
  201. YypOutputArrayEnd (
  202. PYYGEN_CONTEXT Context,
  203. FILE *File
  204. );
  205. VOID
  206. YypOutputValue (
  207. PYYGEN_CONTEXT Context,
  208. FILE *File,
  209. YY_VALUE Value
  210. );
  211. VOID
  212. YypOutputString (
  213. FILE *File,
  214. PSTR String
  215. );
  216. VOID
  217. YypOutputGrammarStructure (
  218. PYYGEN_CONTEXT Context,
  219. FILE *File,
  220. YY_VALUE TableSize,
  221. YY_VALUE UndefinedToken
  222. );
  223. VOID
  224. YypPrintOutputStates (
  225. PYYGEN_CONTEXT Context,
  226. PYYGEN_ACTION_CONTEXT ActionContext
  227. );
  228. //
  229. // -------------------------------------------------------------------- Globals
  230. //
  231. PSTR YyAbbreviatedMonths[12] = {
  232. "Jan",
  233. "Feb",
  234. "Mar",
  235. "Apr",
  236. "May",
  237. "Jun",
  238. "Jul",
  239. "Aug",
  240. "Sep",
  241. "Oct",
  242. "Nov",
  243. "Dec"
  244. };
  245. PSTR YyFullMonths[12] = {
  246. "January",
  247. "February",
  248. "March",
  249. "April",
  250. "May",
  251. "June",
  252. "July",
  253. "August",
  254. "September",
  255. "October",
  256. "November",
  257. "December"
  258. };
  259. PSTR YyAbbreviatedWeekdays[7] = {
  260. "Sun",
  261. "Mon",
  262. "Tue",
  263. "Wed",
  264. "Thu",
  265. "Fri",
  266. "Sat"
  267. };
  268. PSTR YyFullWeekdays[7] = {
  269. "Sunday",
  270. "Monday",
  271. "Tuesday",
  272. "Wednesday",
  273. "Thursday",
  274. "Friday",
  275. "Saturday"
  276. };
  277. PSTR YyAmPm[2] = {
  278. "AM",
  279. "PM"
  280. };
  281. //
  282. // ------------------------------------------------------------------ Functions
  283. //
  284. YY_STATUS
  285. YyOutputParserSource (
  286. PYYGEN_CONTEXT Context,
  287. FILE *File
  288. )
  289. /*++
  290. Routine Description:
  291. This routine prints a C source file containing the parser data to the given
  292. file.
  293. Arguments:
  294. Context - Supplies a pointer to the initialized grammar context.
  295. File - Supplies the file handle to output to.
  296. Return Value:
  297. YY Status.
  298. --*/
  299. {
  300. YY_VALUE TableSize;
  301. YY_VALUE UndefinedToken;
  302. YY_STATUS YyStatus;
  303. YypOutputFileHeader(Context, File);
  304. YypOutputRuleData(Context, File);
  305. YypOutputDefaultReductions(Context, File);
  306. YyStatus = YypOutputActions(Context, File, &TableSize);
  307. if (YyStatus != YyStatusSuccess) {
  308. goto OutputParserSouceEnd;
  309. }
  310. YyStatus = YypOutputDebug(Context, File, &UndefinedToken);
  311. if (YyStatus != YyStatusSuccess) {
  312. goto OutputParserSouceEnd;
  313. }
  314. YypOutputGrammarStructure(Context, File, TableSize, UndefinedToken);
  315. OutputParserSouceEnd:
  316. return YyStatus;
  317. }
  318. //
  319. // --------------------------------------------------------- Internal Functions
  320. //
  321. VOID
  322. YypOutputFileHeader (
  323. PYYGEN_CONTEXT Context,
  324. FILE *File
  325. )
  326. /*++
  327. Routine Description:
  328. This routine prints the C file header.
  329. Arguments:
  330. Context - Supplies a pointer to the initialized grammar context.
  331. File - Supplies the file handle to output to.
  332. Return Value:
  333. None.
  334. --*/
  335. {
  336. PSTR Current;
  337. ULONG Hour12;
  338. time_t Time;
  339. struct tm *TimeFields;
  340. Current = YY_DEFAULT_SOURCE_FILE_HEADER;
  341. Time = time(NULL);
  342. TimeFields = localtime(&Time);
  343. if (TimeFields == NULL) {
  344. return;
  345. }
  346. Hour12 = TimeFields->tm_hour;
  347. if (Hour12 == 0) {
  348. Hour12 = 12;
  349. } else if (Hour12 > 12) {
  350. Hour12 -= 12;
  351. }
  352. while (*Current != '\0') {
  353. if (*Current != '%') {
  354. fputc(*Current, File);
  355. Current += 1;
  356. continue;
  357. }
  358. Current += 1;
  359. switch (*Current) {
  360. case 'a':
  361. fprintf(File, "%s", YyAbbreviatedWeekdays[TimeFields->tm_wday]);
  362. break;
  363. case 'A':
  364. fprintf(File, "%s", YyFullWeekdays[TimeFields->tm_wday]);
  365. break;
  366. case 'b':
  367. case 'h':
  368. fprintf(File, "%s", YyAbbreviatedMonths[TimeFields->tm_mon]);
  369. break;
  370. case 'B':
  371. fprintf(File, "%s", YyFullMonths[TimeFields->tm_mon]);
  372. break;
  373. case 'd':
  374. fprintf(File, "%02d", TimeFields->tm_mday);
  375. break;
  376. case 'D':
  377. fprintf(File,
  378. "%02d/%02d/%02d",
  379. TimeFields->tm_mon,
  380. TimeFields->tm_mday,
  381. (TimeFields->tm_year + 1900) % 100);
  382. break;
  383. case 'e':
  384. fprintf(File, "%2d", TimeFields->tm_mday);
  385. break;
  386. case 'f':
  387. fprintf(File, "%s", Context->OutputFileName);
  388. break;
  389. case 'F':
  390. fprintf(File,
  391. "%04d-%02d-%02d",
  392. TimeFields->tm_year + 1900,
  393. TimeFields->tm_mon,
  394. TimeFields->tm_mday);
  395. break;
  396. case 'H':
  397. fprintf(File, "%02d", TimeFields->tm_hour);
  398. break;
  399. case 'I':
  400. fprintf(File, "%02d", Hour12);
  401. break;
  402. case 'm':
  403. fprintf(File, "%02d", TimeFields->tm_mon);
  404. break;
  405. case 'M':
  406. fprintf(File, "%02d", TimeFields->tm_min);
  407. break;
  408. case 'n':
  409. fputc('\n', File);
  410. break;
  411. case 'p':
  412. case 'P':
  413. fprintf(File, "%s", YyAmPm[TimeFields->tm_hour / 12]);
  414. break;
  415. case 'S':
  416. fprintf(File, "%02d", TimeFields->tm_sec);
  417. break;
  418. case 's':
  419. fprintf(File, "%lld", (long long)Time);
  420. break;
  421. case 't':
  422. fputc('\t', File);
  423. break;
  424. case 'T':
  425. fprintf(File,
  426. "%02d:%02d:%02d",
  427. TimeFields->tm_hour,
  428. TimeFields->tm_min,
  429. TimeFields->tm_sec);
  430. break;
  431. case 'u':
  432. fprintf(File,
  433. "%d",
  434. (TimeFields->tm_wday == 0) ? 7 : TimeFields->tm_wday);
  435. break;
  436. case 'w':
  437. fprintf(File, "%d", TimeFields->tm_wday);
  438. break;
  439. case 'y':
  440. fprintf(File, "%02d", (TimeFields->tm_year + 1900) % 100);
  441. break;
  442. case 'Y':
  443. fprintf(File, "%04d", TimeFields->tm_year + 1900);
  444. break;
  445. case '%':
  446. fputc('%', File);
  447. break;
  448. //
  449. // Unknown specifier, just swallow it.
  450. //
  451. default:
  452. fprintf(stderr, "Unknown source header specifier: %c.\n", *Current);
  453. break;
  454. }
  455. Current += 1;
  456. }
  457. return;
  458. }
  459. VOID
  460. YypOutputRuleData (
  461. PYYGEN_CONTEXT Context,
  462. FILE *File
  463. )
  464. /*++
  465. Routine Description:
  466. This routine prints the rule left hand side symbols and rule lengths to
  467. the output source.
  468. Arguments:
  469. Context - Supplies a pointer to the initialized grammar context.
  470. File - Supplies the file handle to output to.
  471. Return Value:
  472. None.
  473. --*/
  474. {
  475. YY_RULE_INDEX Column;
  476. YY_RULE_INDEX RuleIndex;
  477. YY_VALUE Value;
  478. //
  479. // Spit out the rule left hand side symbols.
  480. //
  481. Column = 0;
  482. YypOutputArrayBeginning(Context, File, "LeftSide");
  483. for (RuleIndex = 2; RuleIndex < Context->RuleCount; RuleIndex += 1) {
  484. if (Column >= YY_VALUES_PER_LINES) {
  485. fprintf(File, "\n ");
  486. Column = 0;
  487. }
  488. Column += 1;
  489. //
  490. // Print out the left hand sides so that the start rule is -1, and the
  491. // real rules start at 0.
  492. //
  493. Value = Context->Rules[RuleIndex].LeftSide - (Context->TokenCount + 1);
  494. YypOutputValue(Context, File, Value);
  495. }
  496. YypOutputArrayEnd(Context, File);
  497. //
  498. // Spit out the rule lengths.
  499. //
  500. Column = 0;
  501. YypOutputArrayBeginning(Context, File, "RuleLength");
  502. for (RuleIndex = 2; RuleIndex < Context->RuleCount; RuleIndex += 1) {
  503. if (Column >= YY_VALUES_PER_LINES) {
  504. fprintf(File, "\n ");
  505. Column = 0;
  506. }
  507. Column += 1;
  508. Value = (Context->Rules[RuleIndex + 1].RightSide -
  509. Context->Rules[RuleIndex].RightSide) - 1;
  510. YypOutputValue(Context, File, Value);
  511. }
  512. YypOutputArrayEnd(Context, File);
  513. return;
  514. }
  515. VOID
  516. YypOutputDefaultReductions (
  517. PYYGEN_CONTEXT Context,
  518. FILE *File
  519. )
  520. /*++
  521. Routine Description:
  522. This routine prints the default reductions to the output source.
  523. Arguments:
  524. Context - Supplies a pointer to the initialized grammar context.
  525. File - Supplies the file handle to output to.
  526. Return Value:
  527. None.
  528. --*/
  529. {
  530. ULONG Column;
  531. YY_VALUE Index;
  532. YY_VALUE Value;
  533. YypOutputArrayBeginning(Context, File, "DefaultReductions");
  534. Column = 0;
  535. for (Index = 0; Index < Context->StateCount; Index += 1) {
  536. if (Column >= YY_VALUES_PER_LINES) {
  537. fprintf(File, "\n ");
  538. Column = 0;
  539. }
  540. Column += 1;
  541. Value = Context->DefaultReductions[Index];
  542. if (Value != 0) {
  543. Value -= 2;
  544. }
  545. YypOutputValue(Context, File, Value);
  546. }
  547. YypOutputArrayEnd(Context, File);
  548. return;
  549. }
  550. YY_STATUS
  551. YypOutputActions (
  552. PYYGEN_CONTEXT Context,
  553. FILE *File,
  554. PYY_VALUE TableSize
  555. )
  556. /*++
  557. Routine Description:
  558. This routine prints the parser actions to the output source.
  559. Arguments:
  560. Context - Supplies a pointer to the initialized grammar context.
  561. File - Supplies the file handle to output to.
  562. TableSize - Supplies a pointer where the table size will be returned on
  563. success.
  564. Return Value:
  565. YY Status.
  566. --*/
  567. {
  568. YYGEN_ACTION_CONTEXT ActionContext;
  569. YY_VALUE Index;
  570. YY_VALUE Size;
  571. YY_VALUE VectorCount;
  572. YY_STATUS YyStatus;
  573. YyStatus = YyStatusNoMemory;
  574. memset(&ActionContext, 0, sizeof(YYGEN_ACTION_CONTEXT));
  575. VectorCount = (Context->StateCount * YYGEN_VECTORS_PER_STATE) +
  576. Context->NonTerminalCount;
  577. ActionContext.VectorCount = VectorCount;
  578. ActionContext.From = YypAllocate(VectorCount * sizeof(PYY_VALUE));
  579. if (ActionContext.From == NULL) {
  580. goto OutputActionsEnd;
  581. }
  582. ActionContext.To = YypAllocate(VectorCount * sizeof(PYY_VALUE));
  583. if (ActionContext.To == NULL) {
  584. goto OutputActionsEnd;
  585. }
  586. ActionContext.Tally = YypAllocate(VectorCount * sizeof(YY_VALUE));
  587. if (ActionContext.Tally == NULL) {
  588. goto OutputActionsEnd;
  589. }
  590. ActionContext.Width = YypAllocate(VectorCount * sizeof(YY_VALUE));
  591. if (ActionContext.Width == NULL) {
  592. goto OutputActionsEnd;
  593. }
  594. //
  595. // Create the actions based on tokens.
  596. //
  597. YyStatus = YypCreateTokenActions(Context, &ActionContext);
  598. if (YyStatus != YyStatusSuccess) {
  599. goto OutputActionsEnd;
  600. }
  601. //
  602. // Create the remaining gotos, and print the default (most used) ones.
  603. //
  604. YyStatus = YypOutputDefaultGotos(Context, &ActionContext, File);
  605. if (YyStatus != YyStatusSuccess) {
  606. goto OutputActionsEnd;
  607. }
  608. //
  609. // Sort the actions by width (and then by tally) so that finding duplicate
  610. // shift/reduce actions is quicker.
  611. //
  612. YyStatus = YypSortActions(Context, &ActionContext);
  613. if (YyStatus != YyStatusSuccess) {
  614. goto OutputActionsEnd;
  615. }
  616. //
  617. // Create one giant table of shift/reduce actions.
  618. //
  619. YyStatus = YypPackOutputTable(Context, &ActionContext);
  620. if (YyStatus != YyStatusSuccess) {
  621. goto OutputActionsEnd;
  622. }
  623. //
  624. // Output the shift index table, which indicates the index into the giant
  625. // table to start from for shifting from a given state.
  626. //
  627. YypOutputArray(Context,
  628. File,
  629. "ShiftIndex",
  630. ActionContext.Base,
  631. Context->StateCount);
  632. //
  633. // Output the reduce index table, which indicates the index into the giant
  634. // table to start from for reducing from a given state.
  635. //
  636. Index = Context->StateCount;
  637. Size = (Context->StateCount * 2) - Index;
  638. YypOutputArray(Context,
  639. File,
  640. "ReduceIndex",
  641. ActionContext.Base + Index,
  642. Size);
  643. //
  644. // Output the goto index table.
  645. //
  646. Index = Context->StateCount * YYGEN_VECTORS_PER_STATE;
  647. Size = (ActionContext.VectorCount - 1) - Index;
  648. YypOutputArray(Context,
  649. File,
  650. "GotoIndex",
  651. ActionContext.Base + Index,
  652. Size);
  653. //
  654. // It's time, output the giant table.
  655. //
  656. Size = ActionContext.High + 1;
  657. YypOutputArray(Context,
  658. File,
  659. "Table",
  660. ActionContext.Table,
  661. Size);
  662. //
  663. // Also output the check table, which indicates the "from" state.
  664. //
  665. YypOutputArray(Context,
  666. File,
  667. "Check",
  668. ActionContext.Check,
  669. Size);
  670. OutputActionsEnd:
  671. *TableSize = ActionContext.High;
  672. if (ActionContext.From != NULL) {
  673. for (Index = 0; Index < ActionContext.VectorCount; Index += 1) {
  674. if (ActionContext.From[Index] != NULL) {
  675. YypFree(ActionContext.From[Index]);
  676. }
  677. }
  678. YypFree(ActionContext.From);
  679. }
  680. if (ActionContext.To != NULL) {
  681. for (Index = 0; Index < ActionContext.VectorCount; Index += 1) {
  682. if (ActionContext.To[Index] != NULL) {
  683. YypFree(ActionContext.To[Index]);
  684. }
  685. }
  686. YypFree(ActionContext.To);
  687. }
  688. if (ActionContext.Tally != NULL) {
  689. YypFree(ActionContext.Tally);
  690. }
  691. if (ActionContext.Width != NULL) {
  692. YypFree(ActionContext.Width);
  693. }
  694. if (ActionContext.Order != NULL) {
  695. YypFree(ActionContext.Order);
  696. }
  697. if (ActionContext.Base != NULL) {
  698. YypFree(ActionContext.Base);
  699. }
  700. if (ActionContext.Position != NULL) {
  701. YypFree(ActionContext.Position);
  702. }
  703. if (ActionContext.Table != NULL) {
  704. YypFree(ActionContext.Table);
  705. }
  706. if (ActionContext.Check != NULL) {
  707. YypFree(ActionContext.Check);
  708. }
  709. return YyStatus;
  710. }
  711. YY_STATUS
  712. YypCreateTokenActions (
  713. PYYGEN_CONTEXT Context,
  714. PYYGEN_ACTION_CONTEXT ActionContext
  715. )
  716. /*++
  717. Routine Description:
  718. This routine creates token based actions.
  719. Arguments:
  720. Context - Supplies a pointer to the initialized grammar context.
  721. ActionContext - Supplies a pointer to the working action state.
  722. Return Value:
  723. YY Status.
  724. --*/
  725. {
  726. PYYGEN_ACTION Action;
  727. PYY_VALUE ActionRow;
  728. UINT AllocationSize;
  729. YY_VALUE ReduceCount;
  730. YY_VALUE ShiftCount;
  731. YY_STATE_INDEX StateCount;
  732. YY_STATE_INDEX StateIndex;
  733. PYY_STATE_INDEX States;
  734. YY_VALUE Symbol;
  735. YY_VALUE SymbolMax;
  736. YY_VALUE SymbolMin;
  737. PYY_VALUE Symbols;
  738. YY_VALUE TokenCount;
  739. YY_VALUE VectorIndex;
  740. YY_STATUS YyStatus;
  741. TokenCount = Context->TokenCount + YYGEN_TOKEN_OUTPUT_BASE;
  742. StateCount = Context->StateCount;
  743. YyStatus = YyStatusNoMemory;
  744. //
  745. // The action row contains two consecutive arrays of tokens, the first for
  746. // states to shift to by symbol and the second of rules to reduce by for
  747. // the symbol.
  748. //
  749. AllocationSize = TokenCount * YYGEN_VECTORS_PER_STATE * sizeof(YY_VALUE);
  750. ActionRow = YypAllocate(AllocationSize);
  751. if (ActionRow == NULL) {
  752. goto CreateTokenActionsEnd;
  753. }
  754. for (StateIndex = 0; StateIndex < StateCount; StateIndex += 1) {
  755. if (Context->Parser[StateIndex] == NULL) {
  756. continue;
  757. }
  758. //
  759. // Zero out the action table for this state.
  760. //
  761. for (VectorIndex = 0;
  762. VectorIndex < (YYGEN_VECTORS_PER_STATE * TokenCount);
  763. VectorIndex += 1) {
  764. ActionRow[VectorIndex] = 0;
  765. }
  766. ShiftCount = 0;
  767. ReduceCount = 0;
  768. Action = Context->Parser[StateIndex];
  769. while (Action != NULL) {
  770. if (Action->Suppression == YyNotSuppressed) {
  771. Symbol = Action->Symbol;
  772. //
  773. // Potentially rebase every token but EOF and Error, for
  774. // compatibility.
  775. //
  776. if (Symbol > 1) {
  777. Symbol += YYGEN_TOKEN_OUTPUT_BASE;
  778. }
  779. //
  780. // For shifts, save the state number for that symbol.
  781. //
  782. if (Action->Code == YyActionShift) {
  783. ShiftCount += 1;
  784. ActionRow[Symbol] = Action->Number;
  785. //
  786. // For reductions (that aren't the sole reduction), save the
  787. // rule index by which it reduces.
  788. //
  789. } else if ((Action->Code == YyActionReduce) &&
  790. (Action->Number !=
  791. Context->DefaultReductions[StateIndex])) {
  792. ReduceCount += 1;
  793. ActionRow[Symbol + TokenCount] = Action->Number;
  794. }
  795. }
  796. Action = Action->Next;
  797. }
  798. //
  799. // Save the number of shifts and reductions in the tally.
  800. //
  801. ActionContext->Tally[StateIndex] = ShiftCount;
  802. ActionContext->Tally[StateIndex + StateCount] = ReduceCount;
  803. ActionContext->Width[StateIndex] = 0;
  804. ActionContext->Width[StateIndex + StateCount] = 0;
  805. //
  806. // Create the array of shifts in the from/to arrays for this state.
  807. //
  808. if (ShiftCount > 0) {
  809. SymbolMin = YY_VALUE_MAX;
  810. SymbolMax = 0;
  811. Symbols = YypAllocate(ShiftCount * sizeof(YY_VALUE));
  812. if (Symbols == NULL) {
  813. goto CreateTokenActionsEnd;
  814. }
  815. ActionContext->From[StateIndex] = Symbols;
  816. States = YypAllocate(ShiftCount * sizeof(YY_STATE_INDEX));
  817. if (States == NULL) {
  818. goto CreateTokenActionsEnd;
  819. }
  820. ActionContext->To[StateIndex] = States;
  821. for (Symbol = 0; Symbol < TokenCount; Symbol += 1) {
  822. if (ActionRow[Symbol] != 0) {
  823. if (SymbolMin > Symbol) {
  824. SymbolMin = Symbol;
  825. }
  826. if (SymbolMax < Symbol) {
  827. SymbolMax = Symbol;
  828. }
  829. *Symbols = Symbol;
  830. *States = ActionRow[Symbol];
  831. Symbols += 1;
  832. States += 1;
  833. }
  834. }
  835. //
  836. // Save the size of the range of symbols used by these shifts.
  837. //
  838. ActionContext->Width[StateIndex] = SymbolMax - SymbolMin + 1;
  839. }
  840. //
  841. // Create the array of reductions in the from/to arrays for this state.
  842. //
  843. if (ReduceCount > 0) {
  844. SymbolMin = YY_VALUE_MAX;
  845. SymbolMax = 0;
  846. Symbols = YypAllocate(ReduceCount * sizeof(YY_VALUE));
  847. if (Symbols == NULL) {
  848. goto CreateTokenActionsEnd;
  849. }
  850. ActionContext->From[StateCount + StateIndex] = Symbols;
  851. States = YypAllocate(ReduceCount * sizeof(YY_STATE_INDEX));
  852. if (States == NULL) {
  853. goto CreateTokenActionsEnd;
  854. }
  855. ActionContext->To[StateCount + StateIndex] = States;
  856. for (Symbol = 0; Symbol < TokenCount; Symbol += 1) {
  857. if (ActionRow[TokenCount + Symbol] != 0) {
  858. if (SymbolMin > Symbol) {
  859. SymbolMin = Symbol;
  860. }
  861. if (SymbolMax < Symbol) {
  862. SymbolMax = Symbol;
  863. }
  864. *Symbols = Symbol;
  865. *States = ActionRow[TokenCount + Symbol] - 2;
  866. Symbols += 1;
  867. States += 1;
  868. }
  869. }
  870. //
  871. // Save the range of symbols used by these reductions.
  872. //
  873. ActionContext->Width[StateCount + StateIndex] =
  874. SymbolMax - SymbolMin + 1;
  875. }
  876. }
  877. if ((Context->Flags & YYGEN_FLAG_DEBUG) != 0) {
  878. printf("\nToken Actions:");
  879. YypPrintOutputStates(Context, ActionContext);
  880. }
  881. YyStatus = YyStatusSuccess;
  882. CreateTokenActionsEnd:
  883. if (ActionRow != NULL) {
  884. YypFree(ActionRow);
  885. }
  886. return YyStatus;
  887. }
  888. YY_STATUS
  889. YypOutputDefaultGotos (
  890. PYYGEN_CONTEXT Context,
  891. PYYGEN_ACTION_CONTEXT ActionContext,
  892. FILE *File
  893. )
  894. /*++
  895. Routine Description:
  896. This routine prints the default goto actions to the source output, and
  897. computes the remaining gotos.
  898. Arguments:
  899. Context - Supplies a pointer to the initialized grammar context.
  900. ActionContext - Supplies a pointer to the action context.
  901. File - Supplies the file handle to output to.
  902. Return Value:
  903. YY Status.
  904. --*/
  905. {
  906. ULONG Column;
  907. YY_STATE_INDEX State;
  908. PYY_STATE_INDEX StateCounts;
  909. YY_VALUE Symbol;
  910. YY_STATUS YyStatus;
  911. YyStatus = YyStatusNoMemory;
  912. StateCounts = YypAllocate(sizeof(YY_STATE_INDEX) * Context->StateCount);
  913. if (StateCounts == NULL) {
  914. goto OutputDefaultGotosEnd;
  915. }
  916. YypOutputArrayBeginning(Context, File, "DefaultGoto");
  917. Column = 0;
  918. for (Symbol = Context->StartSymbol + 1;
  919. Symbol < Context->SymbolCount;
  920. Symbol += 1) {
  921. if (Column >= YY_VALUES_PER_LINES) {
  922. fprintf(File, "\n ");
  923. Column = 0;
  924. }
  925. Column += 1;
  926. State = YypFindDefaultGoto(Context, StateCounts, Symbol);
  927. YypOutputValue(Context, File, State);
  928. YyStatus = YypSaveColumn(Context, ActionContext, Symbol, State);
  929. if (YyStatus != YyStatusSuccess) {
  930. goto OutputDefaultGotosEnd;
  931. }
  932. }
  933. YypOutputArrayEnd(Context, File);
  934. YyStatus = YyStatusSuccess;
  935. OutputDefaultGotosEnd:
  936. if (StateCounts != NULL) {
  937. YypFree(StateCounts);
  938. }
  939. return YyStatus;
  940. }
  941. YY_STATE_INDEX
  942. YypFindDefaultGoto (
  943. PYYGEN_CONTEXT Context,
  944. PYY_STATE_INDEX StateCounts,
  945. YY_VALUE Symbol
  946. )
  947. /*++
  948. Routine Description:
  949. This routine returns the default goto state for the given symbol. This is
  950. the goto state that is referenced most often.
  951. Arguments:
  952. Context - Supplies a pointer to the initialized grammar context.
  953. StateCounts - Supplies a pointer to an array of counts, indexed by state.
  954. This is mainly handed down to avoid this routine having to allocate
  955. and free it each time.
  956. Symbol - Supplies the symbol to find the default goto for.
  957. Return Value:
  958. Returns the default goto state.
  959. --*/
  960. {
  961. YY_STATE_INDEX DefaultState;
  962. YY_GOTO_INDEX End;
  963. YY_GOTO_INDEX GotoIndex;
  964. YY_STATE_INDEX MaxCount;
  965. YY_GOTO_INDEX Start;
  966. YY_STATE_INDEX StateIndex;
  967. assert(Symbol >= Context->TokenCount);
  968. Start = Context->GotoMap[Symbol - Context->TokenCount];
  969. End = Context->GotoMap[Symbol + 1 - Context->TokenCount];
  970. if (Start == End) {
  971. return 0;
  972. }
  973. for (StateIndex = 0; StateIndex < Context->StateCount; StateIndex += 1) {
  974. StateCounts[StateIndex] = 0;
  975. }
  976. //
  977. // Count the number of times a state is referenced in the goto map.
  978. //
  979. for (GotoIndex = Start; GotoIndex < End; GotoIndex += 1) {
  980. StateCounts[Context->ToState[GotoIndex]] += 1;
  981. }
  982. //
  983. // Figure out which one was referenced the most.
  984. //
  985. MaxCount = 0;
  986. DefaultState = 0;
  987. for (StateIndex = 0; StateIndex < Context->StateCount; StateIndex += 1) {
  988. if (StateCounts[StateIndex] > MaxCount) {
  989. MaxCount = StateCounts[StateIndex];
  990. DefaultState = StateIndex;
  991. }
  992. }
  993. return DefaultState;
  994. }
  995. YY_STATUS
  996. YypSaveColumn (
  997. PYYGEN_CONTEXT Context,
  998. PYYGEN_ACTION_CONTEXT ActionContext,
  999. YY_VALUE Symbol,
  1000. YY_STATE_INDEX DefaultGoto
  1001. )
  1002. /*++
  1003. Routine Description:
  1004. This routine sets the from and to arrays for non-terminals.
  1005. Arguments:
  1006. Context - Supplies a pointer to the initialized grammar context.
  1007. ActionContext - Supplies a pointer to the action context.
  1008. Symbol - Supplies the non-terminal.
  1009. DefaultGoto - Supplies the default state to go to. This one doesn't need
  1010. to be in the array.
  1011. Return Value:
  1012. YY Status.
  1013. --*/
  1014. {
  1015. YY_STATE_INDEX Count;
  1016. YY_GOTO_INDEX End;
  1017. PYY_VALUE From;
  1018. PYY_VALUE FromStart;
  1019. YY_GOTO_INDEX GotoIndex;
  1020. YY_GOTO_INDEX Start;
  1021. PYY_VALUE To;
  1022. YY_VALUE VectorIndex;
  1023. assert(Symbol >= Context->TokenCount);
  1024. //
  1025. // Count the number of gotos excluding the most-used one.
  1026. //
  1027. Start = Context->GotoMap[Symbol - Context->TokenCount];
  1028. End = Context->GotoMap[Symbol + 1 - Context->TokenCount];
  1029. Count = 0;
  1030. for (GotoIndex = Start; GotoIndex < End; GotoIndex += 1) {
  1031. if (Context->ToState[GotoIndex] != DefaultGoto) {
  1032. Count += 1;
  1033. }
  1034. }
  1035. if (Count == 0) {
  1036. return YyStatusSuccess;
  1037. }
  1038. VectorIndex = (Symbol - (Context->StartSymbol + 1)) +
  1039. (Context->StateCount * YYGEN_VECTORS_PER_STATE);
  1040. assert((ActionContext->From[VectorIndex] == NULL) &&
  1041. (ActionContext->To[VectorIndex] == NULL));
  1042. From = YypAllocate(Count * sizeof(YY_VALUE));
  1043. if (From == NULL) {
  1044. return YyStatusNoMemory;
  1045. }
  1046. ActionContext->From[VectorIndex] = From;
  1047. FromStart = From;
  1048. To = YypAllocate(Count * sizeof(YY_VALUE));
  1049. if (To == NULL) {
  1050. return YyStatusNoMemory;
  1051. }
  1052. //
  1053. // Save the non-default gotos in the from/to arrays.
  1054. //
  1055. ActionContext->To[VectorIndex] = To;
  1056. for (GotoIndex = Start; GotoIndex < End; GotoIndex += 1) {
  1057. if (Context->ToState[GotoIndex] != DefaultGoto) {
  1058. *From = Context->FromState[GotoIndex];
  1059. *To = Context->ToState[GotoIndex];
  1060. From += 1;
  1061. To += 1;
  1062. }
  1063. }
  1064. ActionContext->Tally[VectorIndex] = Count;
  1065. From -= 1;
  1066. assert(From >= FromStart);
  1067. ActionContext->Width[VectorIndex] = *From - *FromStart + 1;
  1068. return YyStatusSuccess;
  1069. }
  1070. YY_STATUS
  1071. YypSortActions (
  1072. PYYGEN_CONTEXT Context,
  1073. PYYGEN_ACTION_CONTEXT ActionContext
  1074. )
  1075. /*++
  1076. Routine Description:
  1077. This routine reorganizes the action context arrays, sorting by tally count.
  1078. Arguments:
  1079. Context - Supplies a pointer to the initialized grammar context.
  1080. ActionContext - Supplies a pointer to the action context.
  1081. Return Value:
  1082. YY Status.
  1083. --*/
  1084. {
  1085. YY_VALUE EntryCount;
  1086. YY_VALUE MoveIndex;
  1087. PYY_VALUE Order;
  1088. YY_VALUE SearchIndex;
  1089. YY_VALUE Tally;
  1090. YY_VALUE VectorIndex;
  1091. YY_VALUE Width;
  1092. YY_STATUS YyStatus;
  1093. EntryCount = 0;
  1094. YyStatus = YyStatusNoMemory;
  1095. Order = YypAllocate(ActionContext->VectorCount * sizeof(YY_VALUE));
  1096. if (Order == NULL) {
  1097. goto SortActionsEnd;
  1098. }
  1099. ActionContext->Order = Order;
  1100. for (VectorIndex = 0;
  1101. VectorIndex < ActionContext->VectorCount;
  1102. VectorIndex += 1) {
  1103. if (ActionContext->Tally[VectorIndex] == 0) {
  1104. continue;
  1105. }
  1106. //
  1107. // Find the right spot to insert this entry, sorting primarily by the
  1108. // width, and then by tally for tiebreakers.
  1109. //
  1110. Tally = ActionContext->Tally[VectorIndex];
  1111. Width = ActionContext->Width[VectorIndex];
  1112. SearchIndex = EntryCount - 1;
  1113. while ((SearchIndex >= 0) &&
  1114. (ActionContext->Width[Order[SearchIndex]] < Width)) {
  1115. SearchIndex -= 1;
  1116. }
  1117. while ((SearchIndex >= 0) &&
  1118. (ActionContext->Width[Order[SearchIndex]] == Width) &&
  1119. (ActionContext->Tally[Order[SearchIndex]] < Tally)) {
  1120. SearchIndex -= 1;
  1121. }
  1122. //
  1123. // Slide the other entries over.
  1124. //
  1125. for (MoveIndex = EntryCount - 1;
  1126. MoveIndex > SearchIndex;
  1127. MoveIndex -= 1) {
  1128. Order[MoveIndex + 1] = Order[MoveIndex];
  1129. }
  1130. Order[SearchIndex + 1] = VectorIndex;
  1131. EntryCount += 1;
  1132. }
  1133. if ((Context->Flags & YYGEN_FLAG_DEBUG) != 0) {
  1134. printf("\nOrder: (%d vectors, %d entries)\n",
  1135. ActionContext->VectorCount,
  1136. EntryCount);
  1137. for (VectorIndex = 0; VectorIndex < EntryCount; VectorIndex += 1) {
  1138. printf(" %d: %d\n", VectorIndex, Order[VectorIndex]);
  1139. }
  1140. }
  1141. YyStatus = YyStatusSuccess;
  1142. SortActionsEnd:
  1143. ActionContext->EntryCount = EntryCount;
  1144. return YyStatus;
  1145. }
  1146. YY_STATUS
  1147. YypPackOutputTable (
  1148. PYYGEN_CONTEXT Context,
  1149. PYYGEN_ACTION_CONTEXT ActionContext
  1150. )
  1151. /*++
  1152. Routine Description:
  1153. This routine creates the final output table, in a minimal representation.
  1154. Arguments:
  1155. Context - Supplies a pointer to the initialized grammar context.
  1156. ActionContext - Supplies a pointer to the action context.
  1157. Return Value:
  1158. YY Status.
  1159. --*/
  1160. {
  1161. YY_VALUE EntryIndex;
  1162. YY_STATE_INDEX State;
  1163. YY_VALUE TableIndex;
  1164. YY_STATUS YyStatus;
  1165. YyStatus = YyStatusNoMemory;
  1166. ActionContext->Base =
  1167. YypAllocate(ActionContext->VectorCount * sizeof(YY_VALUE));
  1168. if (ActionContext->Base == NULL) {
  1169. goto PackOutputTableEnd;
  1170. }
  1171. ActionContext->Position =
  1172. YypAllocate(ActionContext->EntryCount * sizeof(YY_VALUE));
  1173. if (ActionContext->Position == NULL) {
  1174. goto PackOutputTableEnd;
  1175. }
  1176. for (EntryIndex = 0;
  1177. EntryIndex < ActionContext->EntryCount;
  1178. EntryIndex += 1) {
  1179. State = YypFindMatchingVector(Context, ActionContext, EntryIndex);
  1180. if (State < 0) {
  1181. YyStatus = YypPackVector(ActionContext, EntryIndex, &TableIndex);
  1182. if (YyStatus != YyStatusSuccess) {
  1183. goto PackOutputTableEnd;
  1184. }
  1185. } else {
  1186. TableIndex = ActionContext->Base[State];
  1187. }
  1188. ActionContext->Position[EntryIndex] = TableIndex;
  1189. ActionContext->Base[ActionContext->Order[EntryIndex]] = TableIndex;
  1190. }
  1191. YyStatus = YyStatusSuccess;
  1192. PackOutputTableEnd:
  1193. return YyStatus;
  1194. }
  1195. YY_STATUS
  1196. YypPackVector (
  1197. PYYGEN_ACTION_CONTEXT ActionContext,
  1198. YY_VALUE EntryIndex,
  1199. PYY_VALUE TableIndex
  1200. )
  1201. /*++
  1202. Routine Description:
  1203. This routine adds entries in the final output table (and check table)
  1204. corresponding to the given state.
  1205. Arguments:
  1206. ActionContext - Supplies a pointer to the action context.
  1207. EntryIndex - Supplies the state to add table entries for.
  1208. TableIndex - Supplies a pointer where the corresponding index in the table
  1209. will be returned.
  1210. Return Value:
  1211. YY Status.
  1212. --*/
  1213. {
  1214. YY_VALUE ActionIndex;
  1215. YY_VALUE BaseIndex;
  1216. YY_VALUE CopyIndex;
  1217. PYY_VALUE From;
  1218. YY_VALUE MaxIndex;
  1219. PYY_VALUE NewBuffer;
  1220. YY_VALUE NewCapacity;
  1221. YY_VALUE OrderIndex;
  1222. BOOL RangeFree;
  1223. YY_VALUE Tally;
  1224. PYY_VALUE To;
  1225. OrderIndex = ActionContext->Order[EntryIndex];
  1226. Tally = ActionContext->Tally[OrderIndex];
  1227. assert(Tally != 0);
  1228. From = ActionContext->From[OrderIndex];
  1229. To = ActionContext->To[OrderIndex];
  1230. //
  1231. // Figure out the highest index, minus the lowest free index in the table.
  1232. //
  1233. BaseIndex = ActionContext->Low - From[0];
  1234. for (ActionIndex = 1; ActionIndex < Tally; ActionIndex += 1) {
  1235. if (BaseIndex < ActionContext->Low - From[ActionIndex]) {
  1236. BaseIndex = ActionContext->Low - From[ActionIndex];
  1237. }
  1238. }
  1239. //
  1240. // Find an appropriate index in the table (with a free range that's big
  1241. // enough), and make sure the table is sized big enough for this range.
  1242. //
  1243. while (TRUE) {
  1244. //
  1245. // Reserve index zero.
  1246. //
  1247. if (BaseIndex == 0) {
  1248. BaseIndex += 1;
  1249. continue;
  1250. }
  1251. RangeFree = TRUE;
  1252. for (ActionIndex = 0; ActionIndex < Tally; ActionIndex += 1) {
  1253. MaxIndex = BaseIndex + From[ActionIndex];
  1254. //
  1255. // Reallocate the table if needed.
  1256. //
  1257. if (MaxIndex + 1 >= ActionContext->TableCapacity) {
  1258. if (MaxIndex + 1 >= YY_MAX_TABLE) {
  1259. return YyStatusTooManyItems;
  1260. }
  1261. NewCapacity = ActionContext->TableCapacity;
  1262. while (MaxIndex + 1 >= NewCapacity) {
  1263. NewCapacity += 256;
  1264. }
  1265. NewBuffer = YypReallocate(ActionContext->Table,
  1266. NewCapacity * sizeof(YY_VALUE));
  1267. if (NewBuffer == NULL) {
  1268. return YyStatusNoMemory;
  1269. }
  1270. ActionContext->Table = NewBuffer;
  1271. NewBuffer = YypReallocate(ActionContext->Check,
  1272. NewCapacity * sizeof(YY_VALUE));
  1273. if (NewBuffer == NULL) {
  1274. return YyStatusNoMemory;
  1275. }
  1276. ActionContext->Check = NewBuffer;
  1277. for (CopyIndex = ActionContext->TableCapacity;
  1278. CopyIndex < NewCapacity;
  1279. CopyIndex += 1) {
  1280. ActionContext->Table[CopyIndex] = 0;
  1281. ActionContext->Check[CopyIndex] = -1;
  1282. }
  1283. ActionContext->TableCapacity = NewCapacity;
  1284. }
  1285. if (ActionContext->Check[MaxIndex] != -1) {
  1286. RangeFree = FALSE;
  1287. break;
  1288. }
  1289. }
  1290. //
  1291. // Also check the position array to see if this base is in use
  1292. // already.
  1293. //
  1294. if (RangeFree != FALSE) {
  1295. for (ActionIndex = 0; ActionIndex < EntryIndex; ActionIndex += 1) {
  1296. if (ActionContext->Position[ActionIndex] == BaseIndex) {
  1297. RangeFree = FALSE;
  1298. break;
  1299. }
  1300. }
  1301. }
  1302. if (RangeFree != FALSE) {
  1303. break;
  1304. }
  1305. BaseIndex += 1;
  1306. }
  1307. //
  1308. // A free range was found. Copy the tos and froms into the table and check.
  1309. //
  1310. for (ActionIndex = 0; ActionIndex < Tally; ActionIndex += 1) {
  1311. CopyIndex = BaseIndex + From[ActionIndex];
  1312. ActionContext->Table[CopyIndex] = To[ActionIndex];
  1313. ActionContext->Check[CopyIndex] = From[ActionIndex];
  1314. if (ActionContext->High < CopyIndex) {
  1315. ActionContext->High = CopyIndex;
  1316. }
  1317. }
  1318. //
  1319. // Also update the lowest free index. The table is always one bigger than
  1320. // the max index used, so don't worry about slipping off the end.
  1321. //
  1322. while (ActionContext->Check[ActionContext->Low] != -1) {
  1323. ActionContext->Low += 1;
  1324. }
  1325. *TableIndex = BaseIndex;
  1326. return YyStatusSuccess;
  1327. }
  1328. YY_STATE_INDEX
  1329. YypFindMatchingVector (
  1330. PYYGEN_CONTEXT Context,
  1331. PYYGEN_ACTION_CONTEXT ActionContext,
  1332. YY_VALUE EntryIndex
  1333. )
  1334. /*++
  1335. Routine Description:
  1336. This routine attempts to match the current set of froms and tos to a
  1337. previous set.
  1338. Arguments:
  1339. Context - Supplies a pointer to the application context.
  1340. ActionContext - Supplies a pointer to the action context.
  1341. EntryIndex - Supplies the entry index to match on.
  1342. Return Value:
  1343. Returns the index of a state (in the from/to arrays) where the given set
  1344. of shift or reduce actions occurred previously.
  1345. -1 if this is a new set of actions.
  1346. --*/
  1347. {
  1348. YY_VALUE CheckIndex;
  1349. BOOL Match;
  1350. YY_VALUE OrderIndex;
  1351. YY_VALUE SearchOrder;
  1352. YY_VALUE Tally;
  1353. YY_VALUE Width;
  1354. OrderIndex = ActionContext->Order[EntryIndex];
  1355. if (OrderIndex > (Context->StateCount * 2)) {
  1356. return -1;
  1357. }
  1358. Tally = ActionContext->Tally[OrderIndex];
  1359. Width = ActionContext->Width[OrderIndex];
  1360. EntryIndex -= 1;
  1361. while (EntryIndex >= 0) {
  1362. SearchOrder = ActionContext->Order[EntryIndex];
  1363. //
  1364. // Quick exit check if the widths or tallies don't match. Since the
  1365. // order had them sorted by width and then tally, as soon as they don't
  1366. // match, none will.
  1367. //
  1368. if ((ActionContext->Width[SearchOrder] != Width) ||
  1369. (ActionContext->Tally[SearchOrder] != Tally)) {
  1370. return -1;
  1371. }
  1372. Match = TRUE;
  1373. for (CheckIndex = 0; CheckIndex < Tally; CheckIndex += 1) {
  1374. if ((ActionContext->To[SearchOrder][CheckIndex] !=
  1375. ActionContext->To[OrderIndex][CheckIndex]) ||
  1376. (ActionContext->From[SearchOrder][CheckIndex] !=
  1377. ActionContext->From[OrderIndex][CheckIndex])) {
  1378. Match = FALSE;
  1379. break;
  1380. }
  1381. }
  1382. if (Match != FALSE) {
  1383. return SearchOrder;
  1384. }
  1385. EntryIndex -= 1;
  1386. }
  1387. return -1;
  1388. }
  1389. YY_STATUS
  1390. YypOutputDebug (
  1391. PYYGEN_CONTEXT Context,
  1392. FILE *File,
  1393. PYY_VALUE UndefinedToken
  1394. )
  1395. /*++
  1396. Routine Description:
  1397. This routine outputs debugging information to the parser source file.
  1398. Arguments:
  1399. Context - Supplies a pointer to the application context.
  1400. File - Supplies a pointer to the file to output to.
  1401. UndefinedToken - Supplies a pointer where the undefined token index into
  1402. the names will be returned.
  1403. Return Value:
  1404. YY Status.
  1405. --*/
  1406. {
  1407. YY_VALUE Index;
  1408. PYY_VALUE Items;
  1409. PSTR Name;
  1410. PYYGEN_RULE Rule;
  1411. PSTR *SymbolNames;
  1412. YY_VALUE TokenCount;
  1413. TokenCount = Context->TokenCount + YYGEN_TOKEN_OUTPUT_BASE;
  1414. *UndefinedToken = TokenCount;
  1415. SymbolNames = YypAllocate((TokenCount + 1) * sizeof(PSTR));
  1416. if (SymbolNames == NULL) {
  1417. return YyStatusNoMemory;
  1418. }
  1419. //
  1420. // EOF doesn't get rebased, but everything else does.
  1421. //
  1422. SymbolNames[0] = Context->Elements[0].Name;
  1423. for (Index = 1; Index < Context->TokenCount; Index += 1) {
  1424. SymbolNames[Index + YYGEN_TOKEN_OUTPUT_BASE] =
  1425. Context->Elements[Index].Name;
  1426. }
  1427. SymbolNames[Index + YYGEN_TOKEN_OUTPUT_BASE] = "illegal-symbol";
  1428. fprintf(File, "const char *%s%s[] = {", Context->VariablePrefix, "Names");
  1429. for (Index = 0; Index < TokenCount + 1; Index += 1) {
  1430. Name = SymbolNames[Index];
  1431. if (Name != NULL) {
  1432. fprintf(File, "\n \"");
  1433. YypOutputString(File, Name);
  1434. fprintf(File, "\",");
  1435. } else {
  1436. fprintf(File, "\n 0,");
  1437. }
  1438. }
  1439. YypOutputArrayEnd(Context, File);
  1440. fprintf(File, "const char *%s%s[] = {", Context->VariablePrefix, "Rules");
  1441. for (Index = 2; Index < Context->RuleCount; Index += 1) {
  1442. Rule = &(Context->Rules[Index]);
  1443. fprintf(File, "\n \"");
  1444. YypOutputString(File, Context->Elements[Rule->LeftSide].Name);
  1445. fprintf(File, " :");
  1446. Items = Context->Items + Rule->RightSide;
  1447. while (*Items > 0) {
  1448. fprintf(File, " ");
  1449. YypOutputString(File, Context->Elements[*Items].Name);
  1450. Items += 1;
  1451. }
  1452. fprintf(File, "\",");
  1453. }
  1454. YypOutputArrayEnd(Context, File);
  1455. YypFree(SymbolNames);
  1456. return YyStatusSuccess;
  1457. }
  1458. VOID
  1459. YypOutputArray (
  1460. PYYGEN_CONTEXT Context,
  1461. FILE *File,
  1462. PSTR Name,
  1463. PYY_VALUE Array,
  1464. YY_VALUE Size
  1465. )
  1466. /*++
  1467. Routine Description:
  1468. This routine prints an array to the output source.
  1469. Arguments:
  1470. Context - Supplies a pointer to the initialized grammar context.
  1471. File - Supplies the file handle to output to.
  1472. Name - Supplies the name of the array.
  1473. Array - Supplies the array values.
  1474. Size - Supplies the number of elements in the array.
  1475. Return Value:
  1476. None.
  1477. --*/
  1478. {
  1479. ULONG Column;
  1480. YY_VALUE Index;
  1481. YypOutputArrayBeginning(Context, File, Name);
  1482. Column = 0;
  1483. for (Index = 0; Index < Size; Index += 1) {
  1484. if (Column >= YY_VALUES_PER_LINES) {
  1485. fprintf(File, "\n ");
  1486. Column = 0;
  1487. }
  1488. Column += 1;
  1489. YypOutputValue(Context, File, Array[Index]);
  1490. }
  1491. YypOutputArrayEnd(Context, File);
  1492. return;
  1493. }
  1494. VOID
  1495. YypOutputArrayBeginning (
  1496. PYYGEN_CONTEXT Context,
  1497. FILE *File,
  1498. PSTR Name
  1499. )
  1500. /*++
  1501. Routine Description:
  1502. This routine prints an array beginning source line.
  1503. Arguments:
  1504. Context - Supplies a pointer to the initialized grammar context.
  1505. File - Supplies the file handle to output to.
  1506. Name - Supplies the name of the array.
  1507. Return Value:
  1508. None.
  1509. --*/
  1510. {
  1511. fprintf(File,
  1512. "const YY_VALUE %s%s[] = {\n ",
  1513. Context->VariablePrefix,
  1514. Name);
  1515. return;
  1516. }
  1517. VOID
  1518. YypOutputArrayEnd (
  1519. PYYGEN_CONTEXT Context,
  1520. FILE *File
  1521. )
  1522. /*++
  1523. Routine Description:
  1524. This routine prints an array termination source.
  1525. Arguments:
  1526. Context - Supplies a pointer to the initialized grammar context.
  1527. File - Supplies the file handle to output to.
  1528. Name - Supplies the name of the array.
  1529. Return Value:
  1530. None.
  1531. --*/
  1532. {
  1533. fprintf(File, "\n};\n\n");
  1534. return;
  1535. }
  1536. VOID
  1537. YypOutputValue (
  1538. PYYGEN_CONTEXT Context,
  1539. FILE *File,
  1540. YY_VALUE Value
  1541. )
  1542. /*++
  1543. Routine Description:
  1544. This routine prints a single integer to the output source file.
  1545. Arguments:
  1546. Context - Supplies a pointer to the initialized grammar context.
  1547. File - Supplies the file handle to output to.
  1548. Value - Supplies the value to print.
  1549. Return Value:
  1550. None.
  1551. --*/
  1552. {
  1553. fprintf(File, " %d,", Value);
  1554. return;
  1555. }
  1556. VOID
  1557. YypOutputString (
  1558. FILE *File,
  1559. PSTR String
  1560. )
  1561. /*++
  1562. Routine Description:
  1563. This routine prints a C source string to the given output. It does not
  1564. print the surrounding quotation marks.
  1565. Arguments:
  1566. File - Supplies the file handle to output to.
  1567. String - Supplies the string to print in C source form.
  1568. Return Value:
  1569. None.
  1570. --*/
  1571. {
  1572. while (*String != '\0') {
  1573. switch (*String) {
  1574. case '\n':
  1575. fprintf(File, "\\n");
  1576. break;
  1577. case '\v':
  1578. fprintf(File, "\\v");
  1579. break;
  1580. case '\t':
  1581. fprintf(File, "\\t");
  1582. break;
  1583. case '\r':
  1584. fprintf(File, "\\r");
  1585. break;
  1586. case '\f':
  1587. fprintf(File, "\\f");
  1588. break;
  1589. case '\a':
  1590. fprintf(File, "\\a");
  1591. break;
  1592. case '\b':
  1593. fprintf(File, "\\b");
  1594. break;
  1595. case '\\':
  1596. fprintf(File, "\\\\");
  1597. break;
  1598. default:
  1599. if (isprint(*String)) {
  1600. fputc(*String, File);
  1601. }
  1602. break;
  1603. }
  1604. String += 1;
  1605. }
  1606. return;
  1607. }
  1608. VOID
  1609. YypOutputGrammarStructure (
  1610. PYYGEN_CONTEXT Context,
  1611. FILE *File,
  1612. YY_VALUE TableSize,
  1613. YY_VALUE UndefinedToken
  1614. )
  1615. /*++
  1616. Routine Description:
  1617. This routine prints the final structure that ties the grammar together.
  1618. Arguments:
  1619. Context - Supplies a pointer to the initialized grammar context.
  1620. File - Supplies the file handle to output to.
  1621. TableSize - Supplies the number of elements in the table.
  1622. UndefinedToken - Supplies the index into the names array where the
  1623. description for an undefined token lies.
  1624. Return Value:
  1625. None.
  1626. --*/
  1627. {
  1628. YY_VALUE Start;
  1629. fprintf(File, "YY_GRAMMAR %sGrammar = {\n", Context->VariablePrefix);
  1630. fprintf(File, " %sLeftSide,\n", Context->VariablePrefix);
  1631. fprintf(File, " %sRuleLength,\n", Context->VariablePrefix);
  1632. fprintf(File, " %sDefaultReductions,\n", Context->VariablePrefix);
  1633. fprintf(File, " %sShiftIndex,\n", Context->VariablePrefix);
  1634. fprintf(File, " %sReduceIndex,\n", Context->VariablePrefix);
  1635. fprintf(File, " %sGotoIndex,\n", Context->VariablePrefix);
  1636. fprintf(File, " %sTable,\n", Context->VariablePrefix);
  1637. fprintf(File, " %sCheck,\n", Context->VariablePrefix);
  1638. fprintf(File, " %sDefaultGoto,\n", Context->VariablePrefix);
  1639. fprintf(File, " %d,\n", TableSize);
  1640. fprintf(File, " %sNames,\n", Context->VariablePrefix);
  1641. fprintf(File, " %sRules,\n", Context->VariablePrefix);
  1642. fprintf(File, " %d,\n", Context->FinalState);
  1643. Start = Context->Items[Context->Rules[2].RightSide] -
  1644. (Context->StartSymbol + 1);
  1645. fprintf(File, " %d,\n", Start);
  1646. fprintf(File,
  1647. " %d,\n",
  1648. Context->TokenCount + YYGEN_TOKEN_OUTPUT_BASE - 1);
  1649. fprintf(File, " %d,\n", UndefinedToken);
  1650. fprintf(File, "};\n\n");
  1651. return;
  1652. }
  1653. VOID
  1654. YypPrintOutputStates (
  1655. PYYGEN_CONTEXT Context,
  1656. PYYGEN_ACTION_CONTEXT ActionContext
  1657. )
  1658. /*++
  1659. Routine Description:
  1660. This routine prints the actions as defined by the output generator.
  1661. Arguments:
  1662. Context - Supplies a pointer to the initialized grammar context.
  1663. ActionContext - Supplies a pointer to the initialized action context.
  1664. Return Value:
  1665. None.
  1666. --*/
  1667. {
  1668. YY_VALUE ActionIndex;
  1669. YY_STATE_INDEX StateIndex;
  1670. printf("\nShift Output Actions:\n");
  1671. for (StateIndex = 0; StateIndex < Context->StateCount; StateIndex += 1) {
  1672. printf(" %d: %d (width %d)\n",
  1673. StateIndex,
  1674. ActionContext->Tally[StateIndex],
  1675. ActionContext->Width[StateIndex]);
  1676. for (ActionIndex = 0;
  1677. ActionIndex < ActionContext->Tally[StateIndex];
  1678. ActionIndex += 1) {
  1679. printf(" %d -> %d\n",
  1680. ActionContext->From[StateIndex][ActionIndex],
  1681. ActionContext->To[StateIndex][ActionIndex]);
  1682. }
  1683. }
  1684. printf("\nReduce Output Actions:\n");
  1685. for (StateIndex = Context->StateCount;
  1686. StateIndex < (Context->StateCount * 2);
  1687. StateIndex += 1) {
  1688. printf(" %d: %d (width %d)\n",
  1689. StateIndex - Context->StateCount,
  1690. ActionContext->Tally[StateIndex],
  1691. ActionContext->Width[StateIndex]);
  1692. for (ActionIndex = 0;
  1693. ActionIndex < ActionContext->Tally[StateIndex];
  1694. ActionIndex += 1) {
  1695. printf(" %d -> %d\n",
  1696. ActionContext->From[StateIndex][ActionIndex],
  1697. ActionContext->To[StateIndex][ActionIndex]);
  1698. }
  1699. }
  1700. return;
  1701. }