cgg.y 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. %{
  6. #ifndef NORCSID
  7. static char rcsid[]= "$Id$";
  8. #endif
  9. #include "param.h"
  10. #include "varinfo.h"
  11. #include "lookup.h"
  12. #include "set.h"
  13. #include "iocc.h"
  14. #include "instruct.h"
  15. #include "expr.h"
  16. #include "extern.h"
  17. #include <cgg_cg.h>
  18. #include <em_reg.h>
  19. extern int lineno;
  20. int instline,saveline;
  21. int startline;
  22. int npatterns;
  23. int att_type;
  24. int patindex[MAXPATTERNS];
  25. extern set_t l_sets[];
  26. void skipupto(int tok, char *str);
  27. int emhere=0; /* lexical analyzer flag */
  28. int optexact=0; /* Inside "with exact" rule */
  29. int optstack=0; /* Inside with <blah> STACK rule */
  30. int saferulefound=0;
  31. int maxrule=0;
  32. int in_em_repl=0; /* set when in EM replacement part */
  33. struct varinfo *defcost;
  34. int Xstackflag=0; /* set in coercions, moves, and tests. %1 means something
  35. different then.
  36. */
  37. struct varinfo *gen_inst(),*gen_move(),*gen_test(),*gen_preturn(),*gen_tlab();
  38. struct varinfo *gen_label(), *make_erase();
  39. expr_t make_expr(),ident_expr(),subreg_expr(),tokm_expr(),all_expr();
  40. expr_t perc_ident_expr(),sum_expr(),regvar_expr();
  41. set_t ident_to_set(),setproduct(),setsum(),setdiff();
  42. iocc_t subr_iocc(),tokm_iocc(),ident_iocc(),all_iocc(),percident_iocc(), descr_iocc();
  43. extern int narexpr;
  44. extern expr_t arexp[];
  45. int niops;
  46. iocc_t iops[20];
  47. %}
  48. %union {
  49. int yy_int;
  50. char * yy_str;
  51. varinfo * yy_varinfo;
  52. set_t yy_set;
  53. operand *yy_oplist;
  54. expr_t yy_expr;
  55. iocc_t yy_iocc;
  56. }
  57. %token PROPERTIES
  58. %token REGISTERS
  59. %token TOKENS
  60. %token SETS
  61. %token MOVES
  62. %token TESTS
  63. %token STACKINGRULES COERCIONS
  64. %token INSTRUCTIONS
  65. %token TOPELTSIZE FALLTHROUGH LABELDEF
  66. %token PROC CALL EXAMPLE
  67. %token FROM TO
  68. %token TEST MOVE STACK RETURN
  69. %token PATTERNS PAT WITH EXACT KILLS USES REUSING GEN YIELDS LEAVING
  70. %token DEFINED SAMESIGN SFIT UFIT ROM LOWW HIGHW ISROM
  71. %token CMPEQ CMPNE CMPLT CMPGT CMPLE CMPGE OR2 AND2 LSHIFT RSHIFT NOT COMP
  72. %token INREG REGVAR REG_ANY REG_FLOAT REG_LOOP REG_POINTER
  73. %token <yy_int> ADORNACCESS
  74. %token <yy_int> ADORNCC
  75. %token INT
  76. %token ADDR
  77. %token <yy_int> EMMNEM
  78. %token <yy_int> NUMBER
  79. %token <yy_int> DOLLAR PERCENT ALLREG
  80. %token <yy_str> IDENT PERC_IDENT
  81. %token <yy_str> STRING
  82. %token TIMEFACTOR SIZEFACTOR
  83. %token COST
  84. %type <yy_varinfo> prop_list property ident_list ident_list_el
  85. %type <yy_varinfo> att_list att_list_el att_list_el_list att_ident structdecl optcost optformat
  86. %type <yy_varinfo> kills allocates yields leaving
  87. %type <yy_varinfo> generates kill_list kill_list_el uselist uselist_el genlist yieldlist
  88. %type <yy_varinfo> leavelist leavelist_el gen_instruction
  89. %type <yy_varinfo> opt_erase_list erase_list erase_list_el
  90. %type <yy_str> opt_par_string optstring
  91. %type <yy_int> register propno att_list_el_type tokenset_no
  92. %type <yy_int> adornlist optstar optuses optregvar regvartype optregvartype
  93. %type <yy_int> emarg tokarg subreg allreg
  94. %type <yy_expr> expr regvarexpr
  95. %type <yy_iocc> tokeninstance
  96. %type <yy_int> optexpr optexact optstack
  97. %type <yy_set> tokenset
  98. %type <yy_oplist> oplist oplist_el
  99. %left OR2
  100. %left AND2
  101. %left '|'
  102. %left '^'
  103. %left '&'
  104. %left CMPEQ CMPNE
  105. %left CMPLT CMPLE CMPGT CMPGE
  106. %left RSHIFT LSHIFT
  107. %left '+' '-'
  108. %left '*' '/' '%'
  109. %nonassoc NOT COMP UMINUS
  110. %start machtable
  111. %%
  112. /*
  113. * The machine table consists of a number of sections, with their
  114. * own associated parsers.
  115. */
  116. machtable
  117. : constants
  118. properties
  119. registers
  120. tokens
  121. { make_std_sets(); }
  122. sets
  123. instructions
  124. moves
  125. tests
  126. stacks
  127. coercs
  128. code
  129. ;
  130. /*
  131. * Constants are parsed as name=value pairs
  132. */
  133. constants
  134. : constdeflist
  135. ;
  136. constdeflist
  137. : /* empty */
  138. | constdeflist constdef
  139. ;
  140. constdef
  141. : IDENT'=' NUMBER
  142. { n_const($1,$3); free($1); }
  143. | IDENT '=' STRING
  144. { n_sconst($1,$3); free($1); free($3); }
  145. | TIMEFACTOR '=' NUMBER '/' NUMBER
  146. { fc1 = $3; fc2 = $5; }
  147. | SIZEFACTOR '=' NUMBER '/' NUMBER
  148. { fc3 = $3; fc4 = $5; }
  149. | error
  150. ;
  151. /*
  152. * Properties are parsed as a list of names optionally followed by their size
  153. */
  154. properties
  155. : PROPERTIES { make_const(); } prdef_list
  156. ;
  157. prdef_list
  158. : prdef_list_el
  159. | prdef_list optcomma prdef_list_el
  160. ;
  161. prdef_list_el
  162. : IDENT
  163. { n_prop($1,wordsize); free($1); }
  164. | IDENT '(' NUMBER ')'
  165. { n_prop($1,$3); free($1); }
  166. ;
  167. /*
  168. * Registers are rows of reglist:proplist pairs
  169. */
  170. registers
  171. : REGISTERS regdef_list
  172. ;
  173. regdef_list
  174. : regdef_list_el
  175. | regdef_list regdef_list_el
  176. ;
  177. regdef_list_el
  178. : ident_list ':' prop_list optregvar '.'
  179. { regline($1,$3,$4); free((char *) $1); free((char *) $3); }
  180. | error '.'
  181. ;
  182. optregvar
  183. : /* empty */
  184. { $$ = -1; }
  185. | REGVAR
  186. { $$ = reg_any; }
  187. | REGVAR '(' regvartype ')'
  188. { $$ = $3; }
  189. ;
  190. regvartype
  191. : REG_ANY
  192. { $$ = reg_any;}
  193. | REG_FLOAT
  194. { $$ = reg_float;}
  195. | REG_LOOP
  196. { $$ = reg_loop;}
  197. | REG_POINTER
  198. { $$ = reg_pointer;}
  199. ;
  200. ident_list
  201. : ident_list_el
  202. | ident_list optcomma ident_list_el
  203. { $3->vi_next = $1; $$ = $3; }
  204. ;
  205. ident_list_el
  206. : IDENT opt_par_string
  207. { NEW($$,struct varinfo);
  208. $$->vi_next = 0;
  209. $$->vi_int[0] = n_reg($1,$2,0,0,0);
  210. free($1); if($2!=0) free($2);
  211. }
  212. | IDENT opt_par_string '=' register
  213. { NEW($$,struct varinfo);
  214. $$->vi_next = 0;
  215. $$->vi_int[0] = n_reg($1,$2,1,$4,0);
  216. free($1); if($2!=0) free($2);
  217. }
  218. | IDENT opt_par_string '=' register '+' register
  219. { NEW($$,struct varinfo);
  220. $$->vi_next = 0;
  221. $$->vi_int[0] = n_reg($1,$2,2,$4,$6);
  222. free($1); if($2!=0) free($2);
  223. }
  224. ;
  225. opt_par_string
  226. : /* empty */
  227. { $$ = 0; }
  228. | '(' STRING ')'
  229. { $$ = $2; }
  230. ;
  231. register
  232. : IDENT
  233. { register symbol *sy_p;
  234. sy_p = lookup($1,symreg,mustexist);
  235. $$ = sy_p->sy_value.syv_regno;
  236. free($1);
  237. }
  238. ;
  239. prop_list
  240. : property
  241. | prop_list optcomma property
  242. { $3->vi_next = $1; $$ = $3; }
  243. ;
  244. property
  245. : IDENT
  246. { register symbol *sy_p;
  247. sy_p = lookup($1,symprop,mustexist);
  248. NEW($$,struct varinfo);
  249. $$->vi_next=0;
  250. $$->vi_int[0]=sy_p->sy_value.syv_propno;
  251. free($1);
  252. }
  253. ;
  254. propno
  255. : IDENT
  256. { register symbol *sy_p;
  257. sy_p = lookup($1,symprop,mustexist);
  258. $$ = sy_p->sy_value.syv_propno;
  259. free($1);
  260. }
  261. ;
  262. /* tokens are parsed as struct definitions
  263. * types in the struct can be register properties, ADDR or INT
  264. */
  265. tokens
  266. : TOKENS tokdeflist
  267. ;
  268. tokdeflist
  269. : tokdeflist_el
  270. | tokdeflist tokdeflist_el
  271. ;
  272. tokdeflist_el
  273. : IDENT '=' structdecl NUMBER optcost optformat '.'
  274. { n_tok($1,$3,$4,$5,$6);
  275. free($1);
  276. freevi($3);
  277. freevi($5);
  278. freevi($6);
  279. }
  280. | error '.'
  281. ;
  282. structdecl
  283. : '{' att_list '}'
  284. { $$ = $2; }
  285. ;
  286. att_list
  287. : /* empty */
  288. { $$ = 0; }
  289. | att_list_el att_list
  290. { $$ = $1; while ($$->vi_next) $$ = $$->vi_next;
  291. $$->vi_next = $2; $$ = $1;
  292. }
  293. ;
  294. att_list_el
  295. : att_list_el_type
  296. { att_type = $1; }
  297. att_list_el_list
  298. ';'
  299. { $$ = $3; }
  300. ;
  301. att_list_el_list
  302. : att_ident
  303. | att_ident ',' att_list_el_list
  304. { $1->vi_next = $3; $$ = $1; }
  305. ;
  306. att_ident
  307. : IDENT
  308. { NEW($$, struct varinfo);
  309. $$->vi_next = 0;
  310. $$->vi_int[0] = att_type;
  311. $$->vi_str[0] = $1;
  312. }
  313. ;
  314. att_list_el_type
  315. : INT
  316. { $$ = -1; }
  317. | ADDR
  318. { $$ = -2; }
  319. | propno
  320. ;
  321. optcost
  322. :
  323. { if (defcost==VI_NULL)
  324. $$=VI_NULL;
  325. else {
  326. NEW($$,struct varinfo);
  327. *$$ = *defcost;
  328. }
  329. }
  330. | COST '(' NUMBER ',' NUMBER ')'
  331. { NEW ($$,struct varinfo);
  332. $$->vi_int[0] = $3;
  333. $$->vi_int[1] = $5;
  334. }
  335. ;
  336. optformat
  337. :
  338. { $$ = 0; }
  339. | STRING optformat
  340. { NEW($$,struct varinfo);
  341. $$->vi_next = $2;
  342. $$->vi_int[0] = 0;
  343. $$->vi_str[0] = $1;
  344. }
  345. | IDENT optformat
  346. { NEW($$,struct varinfo);
  347. $$->vi_next = $2;
  348. $$->vi_int[0] = 1;
  349. $$->vi_str[0] = $1;
  350. }
  351. ;
  352. optcomma
  353. : ','
  354. | /* empty */
  355. ;
  356. /* sets are parsed as ident = expression */
  357. sets
  358. : SETS setdeflist
  359. ;
  360. setdeflist
  361. : setdeflist_el
  362. | setdeflist setdeflist_el
  363. ;
  364. setdeflist_el
  365. : IDENT '=' tokenset_no '.'
  366. { n_set($1,$3); free($1); }
  367. | error '.'
  368. ;
  369. tokenset_no
  370. : tokenset
  371. { $$ = setlookup($1); }
  372. ;
  373. tokenset
  374. : IDENT
  375. { $$ = ident_to_set($1); free($1); }
  376. | tokenset '*' tokenset
  377. { $$ = setproduct($1,$3); }
  378. | tokenset '+' tokenset
  379. { $$ = setsum($1,$3); }
  380. | tokenset '-' tokenset
  381. { $$ = setdiff($1,$3); }
  382. | '(' tokenset ')'
  383. { $$ = $2; }
  384. ;
  385. instructions
  386. : INSTRUCTIONS optcost instdef_list
  387. { defcost = $2; }
  388. ;
  389. instdef_list
  390. : instdef_list_el
  391. | instdef_list instdef_list_el
  392. ;
  393. instdef_list_el
  394. : IDENT optstring oplist opt_erase_list optcost '.'
  395. { n_instr($1,$2,$3,$4,$5); freevi($5); }
  396. | error '.'
  397. ;
  398. oplist
  399. : /* empty */
  400. { $$ = 0; }
  401. | oplist_el
  402. | oplist_el ',' oplist
  403. { $$ = $1; $$->o_next = $3; }
  404. ;
  405. oplist_el
  406. : tokenset_no adornlist
  407. { NEW($$,struct operand);
  408. $$->o_next = 0 ;
  409. $$->o_setno = $1;
  410. $$->o_adorn = $2;
  411. checkprintformat($1);
  412. }
  413. ;
  414. adornlist
  415. : /* empty */
  416. { $$ = 0; }
  417. | ADORNACCESS adornlist
  418. { if ($2&AD_RWMASK)
  419. error("Only one of :ro,:wo,:rw allowed");
  420. $$ = $1 | $2;
  421. }
  422. | ADORNCC adornlist
  423. { $$ = $1|$2; }
  424. ;
  425. opt_erase_list
  426. : /* empty */
  427. { $$ = VI_NULL;}
  428. | KILLS erase_list
  429. { $$ = $2; }
  430. ;
  431. erase_list
  432. : erase_list_el
  433. { $$ = $1; }
  434. | erase_list_el erase_list
  435. { $1->vi_next = $2; $$ = $1; }
  436. ;
  437. erase_list_el
  438. : IDENT
  439. { $$ = make_erase($1); }
  440. | ADORNCC
  441. { NEW($$, struct varinfo);
  442. $$->vi_int[0] = -1;
  443. $$->vi_next = VI_NULL;
  444. }
  445. ;
  446. /* Now the moves */
  447. moves
  448. : MOVES
  449. movedeflist
  450. | /* empty */
  451. ;
  452. movedeflist
  453. : movedeflist_el
  454. | movedeflist movedeflist_el
  455. ;
  456. movedeflist_el
  457. : FROM
  458. {startline = lineno; }
  459. tokenset_no
  460. { Xstackflag = 1;
  461. cursetno = $3;
  462. }
  463. optexpr
  464. { Xstackflag = 0;
  465. cursetno = -1;
  466. }
  467. TO tokenset_no
  468. { cursetno = $8;
  469. tokpatlen=2;
  470. tokpatset[0] = $3;
  471. tokpatset[1] = $8;
  472. tokpatro[0] = 1;
  473. Xstackflag = 1;
  474. }
  475. optexpr
  476. { Xstackflag = 0;
  477. cursetno = -1;
  478. }
  479. GEN genlist
  480. { tokpatlen=0;
  481. tokpatro[0]=0;
  482. n_move($3,$5,$8,$10,$13);
  483. freevi($13);
  484. }
  485. | error
  486. ;
  487. /* Now the test part */
  488. tests
  489. : TESTS
  490. { Xstackflag = 1; }
  491. testdeflist
  492. { Xstackflag = 0; }
  493. | /* empty */
  494. ;
  495. testdeflist
  496. : testdeflist_el
  497. | testdeflist testdeflist_el
  498. ;
  499. testdeflist_el
  500. : TO
  501. { startline = lineno;}
  502. TEST tokenset_no
  503. { cursetno = $4;
  504. tokpatlen=1;
  505. tokpatset[0]=$4;
  506. tokpatro[0] = 1;
  507. }
  508. optexpr GEN genlist
  509. { tokpatlen=0;
  510. tokpatro[0] = 0;
  511. n_test($4,$6,$8);
  512. freevi($8);
  513. cursetno = -1;
  514. }
  515. | error
  516. ;
  517. /* Now the stacks */
  518. stacks
  519. : STACKINGRULES
  520. { Xstackflag = 1; }
  521. stackdeflist
  522. { Xstackflag = 0; }
  523. ;
  524. stackdeflist
  525. : stackdeflist_el
  526. | stackdeflist stackdeflist_el
  527. ;
  528. stackdeflist_el
  529. : FROM
  530. {startline = lineno;}
  531. tokenset_no
  532. { cursetno = $3;
  533. tokpatlen=1;
  534. tokpatset[0] = $3;
  535. tokpatro[0] = 1;
  536. }
  537. optexpr TO STACK optuses GEN genlist
  538. { tokpatro[0] = 0;
  539. n_stack($3,$5,$8,$10);
  540. freevi($10);
  541. cursetno = -1;
  542. }
  543. ;
  544. optuses
  545. : /* empty */
  546. { $$ = -1; nallreg=0;}
  547. | USES propno
  548. { $$ = $2; nallreg = 1; allreg[0] = $2; }
  549. ;
  550. /* Now the one-to-one coercion rules */
  551. coercs
  552. : COERCIONS
  553. { Xstackflag = 1; }
  554. coercdeflist
  555. { Xstackflag = 0; }
  556. ;
  557. coercdeflist
  558. : coercdeflist_el
  559. | coercdeflist coercdeflist_el
  560. ;
  561. coercdeflist_el
  562. : FROM
  563. {startline = lineno; tokpatlen=0; inithall();}
  564. STACK allocates generates YIELDS tokeninstance
  565. { checkhall();
  566. n_coerc(0,0,$4,$5,(struct varinfo *) 0,$7);
  567. freevi($4);
  568. freevi($5);
  569. }
  570. | FROM
  571. {startline = lineno;}
  572. tokenset_no
  573. { cursetno = $3;
  574. tokpatlen=1;
  575. tokpatset[0]=$3;
  576. tokpatro[0] = 1;
  577. inithall();
  578. }
  579. optexpr allocates generates yields
  580. { tokpatro[0] = 0;
  581. checkhall();
  582. n_coerc($3,$5,$6,$7,$8);
  583. freevi($6);
  584. freevi($7);
  585. cursetno = -1;
  586. }
  587. ;
  588. /* Now the code part */
  589. code
  590. : PATTERNS coderules
  591. ;
  592. coderules
  593. : coderule
  594. | coderules coderule
  595. ;
  596. coderule
  597. : PAT {emhere=1;} empattern {emhere=0;} optexpr
  598. { empatexpr = $5;
  599. npatterns = 0;
  600. saferulefound=0;
  601. if (empatlen>maxempatlen)
  602. maxempatlen=empatlen;
  603. }
  604. patterns
  605. { if (!saferulefound)
  606. error("Previous rule impossible on empty stack");
  607. outpatterns();
  608. }
  609. | PROC IDENT example
  610. { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); }
  611. patterns
  612. { if (!saferulefound)
  613. error("Previous rule impossible on empty stack");
  614. outpatterns(); inproc=0;
  615. }
  616. | error
  617. { skipupto(PAT,"pat"); yyerrok; yyclearin; }
  618. ;
  619. example
  620. : /* empty */
  621. { empatlen = 0; }
  622. | EXAMPLE {emhere=1;} empattern {emhere=0;}
  623. ;
  624. empattern
  625. : EMMNEM
  626. { empatlen = 1; emmnem[0] = $1; }
  627. | empattern EMMNEM
  628. { NEXT(empatlen,EMPATMAX,"Em pattern");
  629. emmnem[empatlen-1] = $2;
  630. }
  631. ;
  632. patterns
  633. : onepattern
  634. { saferulefound=1;
  635. callproc=0;
  636. }
  637. | morepatterns
  638. { callproc=0;
  639. if (npatterns>maxrule)
  640. maxrule=npatterns;
  641. }
  642. | CALL IDENT '(' stringlist ')'
  643. { register symbol *sy_p;
  644. saferulefound=1;
  645. sy_p=lookup($2,symproc,mustexist);
  646. callproc=sy_p->sy_value.syv_procoff;
  647. free($2);
  648. if (nprocargs > maxprocargs) maxprocargs = nprocargs;
  649. }
  650. ;
  651. stringlist
  652. : STRING
  653. { nprocargs = 1; procarg[0] = strlookup($1); free($1); }
  654. | stringlist ',' STRING
  655. { NEXT(nprocargs, MAXPROCARG, "Procedure argument list");
  656. procarg[nprocargs-1] = strlookup($3); free($3);
  657. }
  658. ;
  659. onepattern
  660. : { inithall(); startline=lineno;
  661. tokpatlen=0; optexact=0; optstack=0;
  662. }
  663. kills allocates generates yields leaving
  664. {
  665. patindex[npatterns++]=codeindex;
  666. checkhall();
  667. dopattern(0,$2,$3,$4,$5,$6);
  668. freevi($2);
  669. freevi($3);
  670. freevi($4);
  671. freevi($5);
  672. freevi($6);
  673. }
  674. ;
  675. morepatterns
  676. : { inithall(); } pattern
  677. | morepatterns { inithall(); } pattern
  678. ;
  679. pattern
  680. : stackpattern kills allocates generates yields leaving
  681. { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex;
  682. if (hall() && !optexact) saferulefound=1;
  683. dopattern(0,$2,$3,$4,$5,$6);
  684. freevi($2);
  685. freevi($3);
  686. freevi($4);
  687. freevi($5);
  688. freevi($6);
  689. }
  690. ;
  691. stackpattern
  692. : WITH optexact
  693. { startline = lineno; }
  694. setlist optstack
  695. { if (tokpatlen > maxtokpatlen) maxtokpatlen = tokpatlen; }
  696. ;
  697. optexact
  698. : /* empty */
  699. { $$ = optexact = 0; }
  700. | EXACT
  701. { $$ = optexact = 1; }
  702. ;
  703. optstack
  704. : /* empty */
  705. { $$ = optstack = 0; }
  706. | STACK
  707. { $$ = optstack = 1; }
  708. ;
  709. setlist
  710. : /* empty */
  711. { tokpatlen = 0; }
  712. | setlist tokenset_no
  713. { NEXT(tokpatlen,TOKPATMAX,"Stack pattern");
  714. tokpatset[tokpatlen-1] = $2;
  715. checkunstacking($2);
  716. if (l_sets[$2].set_size == 0) {
  717. error("Tokenset is empty or has elements with different sizes");
  718. }
  719. }
  720. ;
  721. kills
  722. : /* empty */
  723. { $$ = 0; }
  724. | KILLS kill_list
  725. { $$ = $2;
  726. }
  727. ;
  728. kill_list
  729. : kill_list_el
  730. | kill_list_el ',' kill_list
  731. { $$=$1; $$->vi_next = $3; }
  732. ;
  733. kill_list_el
  734. : tokenset_no { cursetno=$1; } optexpr
  735. { NEW($$,struct varinfo);
  736. $$->vi_next = 0;
  737. $$->vi_int[0]=$1;
  738. $$->vi_int[1]=$3;
  739. cursetno = -1;
  740. }
  741. | regvarexpr
  742. { NEW($$,struct varinfo);
  743. $$->vi_next = 0;
  744. $$->vi_int[0] = -($1.ex_index + 1);
  745. $$->vi_int[1] = 0;
  746. }
  747. ;
  748. allocates
  749. : /* empty */
  750. { $$ = 0; nallreg=0;}
  751. | USES uselist
  752. { $$ = $2; setallreg($2); }
  753. ;
  754. uselist
  755. : uselist_el
  756. { prophall($1->vi_int[0]); }
  757. | uselist_el ',' uselist
  758. { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; }
  759. ;
  760. uselist_el
  761. : property
  762. { $$=$1; $$->vi_int[1] = 0; }
  763. | property '=' tokeninstance
  764. { if (!existalmove($3,$$->vi_int[0]))
  765. error("No such move defined");
  766. $$=$1; $$->vi_int[1] = $3.in_index;
  767. }
  768. | REUSING tokeninstance
  769. { NEW($$,struct varinfo);
  770. $$->vi_next = 0;
  771. $$->vi_int[0] = -1;
  772. $$->vi_int[1] = $2.in_index;
  773. }
  774. ;
  775. generates
  776. : /* empty */
  777. { $$ = 0; }
  778. | GEN genlist
  779. { $$ = $2; }
  780. ;
  781. genlist
  782. : /* empty */
  783. { $$ = 0; }
  784. | gen_instruction genlist
  785. { if ($1!=0) {
  786. register struct varinfo *tvip;
  787. $$=tvip=$1;
  788. while (tvip->vi_next!=VI_NULL)
  789. tvip=tvip->vi_next;
  790. tvip->vi_next = $2;
  791. } else {
  792. $$ = $2;
  793. }
  794. }
  795. ;
  796. gen_instruction
  797. : {instline = lineno; } IDENT optstar gen_oplist
  798. { saveline =lineno; lineno=instline;
  799. $$ = gen_inst($2,$3); free($2);
  800. lineno = saveline;
  801. }
  802. | NUMBER ':'
  803. { $$ = gen_tlab($1); }
  804. | MOVE tokeninstance ',' tokeninstance
  805. { $$ = gen_move($2,$4); }
  806. | TEST tokeninstance
  807. { $$ = gen_test($2);}
  808. | LABELDEF emarg
  809. { $$ = gen_label($2-1); use_tes++; }
  810. | RETURN
  811. { $$ = gen_preturn(); }
  812. ;
  813. optstar
  814. : /* empty */
  815. { $$=0; }
  816. | '*'
  817. { $$=1; }
  818. | '[' NUMBER ']'
  819. { $$=$2; }
  820. ;
  821. gen_oplist
  822. : '.' /* empty gives conflicts */
  823. { niops=0; }
  824. | tokeninstance
  825. { niops=1;iops[0]=$1; }
  826. | gen_oplist ',' tokeninstance
  827. { iops[niops++] = $3; }
  828. ;
  829. yields
  830. : /* empty */
  831. { $$ = 0; }
  832. | YIELDS { tokrepllen = 0; } yieldlist
  833. { $$ = $3; if (tokrepllen > maxtokrepllen) maxtokrepllen = tokrepllen; }
  834. ;
  835. yieldlist
  836. : /* empty */
  837. { $$ = 0; }
  838. | tokeninstance yieldlist
  839. { checkstacking($1.in_set);
  840. NEW($$,struct varinfo);
  841. $$->vi_next = $2;
  842. $$->vi_int[0] = $1.in_index;
  843. tokrepllen++;
  844. }
  845. ;
  846. leaving
  847. : /* empty */
  848. { $$ = 0; }
  849. | LEAVING {emhere=1; in_em_repl=1; emrepllen = 0; } leavelist
  850. { emhere=0; in_em_repl=0; $$ = $3;
  851. if (emrepllen > maxemrepllen) maxemrepllen = emrepllen;
  852. }
  853. ;
  854. leavelist
  855. : leavelist_el
  856. | leavelist_el leavelist
  857. { $$=$1; $$->vi_next=$2; }
  858. ;
  859. leavelist_el
  860. : EMMNEM optexpr
  861. { NEW($$,struct varinfo);
  862. $$->vi_next=0;
  863. $$->vi_int[0] = $1;
  864. $$->vi_int[1] = $2;
  865. emrepllen++;
  866. }
  867. ;
  868. optstring
  869. : /* empty */
  870. { $$ = 0; }
  871. | STRING
  872. ;
  873. optexpr
  874. : /* empty */
  875. { $$ = 0; }
  876. | expr
  877. { $$ = $1.ex_index; } /* type checking ? */
  878. ;
  879. tokeninstance
  880. : tokarg subreg
  881. { $$ = subr_iocc($1,$2); }
  882. | tokarg '.' IDENT
  883. { $$ = tokm_iocc($1,$3); free($3); }
  884. | IDENT
  885. { $$ = ident_iocc($1); free($1);}
  886. | allreg subreg
  887. { $$ = all_iocc($1,$2); }
  888. | PERC_IDENT
  889. { if (cursetno < 0) {
  890. error("%%<ident> not allowed here");
  891. }
  892. $$ = percident_iocc($1);
  893. free($1);
  894. }
  895. | '{' IDENT attlist '}'
  896. { $$ = descr_iocc($2); free($2); }
  897. ;
  898. attlist
  899. : /* empty */
  900. { narexpr = 0; }
  901. | attlist ',' expr
  902. { arexp[narexpr++] = $3; }
  903. ;
  904. emarg
  905. : DOLLAR
  906. { if ($1<1 || $1>empatlen)
  907. error("Only %d instructions in pattern",empatlen);
  908. $$ = $1;
  909. }
  910. ;
  911. tokarg
  912. : PERCENT
  913. { $$ = $1;
  914. if (in_em_repl)
  915. error("No token references allowed in EM replacement part");
  916. if ($1<1 || $1>tokpatlen) {
  917. error("Only %d tokens in stackpattern",tokpatlen);
  918. $$ =1;
  919. }
  920. if (Xstackflag) $$ = 0;
  921. }
  922. ;
  923. subreg
  924. : /* empty */
  925. { $$ = 0; }
  926. | '.' NUMBER
  927. { if ($2<1 || $2>2) {
  928. error("Only 2 subregisters allowed");
  929. $$ = 1;
  930. } else {
  931. $$ = $2;
  932. }
  933. }
  934. ;
  935. allreg
  936. : ALLREG
  937. { if ($1>=nallreg)
  938. fatal("Only %d registers allocated",nallreg);
  939. $$ = $1;
  940. }
  941. ;
  942. expr
  943. : NUMBER
  944. { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16));
  945. }
  946. | emarg
  947. { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); }
  948. | STRING
  949. { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); }
  950. | IDENT
  951. { $$ = ident_expr($1); free($1); }
  952. | tokarg subreg
  953. { $$ = subreg_expr($1,$2); }
  954. | tokarg '.' IDENT
  955. { $$ = tokm_expr($1,$3); free($3); }
  956. | allreg subreg
  957. { $$ = all_expr($1,$2); }
  958. | PERC_IDENT
  959. { if (cursetno < 0) {
  960. error("%%<ident> not allowed here");
  961. }
  962. $$ = perc_ident_expr($1);
  963. free($1);
  964. }
  965. | DEFINED '(' expr ')'
  966. { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); }
  967. | SAMESIGN '(' expr ',' expr ')'
  968. { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); }
  969. | TOPELTSIZE '(' emarg ')'
  970. { $$ = make_expr(TYPINT,EX_TOPELTSIZE,$3-1,0); }
  971. | FALLTHROUGH '(' emarg ')'
  972. { $$ = make_expr(TYPBOOL,EX_FALLTHROUGH,$3-1,0); }
  973. | SFIT '(' expr ',' expr ')'
  974. { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); }
  975. | UFIT '(' expr ',' expr ')'
  976. { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); }
  977. | ROM '(' emarg ',' NUMBER ')'
  978. { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); }
  979. | ISROM '(' emarg ')'
  980. { $$ = make_expr(TYPBOOL,EX_ISROM,$3-1,0); }
  981. | LOWW '(' emarg ')'
  982. { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
  983. | HIGHW '(' emarg ')'
  984. { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
  985. /* Excluded, because it causes a shift-reduce conflict
  986. (problems with a tokenset_no followed by an optexpr)
  987. | '-' expr %prec UMINUS
  988. { $$ = make_expr(TYPINT,EX_CON, 0, 0);
  989. $$ = make_expr(TYPINT,EX_MINUS,i_expr($$),i_expr($2));
  990. }
  991. */
  992. | '(' expr ')'
  993. { $$ = $2; }
  994. | expr CMPEQ expr
  995. { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); }
  996. | expr CMPNE expr
  997. { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); }
  998. | expr CMPLT expr
  999. { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); }
  1000. | expr CMPGT expr
  1001. { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); }
  1002. | expr CMPLE expr
  1003. { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); }
  1004. | expr CMPGE expr
  1005. { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); }
  1006. | expr OR2 expr
  1007. { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); }
  1008. | expr AND2 expr
  1009. { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); }
  1010. | expr '|' expr
  1011. { $$ = make_expr(TYPINT,EX_OR,i_expr($1),i_expr($3)); }
  1012. | expr '^' expr
  1013. { $$ = make_expr(TYPINT,EX_XOR,i_expr($1),i_expr($3)); }
  1014. | expr '&' expr
  1015. { $$ = make_expr(TYPINT,EX_AND,i_expr($1),i_expr($3)); }
  1016. | expr '+' expr
  1017. { $$ = sum_expr($1,$3); }
  1018. | expr '-' expr
  1019. { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); }
  1020. | expr '*' expr
  1021. { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); }
  1022. | expr '/' expr
  1023. { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); }
  1024. | expr '%' expr
  1025. { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); }
  1026. | expr LSHIFT expr
  1027. { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); }
  1028. | expr RSHIFT expr
  1029. { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); }
  1030. | NOT expr
  1031. { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); }
  1032. | COMP expr
  1033. { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); }
  1034. | INREG '(' expr ')'
  1035. { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); }
  1036. | regvartype
  1037. { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); }
  1038. | regvarexpr
  1039. ;
  1040. regvarexpr
  1041. : REGVAR '(' expr optregvartype ')'
  1042. { $$ = regvar_expr($3,$4); }
  1043. ;
  1044. optregvartype
  1045. : /* empty */
  1046. { $$ = reg_any; }
  1047. | ',' regvartype
  1048. { $$ = $2; }
  1049. ;
  1050. %%
  1051. #include "scan.c"