1 /****************************************************************************
2     Copyright (C) 1987-2015 by Jeffery P. Hansen
3 
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8 
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License along
15     with this program; if not, write to the Free Software Foundation, Inc.,
16     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 ****************************************************************************/
18 %expect 1
19 
20 %token NETLISTBEGIN HDLBEGIN BUILTINBEGIN SYMBOLBEGIN
21 
22 %token XMODULE NETMODULE HDLMODULE BUILTINMODULE
23 
24 %token ASSIGN ENDMODULE
25 %token PRIMITIVE TECHNOLOGY DELAY AREA POWER IF ELSE SWITCH CASE CASEX CASEZ RETURN
26 %token BREAK NEXT FUNC DEFAULT INITIALB
27 %token INPUT REG OUTPUT INOUT WIRE KWVERSION SUPPLY0 SUPPLY1 KWTRI TRI0 TRI1 TRIREG TRIAND TRIOR WAND WOR
28 
29 %token DEASSIGN BBEGIN END ENDCASE ALWAYS POSEDGE NEGEDGE
30 %token INTEGER ENDPRIMITIVE
31 
32 %token SEMI COLON COMMA DOT ASGN NBASGN LPAREN RPAREN LBRACE RBRACE LBRACK RBRACK AT
33 %token ANOTATE ENDANOTATE ROT WPLACE SHOWNAME ENDDECLS NOT PORTS PORTDEF BDPORTS
34 %token SIZE JOINT COMMENT FRAME SLASH BDESC ROOTMODULE TRAN COMLINE COMEND SCRIPT BEGINSCRIPT ENDSCRIPT REQUIRE
35 %token PROPERTY DECPOS ICONDATA DATA ICONEND SYMBOLREF
36 %token TEXTBEGIN HASHMARK
37 
38 %token GT LT EQ BAND BNAND BOR BNOR BXOR BNXOR UINV MOD LSHIFT RSHIFTEQ QUEST
39 
40 %token ARSHIFT ALSHIFT
41 
42 %token BOGOCHAR
43 
44 %token <I> NUMBER
45 %token <S> HEX VERNUM
46 %token <S> LITERAL STRING HDLLINE SYSLITERAL
47 
48 %type <I> bwidth obang bdir dtype wsizep
49 %type <S> dparm clit modparmval
50 %type <E> pexpr pcode pc_stats pc_stat
51 
52 
53 %left QUEST COLON
54 %left OR
55 %left AND
56 %left BOR BNOR
57 %left BXOR BNXOR
58 %left BAND BNAND
59 %left EQ NE
60 %left GT LT GE LE
61 %left LSHIFT RSHIFT
62 %left ADD SUB
63 %left MUL DIV MOD
64 %left POW
65 %left UNEG UPLUS NOT UINV
66 
67 %{
68 #include <unistd.h>
69 #include <stdio.h>
70 #include "config.h"
71 #include "yybasic.h"
72 #include "vgrammar.h"
73 #include "vparser.h"
74 #include "ycmalloc.h"
75 #include "misc.h"
76 
77 extern int yy_is_editor;
78 
79 static char *tech_name = "default";
80 
81 void BeginPV();		/* Pure verilog */
82 void BeginVR();		/* tkgate verilog */
83 void BeginAC();
84 void BeginLC();
85 void BeginBC();
86 void BeginDD();
87 void BeginDDP();
88 void BeginVN();
89 void BeginHDL();
90 
91 %}
92 
93 %%
94 
95 /*****************************************************************************
96  * Top-level file.
97  *****************************************************************************/
98 prog	: ANOTATE KWVERSION STRING ENDANOTATE { VerCheckVersion($3); } vunits
99 	| KWVERSION { BeginVN(); } VERNUM { BeginDD(); }  tunits
100 	| vunit vunits
101 	| /* Empty file */
102 	;
103 
104 
105 /*****************************************************************************
106  * Tech file units
107  *****************************************************************************/
108 tunits	:
109 	| tunits tunit
110 	;
111 
112 tunit	: primdef
113 	| tech_def
114 	;
115 
116 /*****************************************************************************
117  * Verilog file units
118  *****************************************************************************/
119 vunits	:
120 	| vunits vunit
121 	;
122 
123 vunit	: net_module
124 	| builtin_module
125 	| hdl_module
126 	| modsymbol
127 	| ANOTATE SCRIPT STRING ENDANOTATE			{ VerAddScript($3); }
128 	| ANOTATE REQUIRE STRING ENDANOTATE			{ VerAddVLib($3); }
129 	| ANOTATE PROPERTY LITERAL ASGN NUMBER ENDANOTATE	{ VerCircuitProp($3,&$5,TYPE_INT); }
130 	| ANOTATE PROPERTY LITERAL ASGN LITERAL ENDANOTATE	{ VerCircuitProp($3,$5,TYPE_STR); }
131 	| ANOTATE PROPERTY LITERAL ASGN STRING ENDANOTATE 	{ VerCircuitProp($3,$5,TYPE_STR); }
132 	| error ENDANOTATE
133 	| SEMI
134 	;
135 
136 /*****************************************************************************
137  * HDL module
138  *
139  * There are two types of Verilog HDL modules we can scan.  'native' and 'annotated'.
140  * An 'annotated' module is one with tkgate annotations. A native module is one that
141  * is in standard verilog without any tkgate annotations.  These cases correspond
142  * to the first two rules below.
143  *
144  *****************************************************************************/
145 hdl_module	: ANOTATE HDLBEGIN LITERAL ENDANOTATE { nativeVerilog = 0; VerNewModule(HDLMODULE,$3,0); }
146 		  hprops ANOTATE ENDDECLS ENDANOTATE
147 		  { BeginHDL(); } hstats END { BeginVR(); VerEndModule(); }
148 		| hdl_modhead { VerModParm(0); BeginHDL(); } hstats ENDMODULE { BeginVR(); VerEndModule(); }
149 		| error END { BeginVR(); }
150 		| error ENDMODULE { BeginVR(); }
151 		;
152 
153 hdl_modhead	: HDLMODULE LITERAL LPAREN { nativeVerilog = 1; VerNewModule(HDLMODULE,$2,0); } omargs RPAREN SEMI
154 		| HDLMODULE LITERAL SEMI { nativeVerilog = 1; VerNewModule(HDLMODULE,$2,1); }
155 		| HDLMODULE LITERAL HASHMARK { nativeVerilog = 1; VerNewModule(HDLMODULE,$2,0); } LPAREN mparms RPAREN LPAREN omargs RPAREN SEMI
156 		;
157 
158 mparms	: mparm
159 	| mparms COMMA mparm
160 	;
161 
162 mparm	: LITERAL ASGN pexpr			{ VerModHashParm($1,$3); }
163 	| DOT LITERAL LPAREN pexpr RPAREN	{ VerModHashParm($2,$4); }
164 	;
165 
166 
167 hstats		:
168 		| hstats HDLLINE { VerAddHdlLine($2); }
169 		;
170 
171 hprops	:
172 	| hprops hprop
173 	;
174 
175 hprop	: ANOTATE BDESC { VerBeginBD(); } cnote ENDANOTATE { VerEndBD(); }
176 	| ANOTATE SYMBOLREF COLON NUMBER ENDANOTATE { VerModuleProp("symbol",&$4,TYPE_INT); }
177 	| ANOTATE ROOTMODULE ENDANOTATE { VerSetRootMod(); }
178 	| ANOTATE PROPERTY LITERAL ASGN NUMBER ENDANOTATE { VerModuleProp($3,&$5,TYPE_INT); }
179 	| ANOTATE PROPERTY LITERAL ASGN LITERAL ENDANOTATE { VerModuleProp($3,$5,TYPE_STR); }
180 	| ANOTATE PROPERTY LITERAL ASGN STRING ENDANOTATE { VerModuleProp($3,$5,TYPE_STR); }
181 	;
182 
183 /*****************************************************************************
184  * Built-in module - These should simply be ignored
185  *****************************************************************************/
186 builtin_module : ANOTATE BUILTINBEGIN ENDANOTATE
187 		 { nativeVerilog = 0; BeginHDL(); } skiplines END { BeginVR(); }
188 		;
189 
190 skiplines	:
191 		| skiplines HDLLINE
192 		;
193 
194 /*****************************************************************************
195  * Netlist module
196  *****************************************************************************/
197 net_module	: ANOTATE NETLISTBEGIN LITERAL ENDANOTATE { VerNewModule(NETMODULE,$3,0); }
198 		  net_e_modhead decls enddecl stats ENDMODULE { VerEndModule(); }
199 		  ANOTATE END ENDANOTATE
200 		| net_modhead decls enddecl stats ENDMODULE { VerEndModule(); }
201 		;
202 
203 net_modhead	: NETMODULE LITERAL LPAREN { VerNewModule(NETMODULE,$2,0); } omargs RPAREN SEMI
204 		| NETMODULE LITERAL SEMI  { VerNewModule(NETMODULE,$2,1); }
205 		;
206 net_e_modhead	: NETMODULE LITERAL LPAREN omargs RPAREN SEMI
207 		| NETMODULE LITERAL SEMI
208 		;
209 
210 omargs	:
211 	| margs
212 	;
213 
214 margs	: LITERAL			{ VerModParm($1); }
215 	| margs COMMA LITERAL		{ VerModParm($3); }
216 	;
217 
218 
219 decls	:
220 	| decls decl
221 	;
222 
223 decl	: dtype bwidth LITERAL SEMI 	{ VerNewNet($3,$2,$1); }
224 	| ANOTATE wnotes ENDANOTATE
225 	| ANOTATE BDESC { VerBeginBD(); } cnote ENDANOTATE { VerEndBD(); }
226 	| ANOTATE SYMBOLREF COLON NUMBER ENDANOTATE { VerModuleProp("symbol",&$4,TYPE_INT); }
227 	| ANOTATE ROOTMODULE ENDANOTATE { VerSetRootMod(); }
228 	| ANOTATE PROPERTY LITERAL ASGN NUMBER ENDANOTATE { VerModuleProp($3,&$5,TYPE_INT); }
229 	| ANOTATE PROPERTY LITERAL ASGN LITERAL ENDANOTATE { VerModuleProp($3,$5,TYPE_STR); }
230 	| ANOTATE PROPERTY LITERAL ASGN STRING ENDANOTATE { VerModuleProp($3,$5,TYPE_STR); }
231 	;
232 
233 dtype	: INPUT				{ $$ = INPUT; }
234 	| OUTPUT			{ $$ = OUTPUT; }
235 	| INOUT				{ $$ = INOUT; }
236 	| SUPPLY0			{ $$ = SUPPLY0; }
237 	| SUPPLY1			{ $$ = SUPPLY1; }
238 	| REG 				{ $$ = REG; }
239 	| WIRE 				{ $$ = WIRE; }
240 	| WAND 				{ $$ = WAND; }
241 	| WOR 				{ $$ = WOR; }
242 	| KWTRI 			{ $$ = KWTRI; }
243 	| TRI0 				{ $$ = TRI0; }
244 	| TRI1 				{ $$ = TRI1; }
245 	| TRIAND 			{ $$ = TRIAND; }
246 	| TRIOR 			{ $$ = TRIOR; }
247 	| TRIREG 			{ $$ = TRIREG; }
248 	;
249 
250 wnotes	:
251 	| wnotes wnote
252 	;
253 
254 wnote	: wend wcoords wend
255 	| SHOWNAME COLON NUMBER				{ VerSetShowName($3); }
256 	| DECPOS COLON NUMBER				{ VerSetWireDecorationPos($3,-1,-1); }
257 	| DECPOS COLON LPAREN NUMBER COMMA NUMBER COMMA NUMBER RPAREN	{ VerSetWireDecorationPos($4,$6,$8); }
258 	;
259 
260 wcoords	: wcoord
261 	| wcoords wcoord
262 	;
263 
264 /*
265 wcoord	: LPAREN NUMBER COMMA NUMBER RPAREN					{ VerMakeNode($2,$4,0,0,0); }
266 	| LBRACK NUMBER RBRACK LPAREN NUMBER COMMA NUMBER RPAREN		{ VerMakeNode($5,$7,0,1,$2); }
267 	| HASHMARK LPAREN NUMBER COMMA NUMBER RPAREN				{ VerMakeNode($3,$5,1,0,0); }
268 	| HASHMARK LBRACK NUMBER RBRACK LPAREN NUMBER COMMA NUMBER RPAREN	{ VerMakeNode($6,$8,1,1,$3); }
269 	;
270 */
271 wcoord	: LPAREN wsizep NUMBER COMMA NUMBER RPAREN				{ VerMakeNode($3,$5,$2,0,0); }
272 	| LPAREN wsizep NUMBER COLON NUMBER COMMA NUMBER RPAREN			{ VerMakeNode($5,$7,$2,1,$3); }
273 	;
274 
275 wsizep	: HASHMARK COLON	{ $$ = 1; }
276 	|			{ $$ = 0; }
277 	;
278 
279 wend	: LBRACE NUMBER RBRACE			{ VerMakeWire($2); }
280 	;
281 
282 enddecl	: ANOTATE ENDDECLS ENDANOTATE		{ VerEndDecls(); }
283 	;
284 
285 bwidth	:					{ $$ = 1; }
286 	| LBRACK NUMBER COLON NUMBER RBRACK	{ $$ = ($2-$4)+1; }
287 	;
288 
289 stats	:
290 	| stats stat
291 	;
292 
293 stat	: call SEMI ANOTATE cnote ENDANOTATE { VerEndGate(); }
294 	| ANOTATE joint ENDANOTATE { VerEndGate(); }
295 	| ANOTATE iogate ENDANOTATE { VerEndGate(); }
296 	| ANOTATE comment ENDANOTATE { VerEndGate(); }
297 	| ANOTATE frame ENDANOTATE { VerEndGate(); }
298 	| ANOTATE script { VerEndGate(); }
299 	| concat { VerEndGate(); }
300 	| tran { VerEndGate(); }
301 	| tapassign { VerEndGate(); }
302 	| concat_assign { VerEndGate(); }
303 	| error ENDANOTATE { yyerrok; }
304 	;
305 
306 comment	: COMMENT LITERAL { VerGate("COMMENT",$2); } cnote ENDANOTATE comlines ANOTATE COMEND
307 	;
308 
309 script	: BEGINSCRIPT LITERAL { VerGate("SCRIPT",$2); } cnote ENDANOTATE {BeginHDL(); } script_lines END { BeginVR(); }
310 	;
311 
312 script_lines	:
313 		| script_lines HDLLINE { VerAddScriptLine($2); }
314 		;
315 
316 
317 frame	: FRAME LITERAL { VerGate("FRAME",$2); } cnote
318 	;
319 
320 comlines :
321 	| comlines ANOTATE cnote ENDANOTATE
322 	;
323 
324 joint	: JOINT LITERAL { VerGate("JOINT",$2); } LPAREN LITERAL RPAREN { VerJointNet($5); } cnote
325 	;
326 
327 iogate	: LITERAL LPAREN { VerGate($1,0); } ocargs RPAREN cnote
328 	| LITERAL LITERAL LPAREN { VerGate($1,$2); } ocargs RPAREN cnote
329 	;
330 
331 tapassign	: ASSIGN LITERAL ASGN LITERAL LBRACK NUMBER RBRACK SEMI ANOTATE LITERAL LITERAL
332 		{ VerGate("TAP",$11); VerTranRange($6,$6); VerAttach("Z",$2,0); VerAttach("I",$4,0); VerTranDup(); }
333 		cnote ENDANOTATE
334 		| ASSIGN LITERAL ASGN LITERAL LBRACK NUMBER COLON NUMBER RBRACK SEMI ANOTATE LITERAL LITERAL
335 		{ VerGate("TAP",$13); VerTranRange($6,$8); VerAttach("Z",$2,0); VerAttach("I",$4,0); VerTranDup(); }
336 		cnote ENDANOTATE
337 		;
338 
339 concat_assign	: ASSIGN LITERAL ASGN LBRACE { VerGate("CONCAT",0); VerAttach("Z",$2,0); } concat_args RBRACE SEMI
340 			ANOTATE LITERAL LITERAL { VerRenameCurrent($11); VerRevPad(0); } cnote ENDANOTATE
341 		| ASSIGN LBRACE  { VerGate("CONCAT",0); } concat_args RBRACE ASGN LITERAL { VerAttach("Z",$7,0); } SEMI
342 			ANOTATE LITERAL LITERAL { VerRenameCurrent($12); VerRevPad(0); } cnote ENDANOTATE
343 		;
344 
345 
346 concat	: TRAN LITERAL LBRACK  NUMBER COLON NUMBER RBRACK LPAREN { VerGate("CONCAT",$2); }
347 	  LBRACE concat_args RBRACE
348 	  COMMA
349 	  LITERAL { VerAttach("Z",$14,0); }
350 	  RPAREN SEMI { VerRevPad(0); }
351 	  ANOTATE cnote ENDANOTATE
352 	;
353 
354 concat_args : LITERAL { VerAttach("I",$1,0); }
355 	    | concat_args COMMA LITERAL { VerAttach("I",$3,0); }
356 		;
357 
358 /*
359  * Old style syntac for TAP gates.
360  */
361 tran	: TRAN LITERAL LPAREN { VerGate("TAP",$2); } carg COMMA
362 		tran_arg { VerTranDup(); } RPAREN SEMI ANOTATE cnote ENDANOTATE
363 	;
364 
365 tran_arg	: DOT LITERAL LPAREN obang LITERAL tran_range RPAREN { VerAttach($2,$5,$4); }
366 		| obang LITERAL tran_range			{ VerAttach(0,$2,$1); }
367 		;
368 
369 tran_range	: LBRACK NUMBER RBRACK			{ VerTranRange($2,$2); }
370 		|  LBRACK NUMBER COLON NUMBER RBRACK	{ VerTranRange($2,$4); }
371 		;
372 
373 call		: LITERAL { VerCallMParmFlush(); } omodparms LITERAL LPAREN { VerCell($1,$4); } ocargs RPAREN
374 		;
375 
376 omodparms	:
377 		| HASHMARK LPAREN modparms RPAREN
378 		;
379 
380 modparms	: modparm
381 		| modparms COMMA modparm
382 		;
383 
384 modparm		: modparmval				{ VerCallMParmAdd(0,$1); }
385 		| DOT LITERAL LPAREN modparmval RPAREN	{ VerCallMParmAdd($2,$4); }
386 		| LITERAL ASGN modparmval		{ VerCallMParmAdd($1,$3); }
387 		;
388 
389 modparmval	: NUMBER 				{ $$ = yc_sprintf("%u",$1); }
390 		| HEX					{ $$ = $1; }
391 		| STRING				{ char buf[1024]; $$ = yc_sprintf("\"%s\"",quoteChars(buf,$1,"\"\\")); }
392 		;
393 
394 ocargs	:
395 	| cargs
396 	;
397 
398 cargs	: carg
399 	| cargs COMMA carg
400 	;
401 
402 carg	: DOT LITERAL LPAREN obang clit RPAREN		{ VerAttach($2,$5,$4); }
403 	| obang LITERAL					{ VerAttach(0,$2,$1); }
404 	;
405 
406 /*
407  * We ignore any bit repetitions in netlist modules and assume tkgate will figure
408  * out what to do on its own.
409  */
410 clit	: LITERAL					{ $$ = $1; }
411 	| LBRACE NUMBER LBRACE LITERAL RBRACE RBRACE	{ $$ = $4; }
412 	;
413 
414 obang	:			{ $$ = 0; }
415 	| NOT			{ $$ = 1; }
416 	| UINV			{ $$ = 1; }
417 	;
418 
419 
420 
421 cnote	: citem
422 	| cnote citem
423 	;
424 
425 citem	: AT LPAREN NUMBER COMMA NUMBER RPAREN	{ VerSetPos($3,$5); }
426 	| SIZE COLON LPAREN NUMBER COMMA NUMBER RPAREN { VerSetSize($4,$6); }
427 	| ROT COLON NUMBER			{ VerSetRot($3); }
428 	| WPLACE COLON LBRACK wplist RBRACK
429 	| PORTS COLON LBRACK pplist RBRACK
430 	| BDPORTS COLON LBRACK bdplist RBRACK
431 	| SHOWNAME COLON NUMBER			{ VerSetShowName($3); }
432 	| SYMBOLREF COLON NUMBER		{ VerSetBlockSymbol($3); }
433 	| LITERAL COLON NUMBER			{ VerSetProperty($1,$3); }
434 	| LITERAL COLON STRING			{ VerSetStrProperty($1,$3); }
435 	| LITERAL COLON LITERAL			{ VerSetStrProperty($1,$3); }
436 	;
437 
438 wplist	:
439 	| wplist NUMBER				{ VerPlaceWire($2); }
440 	;
441 
442 pplist	:
443 	| pplist bport
444 	;
445 
446 bport	: LITERAL bdir NUMBER			{ VerBlockPort($1,$2,$3); }
447 	;
448 
449 bdir	: GT					{ $$ = 2; }
450 	| LT					{ $$ = 3; }
451 	| ASGN					{ $$ = 1; }
452 	;
453 
454 bdplist	:
455 	| bdplist bdport
456 	;
457 
458 bdport	: LITERAL bdir LITERAL bwidth LPAREN NUMBER SLASH NUMBER RPAREN
459 			{ VerBDPort($1,$2,$3,$4,$6,$8); }
460 	;
461 
462 /*****************************************************************************
463  * Symbol definition
464  *****************************************************************************/
465 modsymbol : ANOTATE SYMBOLBEGIN COLON NUMBER ENDANOTATE { VerSymbol($4); }
466 	  mslines
467 	  ANOTATE END ENDANOTATE			{ VerSymbol(0); }
468 	;
469 
470 mslines	: msline
471 	| mslines msline
472 	;
473 
474 msline	: ANOTATE ICONDATA LITERAL NUMBER NUMBER NUMBER ENDANOTATE	{ VerSetIcon($3,$4,$5,$6); }
475 	| ANOTATE DATA STRING ENDANOTATE 				{ VerIconData($3); }
476 	| ANOTATE ICONEND ENDANOTATE					{ VerSetIcon(0,0,0,0); }
477 	| ANOTATE PORTDEF portdef ENDANOTATE
478 	;
479 
480 portdef	: LITERAL LITERAL bwidth
481 		AT LPAREN NUMBER COMMA NUMBER RPAREN
482 		ROT COLON NUMBER					{ VerSymPort($1,$2,$3,$6,$8,$12); }
483 	;
484 
485 
486 /******************************************************************************/
487 /* Delay file specifications */
488 
489 tech_def : TECHNOLOGY LITERAL { tech_name = $2; } LBRACE primdefs RBRACE { tech_name = "default"; }
490 	| TECHNOLOGY DEFAULT LBRACE primdefs RBRACE
491 	;
492 
493 primdefs :
494 	 | primdefs primdef
495 	 | primdefs SEMI
496 	 ;
497 
498 primdef	: PRIMITIVE LITERAL { VerBeginDelayDef(tech_name,$2); } LBRACE pstats RBRACE { VerEndDelayDef(); }
499 	;
500 
501 pstats	:
502 	| pstats pstat
503 	;
504 
505 pstat	: AREA ASGN pexpr SEMI { PrimSet("area",0,$3); }
506 	| AREA ASGN pcode semi { PrimSet("area",0,$3); }
507 	| POWER ASGN pexpr SEMI { PrimSet("power",0,$3); }
508 	| POWER ASGN pcode semi { PrimSet("power",0,$3); }
509 	| DELAY dparm ASGN pexpr SEMI { PrimSet("delay",$2,$4); }
510 	| DELAY dparm ASGN pcode semi { PrimSet("delay",$2,$4); }
511 	;
512 
513 /*
514  * Delay parameter specifier
515  */
516 dparm	: LT { BeginDDP(); } LITERAL GT {  BeginDD(); $$ = $3; }
517 	;
518 
519 pexpr	: pexpr ADD pexpr		{ $$ = Expr_op(ADD,$1,$3); }
520 	| pexpr SUB pexpr		{ $$ = Expr_op(SUB,$1,$3); }
521 	| pexpr MUL pexpr		{ $$ = Expr_op(MUL,$1,$3); }
522 	| pexpr DIV pexpr		{ $$ = Expr_op(DIV,$1,$3); }
523 	| pexpr AND pexpr		{ $$ = Expr_op(AND,$1,$3); }
524 	| pexpr POW pexpr		{ $$ = Expr_op(POW,$1,$3); }
525 	| pexpr OR pexpr		{ $$ = Expr_op(OR,$1,$3); }
526 	| pexpr GT pexpr		{ $$ = Expr_op(GT,$1,$3); }
527 	| pexpr LT pexpr		{ $$ = Expr_op(LT,$1,$3); }
528 	| pexpr GE pexpr		{ $$ = Expr_op(GE,$1,$3); }
529 	| pexpr LE pexpr		{ $$ = Expr_op(LE,$1,$3); }
530 	| pexpr EQ pexpr		{ $$ = Expr_op(EQ,$1,$3); }
531 	| pexpr NE pexpr		{ $$ = Expr_op(NE,$1,$3); }
532 	| NOT pexpr			{ $$ = Expr_op(NOT,0,$2); }
533 	| SUB pexpr	%prec UNEG	{ $$ = Expr_op(UNEG,0,$2); }
534 	| LPAREN pexpr RPAREN		{ $$ = $2; }
535 	| LITERAL LPAREN pexpr RPAREN	{ $$ = Expr_func($1,$3,0); }
536 	| LITERAL			{ $$ = Expr_lit($1); }
537 	| NUMBER			{ $$ = Expr_num($1); }
538 	;
539 
540 pcode	: LBRACE pc_stats RBRACE	{ $$ = $2; }
541 	;
542 
543 pc_stats :				{ $$ = 0; }
544 	| pc_stats pc_stat		{ $$ = Expr_op(NEXT,$1,$2); }
545 	;
546 
547 pc_stat	: LITERAL ASGN pexpr SEMI			{ $$ = Expr_op(ASGN,Expr_lit($1),$3); }
548 	| IF LPAREN pexpr RPAREN pc_stat		{ $$ = Expr_op3(IF,$3,$5,0); }
549 	| IF LPAREN pexpr RPAREN pc_stat ELSE pc_stat	{ $$ = Expr_op3(IF,$3,$5,$7); }
550 	| LBRACE pc_stats RBRACE			{ $$ = $2; }
551 	| BREAK	SEMI					{ $$ = Expr_op(BREAK,0,0); }
552 	| CASE NUMBER COLON				{ $$ = Expr_case(CASE,$2); }
553 	| CASE SUB NUMBER COLON				{ $$ = Expr_case(CASE,-$3); }
554 	| DEFAULT COLON					{ $$ = Expr_case(DEFAULT,0); }
555 	| RETURN pexpr SEMI				{ $$ = Expr_op(RETURN,$2,0); }
556 	| SWITCH LPAREN pexpr RPAREN pc_stat		{ $$ = Expr_op(SWITCH,$3,$5); }
557 	;
558 
559 semi	:
560 	| SEMI
561 	;
562 
563 %%
564