cgg.y 22 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103
  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. #include <stdio.h>
  7. #include "param.h"
  8. #include "varinfo.h"
  9. #include "lookup.h"
  10. #include "set.h"
  11. #include "iocc.h"
  12. #include "instruct.h"
  13. #include "expr.h"
  14. #include "output.h"
  15. #include "extern.h"
  16. #include "strlookup.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. {
  581. iocc_t empty; /* WARNING */
  582. tokpatro[0] = 0;
  583. checkhall();
  584. n_coerc($3,$5,$6,$7,$8, empty);
  585. freevi($6);
  586. freevi($7);
  587. cursetno = -1;
  588. }
  589. ;
  590. /* Now the code part */
  591. code
  592. : PATTERNS coderules
  593. ;
  594. coderules
  595. : coderule
  596. | coderules coderule
  597. ;
  598. coderule
  599. : PAT {emhere=1;} empattern {emhere=0;} optexpr
  600. { empatexpr = $5;
  601. npatterns = 0;
  602. saferulefound=0;
  603. if (empatlen>maxempatlen)
  604. maxempatlen=empatlen;
  605. }
  606. patterns
  607. { if (!saferulefound)
  608. error("Previous rule impossible on empty stack");
  609. outpatterns();
  610. }
  611. | PROC IDENT example
  612. { npatterns = 0; saferulefound=0; inproc=1; n_proc($2); }
  613. patterns
  614. { if (!saferulefound)
  615. error("Previous rule impossible on empty stack");
  616. outpatterns(); inproc=0;
  617. }
  618. | error
  619. { skipupto(PAT,"pat"); yyerrok; yyclearin; }
  620. ;
  621. example
  622. : /* empty */
  623. { empatlen = 0; }
  624. | EXAMPLE {emhere=1;} empattern {emhere=0;}
  625. ;
  626. empattern
  627. : EMMNEM
  628. { empatlen = 1; emmnem[0] = $1; }
  629. | empattern EMMNEM
  630. { NEXT(empatlen,EMPATMAX,"Em pattern");
  631. emmnem[empatlen-1] = $2;
  632. }
  633. ;
  634. patterns
  635. : onepattern
  636. { saferulefound=1;
  637. callproc=0;
  638. }
  639. | morepatterns
  640. { callproc=0;
  641. if (npatterns>maxrule)
  642. maxrule=npatterns;
  643. }
  644. | CALL IDENT '(' stringlist ')'
  645. { register symbol *sy_p;
  646. saferulefound=1;
  647. sy_p=lookup($2,symproc,mustexist);
  648. callproc=sy_p->sy_value.syv_procoff;
  649. free($2);
  650. if (nprocargs > maxprocargs) maxprocargs = nprocargs;
  651. }
  652. ;
  653. stringlist
  654. : STRING
  655. { nprocargs = 1; procarg[0] = strlookup($1); free($1); }
  656. | stringlist ',' STRING
  657. { NEXT(nprocargs, MAXPROCARG, "Procedure argument list");
  658. procarg[nprocargs-1] = strlookup($3); free($3);
  659. }
  660. ;
  661. onepattern
  662. : { inithall(); startline=lineno;
  663. tokpatlen=0; optexact=0; optstack=0;
  664. }
  665. kills allocates generates yields leaving
  666. {
  667. patindex[npatterns++]=codeindex;
  668. checkhall();
  669. dopattern(0,$2,$3,$4,$5,$6);
  670. freevi($2);
  671. freevi($3);
  672. freevi($4);
  673. freevi($5);
  674. freevi($6);
  675. }
  676. ;
  677. morepatterns
  678. : { inithall(); } pattern
  679. | morepatterns { inithall(); } pattern
  680. ;
  681. pattern
  682. : stackpattern kills allocates generates yields leaving
  683. { patindex[NEXT(npatterns,MAXPATTERNS,"Patterns")]=codeindex;
  684. if (hall() && !optexact) saferulefound=1;
  685. dopattern(0,$2,$3,$4,$5,$6);
  686. freevi($2);
  687. freevi($3);
  688. freevi($4);
  689. freevi($5);
  690. freevi($6);
  691. }
  692. ;
  693. stackpattern
  694. : WITH optexact
  695. { startline = lineno; }
  696. setlist optstack
  697. { if (tokpatlen > maxtokpatlen) maxtokpatlen = tokpatlen; }
  698. ;
  699. optexact
  700. : /* empty */
  701. { $$ = optexact = 0; }
  702. | EXACT
  703. { $$ = optexact = 1; }
  704. ;
  705. optstack
  706. : /* empty */
  707. { $$ = optstack = 0; }
  708. | STACK
  709. { $$ = optstack = 1; }
  710. ;
  711. setlist
  712. : /* empty */
  713. { tokpatlen = 0; }
  714. | setlist tokenset_no
  715. { NEXT(tokpatlen,TOKPATMAX,"Stack pattern");
  716. tokpatset[tokpatlen-1] = $2;
  717. checkunstacking($2);
  718. if (l_sets[$2].set_size == 0) {
  719. error("Tokenset is empty or has elements with different sizes");
  720. }
  721. }
  722. ;
  723. kills
  724. : /* empty */
  725. { $$ = 0; }
  726. | KILLS kill_list
  727. { $$ = $2;
  728. }
  729. ;
  730. kill_list
  731. : kill_list_el
  732. | kill_list_el ',' kill_list
  733. { $$=$1; $$->vi_next = $3; }
  734. ;
  735. kill_list_el
  736. : tokenset_no { cursetno=$1; } optexpr
  737. { NEW($$,struct varinfo);
  738. $$->vi_next = 0;
  739. $$->vi_int[0]=$1;
  740. $$->vi_int[1]=$3;
  741. cursetno = -1;
  742. }
  743. | regvarexpr
  744. { NEW($$,struct varinfo);
  745. $$->vi_next = 0;
  746. $$->vi_int[0] = -($1.ex_index + 1);
  747. $$->vi_int[1] = 0;
  748. }
  749. ;
  750. allocates
  751. : /* empty */
  752. { $$ = 0; nallreg=0;}
  753. | USES uselist
  754. { $$ = $2; setallreg($2); }
  755. ;
  756. uselist
  757. : uselist_el
  758. { prophall($1->vi_int[0]); }
  759. | uselist_el ',' uselist
  760. { prophall($1->vi_int[0]); $$=$1; $$->vi_next=$3; }
  761. ;
  762. uselist_el
  763. : property
  764. { $$=$1; $$->vi_int[1] = 0; }
  765. | property '=' tokeninstance
  766. { if (!existalmove($3,$$->vi_int[0]))
  767. error("No such move defined");
  768. $$=$1; $$->vi_int[1] = $3.in_index;
  769. }
  770. | REUSING tokeninstance
  771. { NEW($$,struct varinfo);
  772. $$->vi_next = 0;
  773. $$->vi_int[0] = -1;
  774. $$->vi_int[1] = $2.in_index;
  775. }
  776. ;
  777. generates
  778. : /* empty */
  779. { $$ = 0; }
  780. | GEN genlist
  781. { $$ = $2; }
  782. ;
  783. genlist
  784. : /* empty */
  785. { $$ = 0; }
  786. | gen_instruction genlist
  787. { if ($1!=0) {
  788. register struct varinfo *tvip;
  789. $$=tvip=$1;
  790. while (tvip->vi_next!=VI_NULL)
  791. tvip=tvip->vi_next;
  792. tvip->vi_next = $2;
  793. } else {
  794. $$ = $2;
  795. }
  796. }
  797. ;
  798. gen_instruction
  799. : {instline = lineno; } IDENT optstar gen_oplist
  800. { saveline =lineno; lineno=instline;
  801. $$ = gen_inst($2,$3); free($2);
  802. lineno = saveline;
  803. }
  804. | NUMBER ':'
  805. { $$ = gen_tlab($1); }
  806. | MOVE tokeninstance ',' tokeninstance
  807. { $$ = gen_move($2,$4); }
  808. | TEST tokeninstance
  809. { $$ = gen_test($2);}
  810. | LABELDEF emarg
  811. { $$ = gen_label($2-1); use_tes++; }
  812. | RETURN
  813. { $$ = gen_preturn(); }
  814. ;
  815. optstar
  816. : /* empty */
  817. { $$=0; }
  818. | '*'
  819. { $$=1; }
  820. | '[' NUMBER ']'
  821. { $$=$2; }
  822. ;
  823. gen_oplist
  824. : '.' /* empty gives conflicts */
  825. { niops=0; }
  826. | tokeninstance
  827. { niops=1;iops[0]=$1; }
  828. | gen_oplist ',' tokeninstance
  829. { iops[niops++] = $3; }
  830. ;
  831. yields
  832. : /* empty */
  833. { $$ = 0; }
  834. | YIELDS { tokrepllen = 0; } yieldlist
  835. { $$ = $3; if (tokrepllen > maxtokrepllen) maxtokrepllen = tokrepllen; }
  836. ;
  837. yieldlist
  838. : /* empty */
  839. { $$ = 0; }
  840. | tokeninstance yieldlist
  841. { checkstacking($1.in_set);
  842. NEW($$,struct varinfo);
  843. $$->vi_next = $2;
  844. $$->vi_int[0] = $1.in_index;
  845. tokrepllen++;
  846. }
  847. ;
  848. leaving
  849. : /* empty */
  850. { $$ = 0; }
  851. | LEAVING {emhere=1; in_em_repl=1; emrepllen = 0; } leavelist
  852. { emhere=0; in_em_repl=0; $$ = $3;
  853. if (emrepllen > maxemrepllen) maxemrepllen = emrepllen;
  854. }
  855. ;
  856. leavelist
  857. : leavelist_el
  858. | leavelist_el leavelist
  859. { $$=$1; $$->vi_next=$2; }
  860. ;
  861. leavelist_el
  862. : EMMNEM optexpr
  863. { NEW($$,struct varinfo);
  864. $$->vi_next=0;
  865. $$->vi_int[0] = $1;
  866. $$->vi_int[1] = $2;
  867. emrepllen++;
  868. }
  869. ;
  870. optstring
  871. : /* empty */
  872. { $$ = 0; }
  873. | STRING
  874. ;
  875. optexpr
  876. : /* empty */
  877. { $$ = 0; }
  878. | expr
  879. { $$ = $1.ex_index; } /* type checking ? */
  880. ;
  881. tokeninstance
  882. : tokarg subreg
  883. { $$ = subr_iocc($1,$2); }
  884. | tokarg '.' IDENT
  885. { $$ = tokm_iocc($1,$3); free($3); }
  886. | IDENT
  887. { $$ = ident_iocc($1); free($1);}
  888. | allreg subreg
  889. { $$ = all_iocc($1,$2); }
  890. | PERC_IDENT
  891. { if (cursetno < 0) {
  892. error("%%<ident> not allowed here");
  893. }
  894. $$ = percident_iocc($1);
  895. free($1);
  896. }
  897. | '{' IDENT attlist '}'
  898. { $$ = descr_iocc($2); free($2); }
  899. ;
  900. attlist
  901. : /* empty */
  902. { narexpr = 0; }
  903. | attlist ',' expr
  904. { arexp[narexpr++] = $3; }
  905. ;
  906. emarg
  907. : DOLLAR
  908. { if ($1<1 || $1>empatlen)
  909. error("Only %d instructions in pattern",empatlen);
  910. $$ = $1;
  911. }
  912. ;
  913. tokarg
  914. : PERCENT
  915. { $$ = $1;
  916. if (in_em_repl)
  917. error("No token references allowed in EM replacement part");
  918. if ($1<1 || $1>tokpatlen) {
  919. error("Only %d tokens in stackpattern",tokpatlen);
  920. $$ =1;
  921. }
  922. if (Xstackflag) $$ = 0;
  923. }
  924. ;
  925. subreg
  926. : /* empty */
  927. { $$ = 0; }
  928. | '.' NUMBER
  929. { if ($2<1 || $2>2) {
  930. error("Only 2 subregisters allowed");
  931. $$ = 1;
  932. } else {
  933. $$ = $2;
  934. }
  935. }
  936. ;
  937. allreg
  938. : ALLREG
  939. { if ($1>=nallreg)
  940. fatal("Only %d registers allocated",nallreg);
  941. $$ = $1;
  942. }
  943. ;
  944. expr
  945. : NUMBER
  946. { $$ = make_expr(TYPINT,EX_CON, (int) ($1 & 0xFFFF), (int) ($1>>16));
  947. }
  948. | emarg
  949. { $$ = make_expr(argtyp(emmnem[$1-1]),EX_ARG,$1,0); }
  950. | STRING
  951. { $$ = make_expr(TYPADDR,EX_STRING,strlookup($1),0); free($1); }
  952. | IDENT
  953. { $$ = ident_expr($1); free($1); }
  954. | tokarg subreg
  955. { $$ = subreg_expr($1,$2); }
  956. | tokarg '.' IDENT
  957. { $$ = tokm_expr($1,$3); free($3); }
  958. | allreg subreg
  959. { $$ = all_expr($1,$2); }
  960. | PERC_IDENT
  961. { if (cursetno < 0) {
  962. error("%%<ident> not allowed here");
  963. }
  964. $$ = perc_ident_expr($1);
  965. free($1);
  966. }
  967. | DEFINED '(' expr ')'
  968. { $$ = make_expr(TYPBOOL,EX_DEFINED,i_expr($3),0); }
  969. | SAMESIGN '(' expr ',' expr ')'
  970. { $$ = make_expr(TYPBOOL,EX_SAMESIGN,i_expr($3),i_expr($5)); }
  971. | TOPELTSIZE '(' emarg ')'
  972. { $$ = make_expr(TYPINT,EX_TOPELTSIZE,$3-1,0); }
  973. | FALLTHROUGH '(' emarg ')'
  974. { $$ = make_expr(TYPBOOL,EX_FALLTHROUGH,$3-1,0); }
  975. | SFIT '(' expr ',' expr ')'
  976. { $$ = make_expr(TYPBOOL,EX_SFIT,i_expr($3),i_expr($5)); }
  977. | UFIT '(' expr ',' expr ')'
  978. { $$ = make_expr(TYPBOOL,EX_UFIT,i_expr($3),i_expr($5)); }
  979. | ROM '(' emarg ',' NUMBER ')'
  980. { $$ = make_expr(TYPINT,EX_ROM,$3-1,chkincl($5,1,3)-1); }
  981. | ISROM '(' emarg ')'
  982. { $$ = make_expr(TYPBOOL,EX_ISROM,$3-1,0); }
  983. | LOWW '(' emarg ')'
  984. { $$ = make_expr(TYPINT,EX_LOWW,$3-1,0); }
  985. | HIGHW '(' emarg ')'
  986. { $$ = make_expr(TYPINT,EX_HIGHW,$3-1,0); }
  987. /* Excluded, because it causes a shift-reduce conflict
  988. (problems with a tokenset_no followed by an optexpr)
  989. | '-' expr %prec UMINUS
  990. { $$ = make_expr(TYPINT,EX_CON, 0, 0);
  991. $$ = make_expr(TYPINT,EX_MINUS,i_expr($$),i_expr($2));
  992. }
  993. */
  994. | '(' expr ')'
  995. { $$ = $2; }
  996. | expr CMPEQ expr
  997. { $$ = make_expr(TYPBOOL,eq2expr($1,$3),$1.ex_index,$3.ex_index); }
  998. | expr CMPNE expr
  999. { $$ = make_expr(TYPBOOL,ne2expr($1,$3),$1.ex_index,$3.ex_index); }
  1000. | expr CMPLT expr
  1001. { $$ = make_expr(TYPBOOL,EX_NCPLT,i_expr($1),i_expr($3)); }
  1002. | expr CMPGT expr
  1003. { $$ = make_expr(TYPBOOL,EX_NCPGT,i_expr($1),i_expr($3)); }
  1004. | expr CMPLE expr
  1005. { $$ = make_expr(TYPBOOL,EX_NCPLE,i_expr($1),i_expr($3)); }
  1006. | expr CMPGE expr
  1007. { $$ = make_expr(TYPBOOL,EX_NCPGE,i_expr($1),i_expr($3)); }
  1008. | expr OR2 expr
  1009. { $$ = make_expr(TYPBOOL,EX_OR2,b_expr($1),b_expr($3)); }
  1010. | expr AND2 expr
  1011. { $$ = make_expr(TYPBOOL,EX_AND2,b_expr($1),b_expr($3)); }
  1012. | expr '|' expr
  1013. { $$ = make_expr(TYPINT,EX_OR,i_expr($1),i_expr($3)); }
  1014. | expr '^' expr
  1015. { $$ = make_expr(TYPINT,EX_XOR,i_expr($1),i_expr($3)); }
  1016. | expr '&' expr
  1017. { $$ = make_expr(TYPINT,EX_AND,i_expr($1),i_expr($3)); }
  1018. | expr '+' expr
  1019. { $$ = sum_expr($1,$3); }
  1020. | expr '-' expr
  1021. { $$ = make_expr(TYPINT,EX_MINUS,i_expr($1),i_expr($3)); }
  1022. | expr '*' expr
  1023. { $$ = make_expr(TYPINT,EX_TIMES,i_expr($1),i_expr($3)); }
  1024. | expr '/' expr
  1025. { $$ = make_expr(TYPINT,EX_DIVIDE,i_expr($1),i_expr($3)); }
  1026. | expr '%' expr
  1027. { $$ = make_expr(TYPINT,EX_MOD,i_expr($1),i_expr($3)); }
  1028. | expr LSHIFT expr
  1029. { $$ = make_expr(TYPINT,EX_LSHIFT,i_expr($1),i_expr($3)); }
  1030. | expr RSHIFT expr
  1031. { $$ = make_expr(TYPINT,EX_RSHIFT,i_expr($1),i_expr($3)); }
  1032. | NOT expr
  1033. { $$ = make_expr(TYPBOOL,EX_NOT,b_expr($2),0); }
  1034. | COMP expr
  1035. { $$ = make_expr(TYPINT,EX_COMP,i_expr($2),0); }
  1036. | INREG '(' expr ')'
  1037. { $$ = make_expr(TYPINT,EX_INREG,i_expr($3),0); }
  1038. | regvartype
  1039. { $$ = make_expr(TYPINT,EX_CON, $1+1, 0); }
  1040. | regvarexpr
  1041. ;
  1042. regvarexpr
  1043. : REGVAR '(' expr optregvartype ')'
  1044. { $$ = regvar_expr($3,$4); }
  1045. ;
  1046. optregvartype
  1047. : /* empty */
  1048. { $$ = reg_any; }
  1049. | ',' regvartype
  1050. { $$ = $2; }
  1051. ;
  1052. %%
  1053. #include "scan.c"