rlparse.kl 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513
  1. /*
  2. * Copyright 2001-2007 Adrian Thurston <thurston@complang.org>
  3. */
  4. /* This file is part of Ragel.
  5. *
  6. * Ragel is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Ragel is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Ragel; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. */
  20. #include "rlparse.h"
  21. #include "ragel.h"
  22. #include <iostream>
  23. #include <errno.h>
  24. #include <stdlib.h>
  25. using std::cout;
  26. using std::cerr;
  27. using std::endl;
  28. %%{
  29. parser Parser;
  30. include "rlparse.kh";
  31. start: section_list;
  32. section_list: section_list statement_list TK_EndSection;
  33. section_list: ;
  34. statement_list: statement_list statement;
  35. statement_list: ;
  36. statement: assignment commit;
  37. statement: instantiation commit;
  38. statement: action_spec commit;
  39. statement: alphtype_spec commit;
  40. statement: range_spec commit;
  41. statement: getkey_spec commit;
  42. statement: access_spec commit;
  43. statement: variable_spec commit;
  44. statement: export_block commit;
  45. statement: pre_push_spec commit;
  46. statement: post_pop_spec commit;
  47. statement: length_spec commit;
  48. length_spec:
  49. KW_Length TK_Word ';'
  50. final {
  51. LengthDef *lengthDef = new LengthDef( $2->data );
  52. pd->lengthDefList.append( lengthDef );
  53. /* Generic creation of machine for instantiation and assignment. */
  54. MachineDef *machineDef = new MachineDef( lengthDef );
  55. tryMachineDef( $2->loc, $2->data, machineDef, false );
  56. };
  57. pre_push_spec:
  58. KW_PrePush '{' inline_block '}'
  59. final {
  60. if ( pd->prePushExpr != 0 ) {
  61. /* Recover by just ignoring the duplicate. */
  62. error($2->loc) << "pre_push code already defined" << endl;
  63. }
  64. pd->prePushExpr = $3->inlineList;
  65. };
  66. post_pop_spec:
  67. KW_PostPop '{' inline_block '}'
  68. final {
  69. if ( pd->postPopExpr != 0 ) {
  70. /* Recover by just ignoring the duplicate. */
  71. error($2->loc) << "post_pop code already defined" << endl;
  72. }
  73. pd->postPopExpr = $3->inlineList;
  74. };
  75. export_open: KW_Export
  76. final {
  77. exportContext.append( true );
  78. };
  79. nonterm opt_export
  80. {
  81. bool isSet;
  82. };
  83. opt_export: export_open final { $$->isSet = true; };
  84. opt_export: final { $$->isSet = false; };
  85. export_block: export_open '{' statement_list '}'
  86. final {
  87. exportContext.remove( exportContext.length()-1 );
  88. };
  89. assignment:
  90. opt_export machine_name '=' join ';' final {
  91. /* Main machine must be an instance. */
  92. bool isInstance = false;
  93. if ( strcmp($2->token.data, mainMachine) == 0 ) {
  94. warning($2->token.loc) <<
  95. "main machine will be implicitly instantiated" << endl;
  96. isInstance = true;
  97. }
  98. /* Generic creation of machine for instantiation and assignment. */
  99. MachineDef *machineDef = new MachineDef( $4->join );
  100. tryMachineDef( $2->token.loc, $2->token.data, machineDef, isInstance );
  101. if ( $1->isSet )
  102. exportContext.remove( exportContext.length()-1 );
  103. $4->join->loc = $3->loc;
  104. };
  105. instantiation:
  106. opt_export machine_name TK_ColonEquals join_or_lm ';' final {
  107. /* Generic creation of machine for instantiation and assignment. */
  108. tryMachineDef( $2->token.loc, $2->token.data, $4->machineDef, true );
  109. if ( $1->isSet )
  110. exportContext.remove( exportContext.length()-1 );
  111. /* Pass a location to join_or_lm */
  112. if ( $4->machineDef->join != 0 )
  113. $4->machineDef->join->loc = $3->loc;
  114. };
  115. type token_type
  116. {
  117. Token token;
  118. };
  119. nonterm machine_name uses token_type;
  120. machine_name:
  121. TK_Word final {
  122. /* Make/get the priority key. The name may have already been referenced
  123. * and therefore exist. */
  124. PriorDictEl *priorDictEl;
  125. if ( pd->priorDict.insert( $1->data, pd->nextPriorKey, &priorDictEl ) )
  126. pd->nextPriorKey += 1;
  127. pd->curDefPriorKey = priorDictEl->value;
  128. /* Make/get the local error key. */
  129. LocalErrDictEl *localErrDictEl;
  130. if ( pd->localErrDict.insert( $1->data, pd->nextLocalErrKey, &localErrDictEl ) )
  131. pd->nextLocalErrKey += 1;
  132. pd->curDefLocalErrKey = localErrDictEl->value;
  133. $$->token = *$1;
  134. };
  135. action_spec:
  136. KW_Action TK_Word '{' inline_block '}' final {
  137. if ( pd->actionDict.find( $2->data ) ) {
  138. /* Recover by just ignoring the duplicate. */
  139. error($2->loc) << "action \"" << $2->data << "\" already defined" << endl;
  140. }
  141. else {
  142. //cerr << "NEW ACTION " << $2->data << " " << $4->inlineList << endl;
  143. /* Add the action to the list of actions. */
  144. Action *newAction = new Action( $3->loc, $2->data,
  145. $4->inlineList, pd->nextCondId++ );
  146. /* Insert to list and dict. */
  147. pd->actionList.append( newAction );
  148. pd->actionDict.insert( newAction );
  149. }
  150. };
  151. # Specifies the data type of the input alphabet. One or two words followed by a
  152. # semi-colon.
  153. alphtype_spec:
  154. KW_AlphType TK_Word TK_Word ';' final {
  155. if ( ! pd->setAlphType( $1->loc, $2->data, $3->data ) ) {
  156. // Recover by ignoring the alphtype statement.
  157. error($2->loc) << "\"" << $2->data <<
  158. " " << $3->data << "\" is not a valid alphabet type" << endl;
  159. }
  160. };
  161. alphtype_spec:
  162. KW_AlphType TK_Word ';' final {
  163. if ( ! pd->setAlphType( $1->loc, $2->data ) ) {
  164. // Recover by ignoring the alphtype statement.
  165. error($2->loc) << "\"" << $2->data <<
  166. "\" is not a valid alphabet type" << endl;
  167. }
  168. };
  169. # Specifies a range to assume that the input characters will fall into.
  170. range_spec:
  171. KW_Range alphabet_num alphabet_num ';' final {
  172. // Save the upper and lower ends of the range and emit the line number.
  173. pd->lowerNum = $2->token.data;
  174. pd->upperNum = $3->token.data;
  175. pd->rangeLowLoc = $2->token.loc;
  176. pd->rangeHighLoc = $3->token.loc;
  177. };
  178. getkey_spec:
  179. KW_GetKey inline_expr ';' final {
  180. pd->getKeyExpr = $2->inlineList;
  181. };
  182. access_spec:
  183. KW_Access inline_expr ';' final {
  184. pd->accessExpr = $2->inlineList;
  185. };
  186. variable_spec:
  187. KW_Variable opt_whitespace TK_Word inline_expr ';' final {
  188. /* FIXME: Need to implement the rest of this. */
  189. bool wasSet = pd->setVariable( $3->data, $4->inlineList );
  190. if ( !wasSet )
  191. error($3->loc) << "bad variable name" << endl;
  192. };
  193. opt_whitespace: opt_whitespace IL_WhiteSpace;
  194. opt_whitespace: ;
  195. #
  196. # Expressions
  197. #
  198. nonterm join_or_lm
  199. {
  200. MachineDef *machineDef;
  201. };
  202. join_or_lm:
  203. join final {
  204. $$->machineDef = new MachineDef( $1->join );
  205. };
  206. join_or_lm:
  207. TK_BarStar lm_part_list '*' '|' final {
  208. /* Create a new factor going to a longest match structure. Record
  209. * in the parse data that we have a longest match. */
  210. LongestMatch *lm = new LongestMatch( $1->loc, $2->lmPartList );
  211. pd->lmList.append( lm );
  212. for ( LmPartList::Iter lmp = *($2->lmPartList); lmp.lte(); lmp++ )
  213. lmp->longestMatch = lm;
  214. $$->machineDef = new MachineDef( lm );
  215. };
  216. nonterm lm_part_list
  217. {
  218. LmPartList *lmPartList;
  219. };
  220. lm_part_list:
  221. lm_part_list longest_match_part
  222. final {
  223. if ( $2->lmPart != 0 )
  224. $1->lmPartList->append( $2->lmPart );
  225. $$->lmPartList = $1->lmPartList;
  226. };
  227. lm_part_list:
  228. longest_match_part
  229. final {
  230. /* Create a new list with the part. */
  231. $$->lmPartList = new LmPartList;
  232. if ( $1->lmPart != 0 )
  233. $$->lmPartList->append( $1->lmPart );
  234. };
  235. nonterm longest_match_part
  236. {
  237. LongestMatchPart *lmPart;
  238. };
  239. longest_match_part:
  240. action_spec final { $$->lmPart = 0; };
  241. longest_match_part:
  242. assignment final { $$->lmPart = 0; };
  243. longest_match_part:
  244. join opt_lm_part_action ';' final {
  245. $$->lmPart = 0;
  246. Action *action = $2->action;
  247. if ( action != 0 )
  248. action->isLmAction = true;
  249. $$->lmPart = new LongestMatchPart( $1->join, action,
  250. $3->loc, pd->nextLongestMatchId++ );
  251. /* Provide a location to join. Unfortunately We don't
  252. * have the start of the join as in other occurances. Use the end. */
  253. $1->join->loc = $3->loc;
  254. };
  255. nonterm opt_lm_part_action
  256. {
  257. Action *action;
  258. };
  259. opt_lm_part_action:
  260. TK_DoubleArrow action_embed final {
  261. $$->action = $2->action;
  262. };
  263. opt_lm_part_action:
  264. action_embed_block final {
  265. $$->action = $1->action;
  266. };
  267. opt_lm_part_action:
  268. final {
  269. $$->action = 0;
  270. };
  271. nonterm join
  272. {
  273. Join *join;
  274. };
  275. join:
  276. join ',' expression final {
  277. /* Append the expression to the list and return it. */
  278. $1->join->exprList.append( $3->expression );
  279. $$->join = $1->join;
  280. };
  281. join:
  282. expression final {
  283. $$->join = new Join( $1->expression );
  284. };
  285. nonterm expression
  286. {
  287. Expression *expression;
  288. };
  289. expression:
  290. expression '|' term_short final {
  291. $$->expression = new Expression( $1->expression,
  292. $3->term, Expression::OrType );
  293. };
  294. expression:
  295. expression '&' term_short final {
  296. $$->expression = new Expression( $1->expression,
  297. $3->term, Expression::IntersectType );
  298. };
  299. expression:
  300. expression '-' term_short final {
  301. $$->expression = new Expression( $1->expression,
  302. $3->term, Expression::SubtractType );
  303. };
  304. expression:
  305. expression TK_DashDash term_short final {
  306. $$->expression = new Expression( $1->expression,
  307. $3->term, Expression::StrongSubtractType );
  308. };
  309. expression:
  310. term_short final {
  311. $$->expression = new Expression( $1->term );
  312. };
  313. # This is where we resolve the ambiguity involving -. By default ragel tries to
  314. # do a longest match, which gives precedence to a concatenation because it is
  315. # innermost. What we need is to force term into a shortest match so that when -
  316. # is seen it doesn't try to extend term with a concatenation, but ends term and
  317. # goes for a subtraction.
  318. #
  319. # The shortest tag overrides the default longest match action ordering strategy
  320. # and instead forces a shortest match stragegy. The wrap the term production in
  321. # a new nonterminal 'term_short' to guarantee the shortest match behaviour.
  322. shortest term_short;
  323. nonterm term_short
  324. {
  325. Term *term;
  326. };
  327. term_short:
  328. term final {
  329. $$->term = $1->term;
  330. };
  331. nonterm term
  332. {
  333. Term *term;
  334. };
  335. term:
  336. term factor_with_label final {
  337. $$->term = new Term( $1->term, $2->factorWithAug );
  338. };
  339. term:
  340. term '.' factor_with_label final {
  341. $$->term = new Term( $1->term, $3->factorWithAug );
  342. };
  343. term:
  344. term TK_ColonGt factor_with_label final {
  345. $$->term = new Term( $1->term, $3->factorWithAug, Term::RightStartType );
  346. };
  347. term:
  348. term TK_ColonGtGt factor_with_label final {
  349. $$->term = new Term( $1->term, $3->factorWithAug, Term::RightFinishType );
  350. };
  351. term:
  352. term TK_LtColon factor_with_label final {
  353. $$->term = new Term( $1->term,
  354. $3->factorWithAug, Term::LeftType );
  355. };
  356. term:
  357. factor_with_label final {
  358. $$->term = new Term( $1->factorWithAug );
  359. };
  360. nonterm factor_with_label
  361. {
  362. FactorWithAug *factorWithAug;
  363. };
  364. factor_with_label:
  365. TK_Word ':' factor_with_label final {
  366. /* Add the label to the list and pass the factor up. */
  367. $3->factorWithAug->labels.prepend( Label($1->loc, $1->data) );
  368. $$->factorWithAug = $3->factorWithAug;
  369. };
  370. factor_with_label:
  371. factor_with_ep final {
  372. $$->factorWithAug = $1->factorWithAug;
  373. };
  374. nonterm factor_with_ep
  375. {
  376. FactorWithAug *factorWithAug;
  377. };
  378. factor_with_ep:
  379. factor_with_ep TK_Arrow local_state_ref final {
  380. /* Add the target to the list and return the factor object. */
  381. $1->factorWithAug->epsilonLinks.append( EpsilonLink( $2->loc, nameRef ) );
  382. $$->factorWithAug = $1->factorWithAug;
  383. };
  384. factor_with_ep:
  385. factor_with_aug final {
  386. $$->factorWithAug = $1->factorWithAug;
  387. };
  388. nonterm factor_with_aug
  389. {
  390. FactorWithAug *factorWithAug;
  391. };
  392. factor_with_aug:
  393. factor_with_aug aug_type_base action_embed final {
  394. /* Append the action to the factorWithAug, record the refernce from
  395. * factorWithAug to the action and pass up the factorWithAug. */
  396. $1->factorWithAug->actions.append(
  397. ParserAction( $2->loc, $2->augType, 0, $3->action ) );
  398. $$->factorWithAug = $1->factorWithAug;
  399. };
  400. factor_with_aug:
  401. factor_with_aug aug_type_base priority_aug final {
  402. /* Append the named priority to the factorWithAug and pass it up. */
  403. $1->factorWithAug->priorityAugs.append(
  404. PriorityAug( $2->augType, pd->curDefPriorKey, $3->priorityNum ) );
  405. $$->factorWithAug = $1->factorWithAug;
  406. };
  407. factor_with_aug:
  408. factor_with_aug aug_type_base '(' priority_name ',' priority_aug ')' final {
  409. /* Append the priority using a default name. */
  410. $1->factorWithAug->priorityAugs.append(
  411. PriorityAug( $2->augType, $4->priorityName, $6->priorityNum ) );
  412. $$->factorWithAug = $1->factorWithAug;
  413. };
  414. factor_with_aug:
  415. factor_with_aug aug_type_cond action_embed final {
  416. $1->factorWithAug->conditions.append( ConditionTest( $2->loc,
  417. $2->augType, $3->action, true ) );
  418. $$->factorWithAug = $1->factorWithAug;
  419. };
  420. factor_with_aug:
  421. factor_with_aug aug_type_cond '!' action_embed final {
  422. $1->factorWithAug->conditions.append( ConditionTest( $2->loc,
  423. $2->augType, $4->action, false ) );
  424. $$->factorWithAug = $1->factorWithAug;
  425. };
  426. factor_with_aug:
  427. factor_with_aug aug_type_to_state action_embed final {
  428. /* Append the action, pass it up. */
  429. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  430. $2->augType, 0, $3->action ) );
  431. $$->factorWithAug = $1->factorWithAug;
  432. };
  433. factor_with_aug:
  434. factor_with_aug aug_type_from_state action_embed final {
  435. /* Append the action, pass it up. */
  436. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  437. $2->augType, 0, $3->action ) );
  438. $$->factorWithAug = $1->factorWithAug;
  439. };
  440. factor_with_aug:
  441. factor_with_aug aug_type_eof action_embed final {
  442. /* Append the action, pass it up. */
  443. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  444. $2->augType, 0, $3->action ) );
  445. $$->factorWithAug = $1->factorWithAug;
  446. };
  447. factor_with_aug:
  448. factor_with_aug aug_type_gbl_error action_embed final {
  449. /* Append the action to the factorWithAug, record the refernce from
  450. * factorWithAug to the action and pass up the factorWithAug. */
  451. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  452. $2->augType, pd->curDefLocalErrKey, $3->action ) );
  453. $$->factorWithAug = $1->factorWithAug;
  454. };
  455. factor_with_aug:
  456. factor_with_aug aug_type_local_error action_embed final {
  457. /* Append the action to the factorWithAug, record the refernce from
  458. * factorWithAug to the action and pass up the factorWithAug. */
  459. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  460. $2->augType, pd->curDefLocalErrKey, $3->action ) );
  461. $$->factorWithAug = $1->factorWithAug;
  462. };
  463. factor_with_aug:
  464. factor_with_aug aug_type_local_error '(' local_err_name ',' action_embed ')' final {
  465. /* Append the action to the factorWithAug, record the refernce from
  466. * factorWithAug to the action and pass up the factorWithAug. */
  467. $1->factorWithAug->actions.append( ParserAction( $2->loc,
  468. $2->augType, $4->error_name, $6->action ) );
  469. $$->factorWithAug = $1->factorWithAug;
  470. };
  471. factor_with_aug:
  472. factor_with_rep final {
  473. $$->factorWithAug = new FactorWithAug( $1->factorWithRep );
  474. };
  475. type aug_type
  476. {
  477. InputLoc loc;
  478. AugType augType;
  479. };
  480. # Classes of transtions on which to embed actions or change priorities.
  481. nonterm aug_type_base uses aug_type;
  482. aug_type_base: '@' final { $$->loc = $1->loc; $$->augType = at_finish; };
  483. aug_type_base: '%' final { $$->loc = $1->loc; $$->augType = at_leave; };
  484. aug_type_base: '$' final { $$->loc = $1->loc; $$->augType = at_all; };
  485. aug_type_base: '>' final { $$->loc = $1->loc; $$->augType = at_start; };
  486. # Embedding conditions.
  487. nonterm aug_type_cond uses aug_type;
  488. aug_type_cond: TK_StartCond final { $$->loc = $1->loc; $$->augType = at_start; };
  489. aug_type_cond: '>' KW_When final { $$->loc = $1->loc; $$->augType = at_start; };
  490. aug_type_cond: TK_AllCond final { $$->loc = $1->loc; $$->augType = at_all; };
  491. aug_type_cond: '$' KW_When final { $$->loc = $1->loc; $$->augType = at_all; };
  492. aug_type_cond: TK_LeavingCond final { $$->loc = $1->loc; $$->augType = at_leave; };
  493. aug_type_cond: '%' KW_When final { $$->loc = $1->loc; $$->augType = at_leave; };
  494. aug_type_cond: KW_When final { $$->loc = $1->loc; $$->augType = at_all; };
  495. aug_type_cond: KW_InWhen final { $$->loc = $1->loc; $$->augType = at_start; };
  496. aug_type_cond: KW_OutWhen final { $$->loc = $1->loc; $$->augType = at_leave; };
  497. #
  498. # To state actions.
  499. #
  500. nonterm aug_type_to_state uses aug_type;
  501. aug_type_to_state: TK_StartToState
  502. final { $$->loc = $1->loc; $$->augType = at_start_to_state; };
  503. aug_type_to_state: '>' KW_To
  504. final { $$->loc = $1->loc; $$->augType = at_start_to_state; };
  505. aug_type_to_state: TK_NotStartToState
  506. final { $$->loc = $1->loc; $$->augType = at_not_start_to_state; };
  507. aug_type_to_state: '<' KW_To
  508. final { $$->loc = $1->loc; $$->augType = at_not_start_to_state; };
  509. aug_type_to_state: TK_AllToState
  510. final { $$->loc = $1->loc; $$->augType = at_all_to_state; };
  511. aug_type_to_state: '$' KW_To
  512. final { $$->loc = $1->loc; $$->augType = at_all_to_state; };
  513. aug_type_to_state: TK_FinalToState
  514. final { $$->loc = $1->loc; $$->augType = at_final_to_state; };
  515. aug_type_to_state: '%' KW_To
  516. final { $$->loc = $1->loc; $$->augType = at_final_to_state; };
  517. aug_type_to_state: TK_NotFinalToState
  518. final { $$->loc = $1->loc; $$->augType = at_not_final_to_state; };
  519. aug_type_to_state: '@' KW_To
  520. final { $$->loc = $1->loc; $$->augType = at_not_final_to_state; };
  521. aug_type_to_state: TK_MiddleToState
  522. final { $$->loc = $1->loc; $$->augType = at_middle_to_state; };
  523. aug_type_to_state: TK_Middle KW_To
  524. final { $$->loc = $1->loc; $$->augType = at_middle_to_state; };
  525. #
  526. # From state actions.
  527. #
  528. nonterm aug_type_from_state uses aug_type;
  529. aug_type_from_state: TK_StartFromState
  530. final { $$->loc = $1->loc; $$->augType = at_start_from_state; };
  531. aug_type_from_state: '>' KW_From
  532. final { $$->loc = $1->loc; $$->augType = at_start_from_state; };
  533. aug_type_from_state: TK_NotStartFromState
  534. final { $$->loc = $1->loc; $$->augType = at_not_start_from_state; };
  535. aug_type_from_state: '<' KW_From
  536. final { $$->loc = $1->loc; $$->augType = at_not_start_from_state; };
  537. aug_type_from_state: TK_AllFromState
  538. final { $$->loc = $1->loc; $$->augType = at_all_from_state; };
  539. aug_type_from_state: '$' KW_From
  540. final { $$->loc = $1->loc; $$->augType = at_all_from_state; };
  541. aug_type_from_state: TK_FinalFromState
  542. final { $$->loc = $1->loc; $$->augType = at_final_from_state; };
  543. aug_type_from_state: '%' KW_From
  544. final { $$->loc = $1->loc; $$->augType = at_final_from_state; };
  545. aug_type_from_state: TK_NotFinalFromState
  546. final { $$->loc = $1->loc; $$->augType = at_not_final_from_state; };
  547. aug_type_from_state: '@' KW_From
  548. final { $$->loc = $1->loc; $$->augType = at_not_final_from_state; };
  549. aug_type_from_state: TK_MiddleFromState
  550. final { $$->loc = $1->loc; $$->augType = at_middle_from_state; };
  551. aug_type_from_state: TK_Middle KW_From
  552. final { $$->loc = $1->loc; $$->augType = at_middle_from_state; };
  553. #
  554. # Eof state actions.
  555. #
  556. nonterm aug_type_eof uses aug_type;
  557. aug_type_eof: TK_StartEOF
  558. final { $$->loc = $1->loc; $$->augType = at_start_eof; };
  559. aug_type_eof: '>' KW_Eof
  560. final { $$->loc = $1->loc; $$->augType = at_start_eof; };
  561. aug_type_eof: TK_NotStartEOF
  562. final { $$->loc = $1->loc; $$->augType = at_not_start_eof; };
  563. aug_type_eof: '<' KW_Eof
  564. final { $$->loc = $1->loc; $$->augType = at_not_start_eof; };
  565. aug_type_eof: TK_AllEOF
  566. final { $$->loc = $1->loc; $$->augType = at_all_eof; };
  567. aug_type_eof: '$' KW_Eof
  568. final { $$->loc = $1->loc; $$->augType = at_all_eof; };
  569. aug_type_eof: TK_FinalEOF
  570. final { $$->loc = $1->loc; $$->augType = at_final_eof; };
  571. aug_type_eof: '%' KW_Eof
  572. final { $$->loc = $1->loc; $$->augType = at_final_eof; };
  573. aug_type_eof: TK_NotFinalEOF
  574. final { $$->loc = $1->loc; $$->augType = at_not_final_eof; };
  575. aug_type_eof: '@' KW_Eof
  576. final { $$->loc = $1->loc; $$->augType = at_not_final_eof; };
  577. aug_type_eof: TK_MiddleEOF
  578. final { $$->loc = $1->loc; $$->augType = at_middle_eof; };
  579. aug_type_eof: TK_Middle KW_Eof
  580. final { $$->loc = $1->loc; $$->augType = at_middle_eof; };
  581. #
  582. # Global error actions.
  583. #
  584. nonterm aug_type_gbl_error uses aug_type;
  585. aug_type_gbl_error: TK_StartGblError
  586. final { $$->loc = $1->loc; $$->augType = at_start_gbl_error; };
  587. aug_type_gbl_error: '>' KW_Err
  588. final { $$->loc = $1->loc; $$->augType = at_start_gbl_error; };
  589. aug_type_gbl_error: TK_NotStartGblError
  590. final { $$->loc = $1->loc; $$->augType = at_not_start_gbl_error; };
  591. aug_type_gbl_error: '<' KW_Err
  592. final { $$->loc = $1->loc; $$->augType = at_not_start_gbl_error; };
  593. aug_type_gbl_error: TK_AllGblError
  594. final { $$->loc = $1->loc; $$->augType = at_all_gbl_error; };
  595. aug_type_gbl_error: '$' KW_Err
  596. final { $$->loc = $1->loc; $$->augType = at_all_gbl_error; };
  597. aug_type_gbl_error: TK_FinalGblError
  598. final { $$->loc = $1->loc; $$->augType = at_final_gbl_error; };
  599. aug_type_gbl_error: '%' KW_Err
  600. final { $$->loc = $1->loc; $$->augType = at_final_gbl_error; };
  601. aug_type_gbl_error: TK_NotFinalGblError
  602. final { $$->loc = $1->loc; $$->augType = at_not_final_gbl_error; };
  603. aug_type_gbl_error: '@' KW_Err
  604. final { $$->loc = $1->loc; $$->augType = at_not_final_gbl_error; };
  605. aug_type_gbl_error: TK_MiddleGblError
  606. final { $$->loc = $1->loc; $$->augType = at_middle_gbl_error; };
  607. aug_type_gbl_error: TK_Middle KW_Err
  608. final { $$->loc = $1->loc; $$->augType = at_middle_gbl_error; };
  609. #
  610. # Local error actions.
  611. #
  612. nonterm aug_type_local_error uses aug_type;
  613. aug_type_local_error: TK_StartLocalError
  614. final { $$->loc = $1->loc; $$->augType = at_start_local_error; };
  615. aug_type_local_error: '>' KW_Lerr
  616. final { $$->loc = $1->loc; $$->augType = at_start_local_error; };
  617. aug_type_local_error: TK_NotStartLocalError
  618. final { $$->loc = $1->loc; $$->augType = at_not_start_local_error; };
  619. aug_type_local_error: '<' KW_Lerr
  620. final { $$->loc = $1->loc; $$->augType = at_not_start_local_error; };
  621. aug_type_local_error: TK_AllLocalError
  622. final { $$->loc = $1->loc; $$->augType = at_all_local_error; };
  623. aug_type_local_error: '$' KW_Lerr
  624. final { $$->loc = $1->loc; $$->augType = at_all_local_error; };
  625. aug_type_local_error: TK_FinalLocalError
  626. final { $$->loc = $1->loc; $$->augType = at_final_local_error; };
  627. aug_type_local_error: '%' KW_Lerr
  628. final { $$->loc = $1->loc; $$->augType = at_final_local_error; };
  629. aug_type_local_error: TK_NotFinalLocalError
  630. final { $$->loc = $1->loc; $$->augType = at_not_final_local_error; };
  631. aug_type_local_error: '@' KW_Lerr
  632. final { $$->loc = $1->loc; $$->augType = at_not_final_local_error; };
  633. aug_type_local_error: TK_MiddleLocalError
  634. final { $$->loc = $1->loc; $$->augType = at_middle_local_error; };
  635. aug_type_local_error: TK_Middle KW_Lerr
  636. final { $$->loc = $1->loc; $$->augType = at_middle_local_error; };
  637. type action_ref
  638. {
  639. Action *action;
  640. };
  641. # Different ways to embed actions. A TK_Word is reference to an action given by
  642. # the user as a statement in the fsm specification. An action can also be
  643. # specified immediately.
  644. nonterm action_embed uses action_ref;
  645. action_embed: action_embed_word final { $$->action = $1->action; };
  646. action_embed: '(' action_embed_word ')' final { $$->action = $2->action; };
  647. action_embed: action_embed_block final { $$->action = $1->action; };
  648. nonterm action_embed_word uses action_ref;
  649. action_embed_word:
  650. TK_Word final {
  651. /* Set the name in the actionDict. */
  652. Action *action = pd->actionDict.find( $1->data );
  653. if ( action != 0 ) {
  654. /* Pass up the action element */
  655. $$->action = action;
  656. }
  657. else {
  658. /* Will recover by returning null as the action. */
  659. error($1->loc) << "action lookup of \"" << $1->data << "\" failed" << endl;
  660. $$->action = 0;
  661. }
  662. };
  663. nonterm action_embed_block uses action_ref;
  664. action_embed_block:
  665. '{' inline_block '}' final {
  666. /* Create the action, add it to the list and pass up. */
  667. Action *newAction = new Action( $1->loc, 0, $2->inlineList, pd->nextCondId++ );
  668. pd->actionList.append( newAction );
  669. $$->action = newAction;
  670. };
  671. nonterm priority_name
  672. {
  673. int priorityName;
  674. };
  675. # A specified priority name. Looks up the name in the current priority
  676. # dictionary.
  677. priority_name:
  678. TK_Word final {
  679. // Lookup/create the priority key.
  680. PriorDictEl *priorDictEl;
  681. if ( pd->priorDict.insert( $1->data, pd->nextPriorKey, &priorDictEl ) )
  682. pd->nextPriorKey += 1;
  683. // Use the inserted/found priority key.
  684. $$->priorityName = priorDictEl->value;
  685. };
  686. nonterm priority_aug
  687. {
  688. int priorityNum;
  689. };
  690. # Priority change specs.
  691. priority_aug:
  692. priority_aug_num final {
  693. // Convert the priority number to a long. Check for overflow.
  694. errno = 0;
  695. //cerr << "PRIOR AUG: " << $1->token.data << endl;
  696. long aug = strtol( $1->token.data, 0, 10 );
  697. if ( errno == ERANGE && aug == LONG_MAX ) {
  698. /* Priority number too large. Recover by setting the priority to 0. */
  699. error($1->token.loc) << "priority number " << $1->token.data <<
  700. " overflows" << endl;
  701. $$->priorityNum = 0;
  702. }
  703. else if ( errno == ERANGE && aug == LONG_MIN ) {
  704. /* Priority number too large in the neg. Recover by using 0. */
  705. error($1->token.loc) << "priority number " << $1->token.data <<
  706. " underflows" << endl;
  707. $$->priorityNum = 0;
  708. }
  709. else {
  710. /* No overflow or underflow. */
  711. $$->priorityNum = aug;
  712. }
  713. };
  714. nonterm priority_aug_num uses token_type;
  715. priority_aug_num:
  716. TK_UInt final {
  717. $$->token = *$1;
  718. };
  719. priority_aug_num:
  720. '+' TK_UInt final {
  721. $$->token.set( "+", 1 );
  722. $$->token.loc = $1->loc;
  723. $$->token.append( *$2 );
  724. };
  725. priority_aug_num:
  726. '-' TK_UInt final {
  727. $$->token.set( "-", 1 );
  728. $$->token.loc = $1->loc;
  729. $$->token.append( *$2 );
  730. };
  731. nonterm local_err_name
  732. {
  733. int error_name;
  734. };
  735. local_err_name:
  736. TK_Word final {
  737. /* Lookup/create the priority key. */
  738. LocalErrDictEl *localErrDictEl;
  739. if ( pd->localErrDict.insert( $1->data, pd->nextLocalErrKey, &localErrDictEl ) )
  740. pd->nextLocalErrKey += 1;
  741. /* Use the inserted/found priority key. */
  742. $$->error_name = localErrDictEl->value;
  743. };
  744. # The fourth level of precedence. These are the trailing unary operators that
  745. # allow for repetition.
  746. nonterm factor_with_rep
  747. {
  748. FactorWithRep *factorWithRep;
  749. };
  750. factor_with_rep:
  751. factor_with_rep '*' final {
  752. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  753. 0, 0, FactorWithRep::StarType );
  754. };
  755. factor_with_rep:
  756. factor_with_rep TK_StarStar final {
  757. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  758. 0, 0, FactorWithRep::StarStarType );
  759. };
  760. factor_with_rep:
  761. factor_with_rep '?' final {
  762. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  763. 0, 0, FactorWithRep::OptionalType );
  764. };
  765. factor_with_rep:
  766. factor_with_rep '+' final {
  767. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  768. 0, 0, FactorWithRep::PlusType );
  769. };
  770. factor_with_rep:
  771. factor_with_rep '{' factor_rep_num '}' final {
  772. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  773. $3->rep, 0, FactorWithRep::ExactType );
  774. };
  775. factor_with_rep:
  776. factor_with_rep '{' ',' factor_rep_num '}' final {
  777. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  778. 0, $4->rep, FactorWithRep::MaxType );
  779. };
  780. factor_with_rep:
  781. factor_with_rep '{' factor_rep_num ',' '}' final {
  782. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  783. $3->rep, 0, FactorWithRep::MinType );
  784. };
  785. factor_with_rep:
  786. factor_with_rep '{' factor_rep_num ',' factor_rep_num '}' final {
  787. $$->factorWithRep = new FactorWithRep( $2->loc, $1->factorWithRep,
  788. $3->rep, $5->rep, FactorWithRep::RangeType );
  789. };
  790. factor_with_rep:
  791. factor_with_neg final {
  792. $$->factorWithRep = new FactorWithRep( $1->factorWithNeg );
  793. };
  794. nonterm factor_rep_num
  795. {
  796. int rep;
  797. };
  798. factor_rep_num:
  799. TK_UInt final {
  800. // Convert the priority number to a long. Check for overflow.
  801. errno = 0;
  802. long rep = strtol( $1->data, 0, 10 );
  803. if ( errno == ERANGE && rep == LONG_MAX ) {
  804. // Repetition too large. Recover by returing repetition 1. */
  805. error($1->loc) << "repetition number " << $1->data << " overflows" << endl;
  806. $$->rep = 1;
  807. }
  808. else {
  809. // Cannot be negative, so no overflow.
  810. $$->rep = rep;
  811. }
  812. };
  813. #
  814. # The fifth level up in precedence. Negation.
  815. #
  816. nonterm factor_with_neg
  817. {
  818. FactorWithNeg *factorWithNeg;
  819. };
  820. factor_with_neg:
  821. '!' factor_with_neg final {
  822. $$->factorWithNeg = new FactorWithNeg( $1->loc,
  823. $2->factorWithNeg, FactorWithNeg::NegateType );
  824. };
  825. factor_with_neg:
  826. '^' factor_with_neg final {
  827. $$->factorWithNeg = new FactorWithNeg( $1->loc,
  828. $2->factorWithNeg, FactorWithNeg::CharNegateType );
  829. };
  830. factor_with_neg:
  831. factor final {
  832. $$->factorWithNeg = new FactorWithNeg( $1->factor );
  833. };
  834. nonterm factor
  835. {
  836. Factor *factor;
  837. };
  838. factor:
  839. TK_Literal final {
  840. /* Create a new factor node going to a concat literal. */
  841. $$->factor = new Factor( new Literal( *$1, Literal::LitString ) );
  842. };
  843. factor:
  844. alphabet_num final {
  845. /* Create a new factor node going to a literal number. */
  846. $$->factor = new Factor( new Literal( $1->token, Literal::Number ) );
  847. };
  848. factor:
  849. TK_Word final {
  850. /* Find the named graph. */
  851. GraphDictEl *gdNode = pd->graphDict.find( $1->data );
  852. if ( gdNode == 0 ) {
  853. /* Recover by returning null as the factor node. */
  854. error($1->loc) << "graph lookup of \"" << $1->data << "\" failed" << endl;
  855. $$->factor = 0;
  856. }
  857. else if ( gdNode->isInstance ) {
  858. /* Recover by retuning null as the factor node. */
  859. error($1->loc) << "references to graph instantiations not allowed "
  860. "in expressions" << endl;
  861. $$->factor = 0;
  862. }
  863. else {
  864. /* Create a factor node that is a lookup of an expression. */
  865. $$->factor = new Factor( $1->loc, gdNode->value );
  866. }
  867. };
  868. factor:
  869. RE_SqOpen regular_expr_or_data RE_SqClose final {
  870. /* Create a new factor node going to an OR expression. */
  871. $$->factor = new Factor( new ReItem( $1->loc, $2->reOrBlock, ReItem::OrBlock ) );
  872. };
  873. factor:
  874. RE_SqOpenNeg regular_expr_or_data RE_SqClose final {
  875. /* Create a new factor node going to a negated OR expression. */
  876. $$->factor = new Factor( new ReItem( $1->loc, $2->reOrBlock, ReItem::NegOrBlock ) );
  877. };
  878. factor:
  879. RE_Slash regular_expr RE_Slash final {
  880. if ( $3->length > 1 ) {
  881. for ( char *p = $3->data; *p != 0; p++ ) {
  882. if ( *p == 'i' )
  883. $2->regExpr->caseInsensitive = true;
  884. }
  885. }
  886. /* Create a new factor node going to a regular exp. */
  887. $$->factor = new Factor( $2->regExpr );
  888. };
  889. factor:
  890. range_lit TK_DotDot range_lit final {
  891. /* Create a new factor node going to a range. */
  892. $$->factor = new Factor( new Range( $1->literal, $3->literal ) );
  893. };
  894. factor:
  895. '(' join ')' final {
  896. /* Create a new factor going to a parenthesized join. */
  897. $$->factor = new Factor( $2->join );
  898. $2->join->loc = $1->loc;
  899. };
  900. nonterm range_lit
  901. {
  902. Literal *literal;
  903. };
  904. # Literals which can be the end points of ranges.
  905. range_lit:
  906. TK_Literal final {
  907. /* Range literas must have only one char. We restrict this in the parse tree. */
  908. $$->literal = new Literal( *$1, Literal::LitString );
  909. };
  910. range_lit:
  911. alphabet_num final {
  912. /* Create a new literal number. */
  913. $$->literal = new Literal( $1->token, Literal::Number );
  914. };
  915. nonterm alphabet_num uses token_type;
  916. # Any form of a number that can be used as a basic machine. */
  917. alphabet_num:
  918. TK_UInt final {
  919. $$->token = *$1;
  920. };
  921. alphabet_num:
  922. '-' TK_UInt final {
  923. $$->token.set( "-", 1 );
  924. $$->token.loc = $1->loc;
  925. $$->token.append( *$2 );
  926. };
  927. alphabet_num:
  928. TK_Hex final {
  929. $$->token = *$1;
  930. };
  931. #
  932. # Regular Expressions.
  933. #
  934. nonterm regular_expr
  935. {
  936. RegExpr *regExpr;
  937. };
  938. # Parser for regular expression fsms. Any number of expression items which
  939. # generally gives a machine one character long or one character long stared.
  940. regular_expr:
  941. regular_expr regular_expr_item final {
  942. /* An optimization to lessen the tree size. If a non-starred char is
  943. * directly under the left side on the right and the right side is
  944. * another non-starred char then paste them together and return the
  945. * left side. Otherwise just put the two under a new reg exp node. */
  946. if ( $2->reItem->type == ReItem::Data && !$2->reItem->star &&
  947. $1->regExpr->type == RegExpr::RecurseItem &&
  948. $1->regExpr->item->type == ReItem::Data && !$1->regExpr->item->star )
  949. {
  950. /* Append the right side to the right side of the left and toss the
  951. * right side. */
  952. $1->regExpr->item->token.append( $2->reItem->token );
  953. delete $2->reItem;
  954. $$->regExpr = $1->regExpr;
  955. }
  956. else {
  957. $$->regExpr = new RegExpr( $1->regExpr, $2->reItem );
  958. }
  959. };
  960. regular_expr:
  961. final {
  962. /* Can't optimize the tree. */
  963. $$->regExpr = new RegExpr();
  964. };
  965. nonterm regular_expr_item
  966. {
  967. ReItem *reItem;
  968. };
  969. # RegularExprItems can be a character spec with an optional staring of the char.
  970. regular_expr_item:
  971. regular_expr_char RE_Star final {
  972. $1->reItem->star = true;
  973. $$->reItem = $1->reItem;
  974. };
  975. regular_expr_item:
  976. regular_expr_char final {
  977. $$->reItem = $1->reItem;
  978. };
  979. nonterm regular_expr_char
  980. {
  981. ReItem *reItem;
  982. };
  983. # A character spec can be a set of characters inside of square parenthesis, a
  984. # dot specifying any character or some explicitly stated character.
  985. regular_expr_char:
  986. RE_SqOpen regular_expr_or_data RE_SqClose final {
  987. $$->reItem = new ReItem( $1->loc, $2->reOrBlock, ReItem::OrBlock );
  988. };
  989. regular_expr_char:
  990. RE_SqOpenNeg regular_expr_or_data RE_SqClose final {
  991. $$->reItem = new ReItem( $1->loc, $2->reOrBlock, ReItem::NegOrBlock );
  992. };
  993. regular_expr_char:
  994. RE_Dot final {
  995. $$->reItem = new ReItem( $1->loc, ReItem::Dot );
  996. };
  997. regular_expr_char:
  998. RE_Char final {
  999. $$->reItem = new ReItem( $1->loc, *$1 );
  1000. };
  1001. # The data inside of a [] expression in a regular expression. Accepts any
  1002. # number of characters or ranges. */
  1003. nonterm regular_expr_or_data
  1004. {
  1005. ReOrBlock *reOrBlock;
  1006. };
  1007. regular_expr_or_data:
  1008. regular_expr_or_data regular_expr_or_char final {
  1009. /* An optimization to lessen the tree size. If an or char is directly
  1010. * under the left side on the right and the right side is another or
  1011. * char then paste them together and return the left side. Otherwise
  1012. * just put the two under a new or data node. */
  1013. if ( $2->reOrItem->type == ReOrItem::Data &&
  1014. $1->reOrBlock->type == ReOrBlock::RecurseItem &&
  1015. $1->reOrBlock->item->type == ReOrItem::Data )
  1016. {
  1017. /* Append the right side to right side of the left and toss the
  1018. * right side. */
  1019. $1->reOrBlock->item->token.append( $2->reOrItem->token );
  1020. delete $2->reOrItem;
  1021. $$->reOrBlock = $1->reOrBlock;
  1022. }
  1023. else {
  1024. /* Can't optimize, put the left and right under a new node. */
  1025. $$->reOrBlock = new ReOrBlock( $1->reOrBlock, $2->reOrItem );
  1026. }
  1027. };
  1028. regular_expr_or_data:
  1029. final {
  1030. $$->reOrBlock = new ReOrBlock();
  1031. };
  1032. # A single character inside of an or expression. Can either be a character or a
  1033. # set of characters.
  1034. nonterm regular_expr_or_char
  1035. {
  1036. ReOrItem *reOrItem;
  1037. };
  1038. regular_expr_or_char:
  1039. RE_Char final {
  1040. $$->reOrItem = new ReOrItem( $1->loc, *$1 );
  1041. };
  1042. regular_expr_or_char:
  1043. RE_Char RE_Dash RE_Char final {
  1044. $$->reOrItem = new ReOrItem( $2->loc, $1->data[0], $3->data[0] );
  1045. };
  1046. #
  1047. # Inline Lists for inline host code.
  1048. #
  1049. type inline_list
  1050. {
  1051. InlineList *inlineList;
  1052. };
  1053. nonterm inline_block uses inline_list;
  1054. inline_block:
  1055. inline_block inline_block_item
  1056. final {
  1057. /* Append the item to the list, return the list. */
  1058. $$->inlineList = $1->inlineList;
  1059. $$->inlineList->append( $2->inlineItem );
  1060. };
  1061. inline_block:
  1062. final {
  1063. /* Start with empty list. */
  1064. $$->inlineList = new InlineList;
  1065. };
  1066. type inline_item
  1067. {
  1068. InlineItem *inlineItem;
  1069. };
  1070. nonterm inline_block_item uses inline_item;
  1071. nonterm inline_block_interpret uses inline_item;
  1072. inline_block_item:
  1073. inline_expr_any
  1074. final {
  1075. $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text );
  1076. };
  1077. inline_block_item:
  1078. inline_block_symbol
  1079. final {
  1080. $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text );
  1081. };
  1082. inline_block_item:
  1083. inline_block_interpret
  1084. final {
  1085. /* Pass the inline item up. */
  1086. $$->inlineItem = $1->inlineItem;
  1087. };
  1088. nonterm inline_block_symbol uses token_type;
  1089. inline_block_symbol: ',' final { $$->token = *$1; };
  1090. inline_block_symbol: ';' final { $$->token = *$1; };
  1091. inline_block_symbol: '(' final { $$->token = *$1; };
  1092. inline_block_symbol: ')' final { $$->token = *$1; };
  1093. inline_block_symbol: '*' final { $$->token = *$1; };
  1094. inline_block_symbol: TK_NameSep final { $$->token = *$1; };
  1095. # Interpreted statements in a struct block. */
  1096. inline_block_interpret:
  1097. inline_expr_interpret final {
  1098. /* Pass up interpreted items of inline expressions. */
  1099. $$->inlineItem = $1->inlineItem;
  1100. };
  1101. inline_block_interpret:
  1102. KW_Hold ';' final {
  1103. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Hold );
  1104. };
  1105. inline_block_interpret:
  1106. KW_Exec inline_expr ';' final {
  1107. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Exec );
  1108. $$->inlineItem->children = $2->inlineList;
  1109. };
  1110. inline_block_interpret:
  1111. KW_Goto state_ref ';' final {
  1112. $$->inlineItem = new InlineItem( $1->loc,
  1113. new NameRef(nameRef), InlineItem::Goto );
  1114. };
  1115. inline_block_interpret:
  1116. KW_Goto '*' inline_expr ';' final {
  1117. $$->inlineItem = new InlineItem( $1->loc, InlineItem::GotoExpr );
  1118. $$->inlineItem->children = $3->inlineList;
  1119. };
  1120. inline_block_interpret:
  1121. KW_Next state_ref ';' final {
  1122. $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Next );
  1123. };
  1124. inline_block_interpret:
  1125. KW_Next '*' inline_expr ';' final {
  1126. $$->inlineItem = new InlineItem( $1->loc, InlineItem::NextExpr );
  1127. $$->inlineItem->children = $3->inlineList;
  1128. };
  1129. inline_block_interpret:
  1130. KW_Call state_ref ';' final {
  1131. $$->inlineItem = new InlineItem( $1->loc, new NameRef(nameRef), InlineItem::Call );
  1132. };
  1133. inline_block_interpret:
  1134. KW_Call '*' inline_expr ';' final {
  1135. $$->inlineItem = new InlineItem( $1->loc, InlineItem::CallExpr );
  1136. $$->inlineItem->children = $3->inlineList;
  1137. };
  1138. inline_block_interpret:
  1139. KW_Ret ';' final {
  1140. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Ret );
  1141. };
  1142. inline_block_interpret:
  1143. KW_Break ';' final {
  1144. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Break );
  1145. };
  1146. nonterm inline_expr uses inline_list;
  1147. inline_expr:
  1148. inline_expr inline_expr_item
  1149. final {
  1150. $$->inlineList = $1->inlineList;
  1151. $$->inlineList->append( $2->inlineItem );
  1152. };
  1153. inline_expr:
  1154. final {
  1155. /* Init the list used for this expr. */
  1156. $$->inlineList = new InlineList;
  1157. };
  1158. nonterm inline_expr_item uses inline_item;
  1159. inline_expr_item:
  1160. inline_expr_any
  1161. final {
  1162. /* Return a text segment. */
  1163. $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text );
  1164. };
  1165. inline_expr_item:
  1166. inline_expr_symbol
  1167. final {
  1168. /* Return a text segment, must heap alloc the text. */
  1169. $$->inlineItem = new InlineItem( $1->token.loc, $1->token.data, InlineItem::Text );
  1170. };
  1171. inline_expr_item:
  1172. inline_expr_interpret
  1173. final{
  1174. /* Pass the inline item up. */
  1175. $$->inlineItem = $1->inlineItem;
  1176. };
  1177. nonterm inline_expr_any uses token_type;
  1178. inline_expr_any: IL_WhiteSpace try { $$->token = *$1; };
  1179. inline_expr_any: IL_Comment try { $$->token = *$1; };
  1180. inline_expr_any: IL_Literal try { $$->token = *$1; };
  1181. inline_expr_any: IL_Symbol try { $$->token = *$1; };
  1182. inline_expr_any: TK_UInt try { $$->token = *$1; };
  1183. inline_expr_any: TK_Hex try { $$->token = *$1; };
  1184. inline_expr_any: TK_Word try { $$->token = *$1; };
  1185. # Anything in a ExecValExpr that is not dynamically allocated. This includes
  1186. # all special symbols caught in inline code except the semi.
  1187. nonterm inline_expr_symbol uses token_type;
  1188. inline_expr_symbol: ',' try { $$->token = *$1; };
  1189. inline_expr_symbol: '(' try { $$->token = *$1; };
  1190. inline_expr_symbol: ')' try { $$->token = *$1; };
  1191. inline_expr_symbol: '*' try { $$->token = *$1; };
  1192. inline_expr_symbol: TK_NameSep try { $$->token = *$1; };
  1193. nonterm inline_expr_interpret uses inline_item;
  1194. inline_expr_interpret:
  1195. KW_PChar
  1196. final {
  1197. $$->inlineItem = new InlineItem( $1->loc, InlineItem::PChar );
  1198. };
  1199. inline_expr_interpret:
  1200. KW_Char
  1201. final {
  1202. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Char );
  1203. };
  1204. inline_expr_interpret:
  1205. KW_CurState
  1206. final {
  1207. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Curs );
  1208. };
  1209. inline_expr_interpret:
  1210. KW_TargState
  1211. final {
  1212. $$->inlineItem = new InlineItem( $1->loc, InlineItem::Targs );
  1213. };
  1214. inline_expr_interpret:
  1215. KW_Entry '(' state_ref ')'
  1216. final {
  1217. $$->inlineItem = new InlineItem( $1->loc,
  1218. new NameRef(nameRef), InlineItem::Entry );
  1219. };
  1220. # A local state reference. Cannot have :: prefix.
  1221. local_state_ref:
  1222. no_name_sep state_ref_names;
  1223. # Clear the name ref structure.
  1224. no_name_sep:
  1225. final {
  1226. nameRef.empty();
  1227. };
  1228. # A qualified state reference.
  1229. state_ref: opt_name_sep state_ref_names;
  1230. # Optional leading name separator.
  1231. opt_name_sep:
  1232. TK_NameSep
  1233. final {
  1234. /* Insert an initial null pointer val to indicate the existence of the
  1235. * initial name seperator. */
  1236. nameRef.setAs( 0 );
  1237. };
  1238. opt_name_sep:
  1239. final {
  1240. nameRef.empty();
  1241. };
  1242. # List of names separated by ::
  1243. state_ref_names:
  1244. state_ref_names TK_NameSep TK_Word
  1245. final {
  1246. nameRef.append( $3->data );
  1247. };
  1248. state_ref_names:
  1249. TK_Word
  1250. final {
  1251. nameRef.append( $1->data );
  1252. };
  1253. }%%
  1254. %%{
  1255. write types;
  1256. write data;
  1257. }%%
  1258. void Parser::init()
  1259. {
  1260. %% write init;
  1261. }
  1262. int Parser::parseLangEl( int type, const Token *token )
  1263. {
  1264. %% write exec;
  1265. return errCount == 0 ? 0 : -1;
  1266. }
  1267. void Parser::tryMachineDef( InputLoc &loc, char *name,
  1268. MachineDef *machineDef, bool isInstance )
  1269. {
  1270. GraphDictEl *newEl = pd->graphDict.insert( name );
  1271. if ( newEl != 0 ) {
  1272. /* New element in the dict, all good. */
  1273. newEl->value = new VarDef( name, machineDef );
  1274. newEl->isInstance = isInstance;
  1275. newEl->loc = loc;
  1276. newEl->value->isExport = exportContext[exportContext.length()-1];
  1277. /* It it is an instance, put on the instance list. */
  1278. if ( isInstance )
  1279. pd->instanceList.append( newEl );
  1280. }
  1281. else {
  1282. // Recover by ignoring the duplicate.
  1283. error(loc) << "fsm \"" << name << "\" previously defined" << endl;
  1284. }
  1285. }
  1286. ostream &Parser::parse_error( int tokId, Token &token )
  1287. {
  1288. /* Maintain the error count. */
  1289. gblErrorCount += 1;
  1290. cerr << token.loc << ": ";
  1291. cerr << "at token ";
  1292. if ( tokId < 128 )
  1293. cerr << "\"" << Parser_lelNames[tokId] << "\"";
  1294. else
  1295. cerr << Parser_lelNames[tokId];
  1296. if ( token.data != 0 )
  1297. cerr << " with data \"" << token.data << "\"";
  1298. cerr << ": ";
  1299. return cerr;
  1300. }
  1301. int Parser::token( InputLoc &loc, int tokId, char *tokstart, int toklen )
  1302. {
  1303. Token token;
  1304. token.data = tokstart;
  1305. token.length = toklen;
  1306. token.loc = loc;
  1307. int res = parseLangEl( tokId, &token );
  1308. if ( res < 0 ) {
  1309. parse_error(tokId, token) << "parse error" << endl;
  1310. exit(1);
  1311. }
  1312. return res;
  1313. }