1 // -*- C++ -*-
2 //*************************************************************************
3 // DESCRIPTION: Verilog-Perl bison parser
4 //
5 // This file is part of Verilog-Perl.
6 //
7 // Author: Wilson Snyder <wsnyder@wsnyder.org>
8 //
9 // Code available from: https://www.veripool.org/verilog-perl
10 //
11 //*************************************************************************
12 //
13 // Copyright 2001-2021 by Wilson Snyder.  This program is free software;
14 // you can redistribute it and/or modify it under the terms of either the GNU
15 // Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 // GNU General Public License for more details.
21 //
22 //*************************************************************************
23 
24 %{
25 
26 #include <cstdio>
27 #include <fstream>
28 #include <stack>
29 #include <vector>
30 #include <map>
31 #include <deque>
32 #include <cassert>
33 #include <cstring>
34 #include <cerrno>
35 #include <cstdlib>
36 #include <climits>
37 
38 #include "VParse.h"
39 #include "VParseGrammar.h"
40 
41 #define YYERROR_VERBOSE 1
42 #define YYINITDEPTH 5000	// Large as the stack won't grow, since YYSTYPE_IS_TRIVIAL isn't defined
43 #define YYMAXDEPTH 5000
44 
45 // See VParseGrammar.h for the C++ interface to this parser
46 // Include that instead of VParseBison.h
47 
48 //*************************************************************************
49 
50 #define GRAMMARP VParseGrammar::staticGrammarp()
51 #define PARSEP VParseGrammar::staticParsep()
52 
53 #define NEWSTRING(text) (string((text)))
54 #define SPACED(a,b)	((a)+(((a)=="" || (b)=="")?"":" ")+(b))
55 
56 #define VARS_PUSH() { GRAMMARP->m_varStack.push_back(GRAMMARP->m_var); }
57 #define VARS_POP() { GRAMMARP->m_var = GRAMMARP->m_varStack.back(); GRAMMARP->m_varStack.pop_back(); }
58 
59 #define VARRESET_LIST(decl)    { GRAMMARP->pinNum(1); VARRESET(); VARDECL(decl); }	// Start of pinlist
60 #define VARRESET_NONLIST(decl) { GRAMMARP->pinNum(0); VARRESET(); VARDECL(decl); }	// Not in a pinlist
61 #define VARRESET()	 { VARDECL(""); VARIO(""); VARNET(""); VARDTYPE(""); }  // Start of one variable decl
62 
63 // VARDECL("") indicates inside a port list or IO list and we shouldn't declare the variable
64 #define VARDECL(type) \
65     { GRAMMARP->m_var.m_decl = (type); }  // genvar, parameter, localparam
66 #define VARIO(type) \
67     { GRAMMARP->m_var.m_io = (type); }  // input, output, inout, ref, const ref
68 #define VARNET(type) \
69     { GRAMMARP->m_var.m_net = (type); }  // supply*,wire,tri
70 #define VARDTYPE(type) \
71     { GRAMMARP->m_var.m_dtype = (type); }  // "signed", "int", etc
72 
73 #define PINNUMINC()	{ GRAMMARP->pinNumInc(); }
74 
75 #define INSTPREP(cellmod,cellparam,withinInst) { GRAMMARP->pinNum(1); GRAMMARP->m_cellMod=(cellmod); GRAMMARP->m_cellParam=(cellparam); GRAMMARP->m_withinInst = 1; }
76 #define INSTDONE() { GRAMMARP->m_withinInst = 0; }
77 
78 enum net_idx {NI_NETNAME = 0, NI_MSB, NI_LSB};
79 
VARDONE(VFileLine * fl,const string & name,const string & array,const string & value)80 static void VARDONE(VFileLine * fl, const string& name, const string& array, const string& value) {
81     if (GRAMMARP->m_var.m_io != "" && GRAMMARP->m_var.m_decl == "")
82         GRAMMARP->m_var.m_decl = "port";
83     if (GRAMMARP->m_var.m_decl != "") {
84         PARSEP->varCb(fl, GRAMMARP->m_var.m_decl, name, PARSEP->symObjofUpward(),
85                       GRAMMARP->m_var.m_net, GRAMMARP->m_var.m_dtype, array, value);
86     }
87     if (GRAMMARP->m_var.m_io != "" || GRAMMARP->pinNum()) {
88         PARSEP->portCb(fl, name, PARSEP->symObjofUpward(), GRAMMARP->m_var.m_io,
89                        GRAMMARP->m_var.m_dtype, array, GRAMMARP->pinNum());
90     }
91     if (GRAMMARP->m_var.m_dtype == "type") {
92         PARSEP->syms().replaceInsert(VAstType::TYPE, name);
93     }
94 }
95 
VARDONETYPEDEF(VFileLine * fl,const string & name,const string & type,const string & array)96 static void VARDONETYPEDEF(VFileLine* fl, const string& name, const string& type, const string& array) {
97     VARRESET(); VARDECL("typedef"); VARDTYPE(type);
98     VARDONE(fl,name,array,"");
99     // TYPE shouldn't override a more specific node type, as often is forward reference
100     PARSEP->syms().replaceInsert(VAstType::TYPE, name);
101 }
102 
parse_net_constants(VFileLine * fl,VParseHashElem nets[][3])103 static void parse_net_constants(VFileLine* fl, VParseHashElem nets[][3]) {
104     VParseHashElem (*net)[3] = &nets[0];
105     VParseHashElem* nhp = net[0];
106 
107     std::deque<VParseNet>::iterator it = GRAMMARP->m_portStack.begin();
108     while (it != GRAMMARP->m_portStack.end()) {
109 	// Default net name is simply the complete token
110 	const char* netnamep = it->m_name.c_str();
111 
112 	size_t delim = it->m_name.find_first_of("'");
113 	if (it->m_name[0] != '\\' && it->m_msb.empty()
114 	    && delim != string::npos && it->m_name[delim] == '\'') {
115 	    // Handle sized integer constants (e.g., 7'b0) specifically but ignore replications (e.g., {4{w}})
116 	    if (delim != 0 && netnamep[0] != '{') {
117 		// Handle the first part that indicates the width for sized constants (guaranteed to be a decimal)
118 		char* endp;
119 		errno = 0;
120 		long l = strtol(netnamep, &endp, 10);
121 		if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l <= 0) {
122 		    fl->error((string)"Unexpected length in size of integer constant: \""+netnamep+"\".");
123 		    return;
124 		}
125 		// Skip whitespace
126 		while (endp < netnamep + delim && isspace(*endp)) {
127 		    endp++;
128 		}
129 		if (endp != netnamep + delim) {
130 		    fl->error((string)"Could not convert size of integer constant: \""+netnamep+"\".");
131 		    return;
132 		}
133 		int count = l;
134 
135 		// Skip characters up to the delimiter ' to determine new netnamep
136 		netnamep += delim;
137 
138 		// Test for legal base specifiers:
139 		// d, D, h, H, o, O , b, or B for the decimal, hexadecimal, octal, and binary bases, respectively
140 		char base = netnamep[1];
141 		// 's' indicates a signed constant, is followed by the actual base; currently ignored
142 		if (base == 's' || base == 'S') {
143 		    base = netnamep[2];
144 		}
145 		if (strchr("dDhHoObB", base) == NULL) {
146 		    fl->error((string)"Base specifier \""+base+"\" is not valid in integer constant \""+it->m_name.c_str()+"\".");
147 		    return;
148 		}
149 
150 		// These assignments could be prettified with C++11
151 		nhp[NI_MSB].keyp = "msb";
152 		nhp[NI_MSB].val_type = VParseHashElem::ELEM_INT;
153 		nhp[NI_MSB].val_int = count - 1;
154 		nhp[NI_LSB].keyp = "lsb";
155 		nhp[NI_LSB].val_type = VParseHashElem::ELEM_INT;
156 		nhp[NI_LSB].val_int = 0;
157 	    } else {
158 		// fl->error increases the error count which would create regressions for no good reasons.
159 		// There is no ->warn or similar though but we could print, e.g., to stderr in these cases
160 		//fl->error((string)"Neither unsized integer constant nor replications are not fully supported in nets (\""+netnamep+"\").");
161 		//fprintf(stderr, "Neither unsized integer constant nor replications are not fully supported in nets (\"%s\").\n", netnamep);
162 	    }
163 	} else {
164 	    // Ordinary net names might have a range attached or not.
165 	    // If it does then parse its bounds into proper integers.
166 	    const char *msbstr = it->m_msb.c_str();
167 	    if (msbstr[0] != '\0') {
168 		{ // Parse NI_MSB
169 		    char* endp;
170 		    errno = 0;
171 		    long l = strtol(msbstr, &endp, 10);
172 		    // Test for range within int, and proper parsing
173 		    if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l < 0
174 			|| (endp && l == 0 && errno == ERANGE)) {
175 			fl->error((string)"Unexpected length in msb specification of \""+netnamep+"\" (endp="+endp+", errno="+strerror(errno)+").");
176 			return;
177 		    }
178 		    nhp[NI_MSB].keyp = "msb";
179 		    nhp[NI_MSB].val_type = VParseHashElem::ELEM_INT;
180 		    nhp[NI_MSB].val_int = (int)l;
181 		}
182 		{ // Parse NI_LSB
183 		    char* endp;
184 		    errno = 0;
185 		    long l = strtol(it->m_lsb.c_str(), &endp, 10);
186 		    if ((errno == ERANGE && l == LONG_MAX) || l > INT_MAX || l < 0
187 			|| (endp && l == 0 && errno == ERANGE)) {
188 			fl->error((string)"Unexpected length in lsb specification of \""+netnamep+"\".");
189 			return;
190 		    }
191 		    nhp[NI_LSB].keyp = "lsb";
192 		    nhp[NI_LSB].val_type = VParseHashElem::ELEM_INT;
193 		    nhp[NI_LSB].val_int = (int)l;
194 		}
195 	    } else {
196 		nhp[NI_MSB].keyp = NULL;
197 		nhp[NI_LSB].keyp = NULL;
198 	    }
199 	}
200 
201 	nhp[NI_NETNAME].keyp = "netname";
202 	nhp[NI_NETNAME].val_type = VParseHashElem::ELEM_STR;
203 	nhp[NI_NETNAME].val_str = netnamep;
204 	*it++;
205 	nhp += 3; // We operate on three elements in each iteration
206     }
207 }
208 
PINDONE(VFileLine * fl,const string & name,const string & expr)209 static void PINDONE(VFileLine* fl, const string& name, const string& expr) {
210     if (GRAMMARP->m_cellParam) {
211 	// Stack them until we create the instance itself
212 	GRAMMARP->m_pinStack.push_back(VParseGPin(fl, name, expr, GRAMMARP->pinNum()));
213     } else {
214 	PARSEP->pinCb(fl, name, expr, GRAMMARP->pinNum());
215 	if (PARSEP->usePinSelects()) {
216 	    if (GRAMMARP->m_portStack.empty()) {
217 		string netname;
218 		if (GRAMMARP->m_portNextNetName.empty()) {
219 		    netname = expr;
220 		} else {
221 		    netname = GRAMMARP->m_portNextNetName;
222 		}
223 		size_t elem_cnt = GRAMMARP->m_portNextNetMsb.empty() ? 1 : 3;
224 		VParseHashElem nets[elem_cnt];
225 		// These assignments could be prettified with C++11
226 		nets[NI_NETNAME].keyp = "netname";
227 		nets[NI_NETNAME].val_type = VParseHashElem::ELEM_STR;
228 		nets[NI_NETNAME].val_str = netname;
229 		if (elem_cnt > 1) {
230 		    nets[NI_MSB].keyp = "msb";
231 		    nets[NI_MSB].val_type = VParseHashElem::ELEM_STR;
232 		    nets[NI_MSB].val_str = GRAMMARP->m_portNextNetMsb;
233 		    nets[NI_LSB].keyp = "lsb";
234 		    nets[NI_LSB].val_type = VParseHashElem::ELEM_STR;
235 		    nets[NI_LSB].val_str = GRAMMARP->m_portNextNetLsb;
236 		}
237 		PARSEP->pinselectsCb(fl, name, 1, elem_cnt, &nets[0], GRAMMARP->pinNum());
238 	    } else {
239 		// Connection with multiple pins was parsed completely.
240 		// There might be one net left in the pipe...
241 		if (GRAMMARP->m_portNextNetValid) {
242 		    GRAMMARP->m_portStack.push_front(VParseNet(GRAMMARP->m_portNextNetName, GRAMMARP->m_portNextNetMsb, GRAMMARP->m_portNextNetLsb));
243 		}
244 
245 		unsigned int arraycnt = GRAMMARP->m_portStack.size();
246 		VParseHashElem nets[arraycnt][3];
247 		parse_net_constants(fl, nets);
248 		PARSEP->pinselectsCb(fl, name, arraycnt, 3, &nets[0][0], GRAMMARP->pinNum());
249 	    }
250 	    // Clear all pin-related fields
251 	    GRAMMARP->m_portNextNetValid = false;
252 	    GRAMMARP->m_portNextNetName.clear();
253 	    GRAMMARP->m_portStack.clear();
254 	    GRAMMARP->m_portNextNetMsb.clear();
255 	    GRAMMARP->m_portNextNetLsb.clear();
256 	}
257     }
258 }
259 
PINPARAMS()260 static void PINPARAMS() {
261     // Throw out all the "pins" we found before we could do instanceCb
262     while (!GRAMMARP->m_pinStack.empty()) {
263 	VParseGPin& pinr = GRAMMARP->m_pinStack.front();
264 	PARSEP->parampinCb(pinr.m_fl, pinr.m_name, pinr.m_conn, pinr.m_number);
265 	GRAMMARP->m_pinStack.pop_front();
266     }
267     GRAMMARP->m_withinPin = true;
268 }
269 
PORTNET(VFileLine * fl,const string & name)270 static void PORTNET(VFileLine* fl, const string& name) {
271     if (!GRAMMARP->m_withinInst) {
272         return;
273     }
274     GRAMMARP->m_portNextNetValid = true;
275     GRAMMARP->m_portNextNetName = name;
276     GRAMMARP->m_portNextNetMsb.clear();
277     GRAMMARP->m_portNextNetLsb.clear();
278 }
279 
PORTRANGE(const string & msb,const string & lsb)280 static void PORTRANGE(const string& msb, const string& lsb) {
281     if (!GRAMMARP->m_withinInst) {
282         return;
283     }
284     GRAMMARP->m_portNextNetMsb = msb;
285     GRAMMARP->m_portNextNetLsb = lsb;
286 }
287 
PIN_CONCAT_APPEND(const string & expr)288 static void PIN_CONCAT_APPEND(const string& expr) {
289     if (!GRAMMARP->m_withinPin) {
290         return;
291     }
292     if (!GRAMMARP->m_portNextNetValid) {
293 	// Only while not within a valid net term the expression is part
294 	// of a replication constant. If that's detected ignore the
295 	// previous expression (that is actually just the contained
296 	// concatenation) in favor of the full replication expression.
297 	if (expr[0] == '{') {
298 	    if (expr.find_first_of("{", 1) != string::npos) {
299 		// fprintf(stderr, "%d: ignoring \"%s\" in favor of \"%s\".\n", __LINE__, GRAMMARP->m_portStack.front().m_name.c_str(), expr.c_str());
300 		GRAMMARP->m_portStack.pop_front();
301 		GRAMMARP->m_portStack.push_front(VParseNet(expr));
302 	    }
303 	} else {
304 	    GRAMMARP->m_portStack.push_front(VParseNet(expr));
305 	}
306     } else {
307         GRAMMARP->m_portStack.push_front(VParseNet(GRAMMARP->m_portNextNetName, GRAMMARP->m_portNextNetMsb, GRAMMARP->m_portNextNetLsb));
308     }
309     GRAMMARP->m_portNextNetValid = false;
310 }
311 
312 /* Yacc */
VParseBisonlex(VParseBisonYYSType * yylvalp)313 static int  VParseBisonlex(VParseBisonYYSType* yylvalp) { return PARSEP->lexToBison(yylvalp); }
314 
VParseBisonerror(const char * s)315 static void VParseBisonerror(const char *s) { VParseGrammar::bisonError(s); }
316 
ERRSVKWD(VFileLine * fileline,const string & tokname)317 static void ERRSVKWD(VFileLine* fileline, const string& tokname) {
318     static int toldonce = 0;
319     fileline->error((string)"Unexpected \""+tokname+"\": \""+tokname+"\" is a SystemVerilog keyword misused as an identifier.");
320     if (!toldonce++) fileline->error("Modify the Verilog-2001 code to avoid SV keywords, or use `begin_keywords or --language.");
321 }
322 
NEED_S09(VFileLine *,const string &)323 static void NEED_S09(VFileLine*, const string&) {
324     //Let lint tools worry about it
325     //fileline->error((string)"Advanced feature: \""+tokname+"\" is a 1800-2009 construct, but used under --language 1800-2005 or earlier.");
326 }
327 
328 %}
329 
330 BISONPRE_VERSION(0.0, 2.999, %pure_parser)
331 BISONPRE_VERSION(3.0,        %pure-parser)
332 BISONPRE_VERSION(0.0, 2.999, %token_table)
333 BISONPRE_VERSION(3.0,        %token-table)
334 BISONPRE_VERSION(2.4, 2.999, %define lr.keep_unreachable_states)
335 BISONPRE_VERSION(3.0,        %define lr.keep-unreachable-state)
336 
337 // When writing Bison patterns we use yTOKEN instead of "token",
338 // so Bison will error out on unknown "token"s.
339 
340 // Generic lexer tokens, for example a number
341 // IEEE: real_number
342 %token<str>		yaFLOATNUM	"FLOATING-POINT NUMBER"
343 
344 // IEEE: identifier, class_identifier, class_variable_identifier,
345 // covergroup_variable_identifier, dynamic_array_variable_identifier,
346 // enum_identifier, interface_identifier, interface_instance_identifier,
347 // package_identifier, type_identifier, variable_identifier,
348 %token<str>		yaID__ETC	"IDENTIFIER"
349 %token<str>		yaID__LEX	"IDENTIFIER-in-lex"
350 %token<str>		yaID__aPACKAGE	"PACKAGE-IDENTIFIER"
351 %token<str>		yaID__aTYPE	"TYPE-IDENTIFIER"
352 //			aCOVERGROUP is same as aTYPE
353 //			Can't predecode aFUNCTION, can declare after use
354 //			Can't predecode aINTERFACE, can declare after use
355 //			Can't predecode aTASK, can declare after use
356 
357 // IEEE: integral_number
358 %token<str>		yaINTNUM	"INTEGER NUMBER"
359 // IEEE: time_literal + time_unit
360 %token<str>		yaTIMENUM	"TIME NUMBER"
361 // IEEE: string_literal
362 %token<str>		yaSTRING	"STRING"
363 %token<str>		yaSTRING__IGNORE "STRING-ignored"	// Used when expr:string not allowed
364 
365 %token<str>		yaTIMINGSPEC	"TIMING SPEC ELEMENT"
366 
367 %token<str>		ygenGATE	"GATE keyword"
368 %token<str>		ygenCONFIGKEYWORD "CONFIG keyword (cell/use/design/etc)"
369 %token<str>		ygenOPERATOR	"OPERATOR"
370 %token<str>		ygenSTRENGTH	"STRENGTH keyword (strong1/etc)"
371 %token<str>		ygenSYSCALL	"SYSCALL"
372 
373 %token<str>		'!'
374 %token<str>		'#'
375 %token<str>		'%'
376 %token<str>		'&'
377 %token<str>		'('
378 %token<str>		')'
379 %token<str>		'*'
380 %token<str>		'+'
381 %token<str>		','
382 %token<str>		'-'
383 %token<str>		'.'
384 %token<str>		'/'
385 %token<str>		':'
386 %token<str>		';'
387 %token<str>		'<'
388 %token<str>		'='
389 %token<str>		'>'
390 %token<str>		'?'
391 %token<str>		'@'
392 %token<str>		'['
393 %token<str>		']'
394 %token<str>		'^'
395 %token<str>		'{'
396 %token<str>		'|'
397 %token<str>		'}'
398 %token<str>		'~'
399 
400 // Specific keywords
401 // yKEYWORD means match "keyword"
402 // Other cases are yXX_KEYWORD where XX makes it unique,
403 // for example yP_ for punctuation based operators.
404 // Double underscores "yX__Y" means token X followed by Y,
405 // and "yX__ETC" means X folled by everything but Y(s).
406 %token<str>		yACCEPT_ON	"accept_on"
407 %token<str>		yALIAS		"alias"
408 %token<str>		yALWAYS		"always"
409 %token<str>		yAND		"and"
410 %token<str>		yASSERT		"assert"
411 %token<str>		yASSIGN		"assign"
412 %token<str>		yASSUME		"assume"
413 %token<str>		yAUTOMATIC	"automatic"
414 %token<str>		yBEFORE		"before"
415 %token<str>		yBEGIN		"begin"
416 %token<str>		yBIND		"bind"
417 %token<str>		yBINS		"bins"
418 %token<str>		yBINSOF		"binsof"
419 %token<str>		yBIT		"bit"
420 %token<str>		yBREAK		"break"
421 %token<str>		yBUF		"buf"
422 %token<str>		yBYTE		"byte"
423 %token<str>		yCASE		"case"
424 %token<str>		yCASEX		"casex"
425 %token<str>		yCASEZ		"casez"
426 %token<str>		yCHANDLE	"chandle"
427 %token<str>		yCHECKER	"checker"
428 %token<str>		yCLASS		"class"
429 %token<str>		yCLOCK		"clock"
430 %token<str>		yCLOCKING	"clocking"
431 %token<str>		yCONSTRAINT	"constraint"
432 %token<str>		yCONST__ETC	"const"
433 %token<str>		yCONST__LEX	"const-in-lex"
434 %token<str>		yCONST__LOCAL	"const-then-local"
435 %token<str>		yCONST__REF	"const-then-ref"
436 %token<str>		yCONTEXT	"context"
437 %token<str>		yCONTINUE	"continue"
438 %token<str>		yCOVER		"cover"
439 %token<str>		yCOVERGROUP	"covergroup"
440 %token<str>		yCOVERPOINT	"coverpoint"
441 %token<str>		yCROSS		"cross"
442 %token<str>		yDEASSIGN	"deassign"
443 %token<str>		yDEFAULT	"default"
444 %token<str>		yDEFPARAM	"defparam"
445 %token<str>		yDISABLE	"disable"
446 %token<str>		yDIST		"dist"
447 %token<str>		yDO		"do"
448 %token<str>		yEDGE		"edge"
449 %token<str>		yELSE		"else"
450 %token<str>		yEND		"end"
451 %token<str>		yENDCASE	"endcase"
452 %token<str>		yENDCHECKER	"endchecker"
453 %token<str>		yENDCLASS	"endclass"
454 %token<str>		yENDCLOCKING	"endclocking"
455 %token<str>		yENDFUNCTION	"endfunction"
456 %token<str>		yENDGENERATE	"endgenerate"
457 %token<str>		yENDGROUP	"endgroup"
458 %token<str>		yENDINTERFACE	"endinterface"
459 %token<str>		yENDMODULE	"endmodule"
460 %token<str>		yENDPACKAGE	"endpackage"
461 %token<str>		yENDPROGRAM	"endprogram"
462 %token<str>		yENDPROPERTY	"endproperty"
463 %token<str>		yENDSEQUENCE	"endsequence"
464 %token<str>		yENDSPECIFY	"endspecify"
465 %token<str>		yENDTABLE	"endtable"
466 %token<str>		yENDTASK	"endtask"
467 %token<str>		yENUM		"enum"
468 %token<str>		yEVENT		"event"
469 %token<str>		yEVENTUALLY	"eventually"
470 %token<str>		yEXPECT		"expect"
471 %token<str>		yEXPORT		"export"
472 %token<str>		yEXTENDS	"extends"
473 %token<str>		yEXTERN		"extern"
474 %token<str>		yFINAL		"final"
475 %token<str>		yFIRST_MATCH	"first_match"
476 %token<str>		yFOR		"for"
477 %token<str>		yFORCE		"force"
478 %token<str>		yFOREACH	"foreach"
479 %token<str>		yFOREVER	"forever"
480 %token<str>		yFORK		"fork"
481 %token<str>		yFORKJOIN	"forkjoin"
482 %token<str>		yFUNCTION__ETC	"function"
483 %token<str>		yFUNCTION__LEX	"function-in-lex"
484 %token<str>		yFUNCTION__aPUREV "function-is-pure-virtual"
485 %token<str>		yGENERATE	"generate"
486 %token<str>		yGENVAR		"genvar"
487 %token<str>		yGLOBAL__CLOCKING "global-then-clocking"
488 %token<str>		yGLOBAL__LEX	"global-in-lex"
489 %token<str>		yIF		"if"
490 %token<str>		yIFF		"iff"
491 %token<str>		yIGNORE_BINS	"ignore_bins"
492 %token<str>		yILLEGAL_BINS	"illegal_bins"
493 %token<str>		yIMPLEMENTS	"implements"
494 %token<str>		yIMPLIES	"implies"
495 %token<str>		yIMPORT		"import"
496 %token<str>		yINITIAL	"initial"
497 %token<str>		yINOUT		"inout"
498 %token<str>		yINPUT		"input"
499 %token<str>		yINSIDE		"inside"
500 %token<str>		yINT		"int"
501 %token<str>		yINTEGER	"integer"
502 %token<str>		yINTERCONNECT	"interconnect"
503 %token<str>		yINTERFACE	"interface"
504 %token<str>		yINTERSECT	"intersect"
505 %token<str>		yJOIN		"join"
506 %token<str>		yLET		"let"
507 %token<str>		yLOCALPARAM	"localparam"
508 %token<str>		yLOCAL__COLONCOLON "local-then-::"
509 %token<str>		yLOCAL__ETC	"local"
510 %token<str>		yLOCAL__LEX	"local-in-lex"
511 %token<str>		yLOGIC		"logic"
512 %token<str>		yLONGINT	"longint"
513 %token<str>		yMATCHES	"matches"
514 %token<str>		yMODPORT	"modport"
515 %token<str>		yMODULE		"module"
516 %token<str>		yNAND		"nand"
517 %token<str>		yNEGEDGE	"negedge"
518 %token<str>		yNETTYPE	"nettype"
519 %token<str>		yNEW__ETC	"new"
520 %token<str>		yNEW__LEX	"new-in-lex"
521 %token<str>		yNEW__PAREN	"new-then-paren"
522 %token<str>		yNEXTTIME	"nexttime"
523 %token<str>		yNOR		"nor"
524 %token<str>		yNOT		"not"
525 %token<str>		yNULL		"null"
526 %token<str>		yOR		"or"
527 %token<str>		yOUTPUT		"output"
528 %token<str>		yPACKAGE	"package"
529 %token<str>		yPACKED		"packed"
530 %token<str>		yPARAMETER	"parameter"
531 %token<str>		yPOSEDGE	"posedge"
532 %token<str>		yPRIORITY	"priority"
533 %token<str>		yPROGRAM	"program"
534 %token<str>		yPROPERTY	"property"
535 %token<str>		yPROTECTED	"protected"
536 %token<str>		yPURE		"pure"
537 %token<str>		yRAND		"rand"
538 %token<str>		yRANDC		"randc"
539 %token<str>		yRANDCASE	"randcase"
540 %token<str>		yRANDSEQUENCE	"randsequence"
541 %token<str>		yREAL		"real"
542 %token<str>		yREALTIME	"realtime"
543 %token<str>		yREF		"ref"
544 %token<str>		yREG		"reg"
545 %token<str>		yREJECT_ON	"reject_on"
546 %token<str>		yRELEASE	"release"
547 %token<str>		yREPEAT		"repeat"
548 %token<str>		yRESTRICT	"restrict"
549 %token<str>		yRETURN		"return"
550 %token<str>		ySCALARED	"scalared"
551 %token<str>		ySEQUENCE	"sequence"
552 %token<str>		ySHORTINT	"shortint"
553 %token<str>		ySHORTREAL	"shortreal"
554 %token<str>		ySIGNED		"signed"
555 %token<str>		ySOFT		"soft"
556 %token<str>		ySOLVE		"solve"
557 %token<str>		ySPECIFY	"specify"
558 %token<str>		ySPECPARAM	"specparam"
559 %token<str>		ySTATIC__CONSTRAINT "static-then-constraint"
560 %token<str>		ySTATIC__ETC	"static"
561 %token<str>		ySTATIC__LEX	"static-in-lex"
562 %token<str>		ySTRING		"string"
563 %token<str>		ySTRONG		"strong"
564 %token<str>		ySTRUCT		"struct"
565 %token<str>		ySUPER		"super"
566 %token<str>		ySUPPLY0	"supply0"
567 %token<str>		ySUPPLY1	"supply1"
568 %token<str>		ySYNC_ACCEPT_ON	"sync_accept_on"
569 %token<str>		ySYNC_REJECT_ON	"sync_reject_on"
570 %token<str>		yS_ALWAYS	"s_always"
571 %token<str>		yS_EVENTUALLY	"s_eventually"
572 %token<str>		yS_NEXTTIME	"s_nexttime"
573 %token<str>		yS_UNTIL	"s_until"
574 %token<str>		yS_UNTIL_WITH	"s_until_with"
575 %token<str>		yTABLE		"table"
576 %token<str>		yTAGGED		"tagged"
577 %token<str>		yTASK__ETC	"task"
578 %token<str>		yTASK__LEX	"task-in-lex"
579 %token<str>		yTASK__aPUREV	"task-is-pure-virtual"
580 %token<str>		yTHIS		"this"
581 %token<str>		yTHROUGHOUT	"throughout"
582 %token<str>		yTIME		"time"
583 %token<str>		yTIMEPRECISION	"timeprecision"
584 %token<str>		yTIMEUNIT	"timeunit"
585 %token<str>		yTRI		"tri"
586 %token<str>		yTRI0		"tri0"
587 %token<str>		yTRI1		"tri1"
588 %token<str>		yTRIAND		"triand"
589 %token<str>		yTRIOR		"trior"
590 %token<str>		yTRIREG		"trireg"
591 %token<str>		yTYPE		"type"
592 %token<str>		yTYPEDEF	"typedef"
593 %token<str>		yUNION		"union"
594 %token<str>		yUNIQUE		"unique"
595 %token<str>		yUNIQUE0	"unique0"
596 %token<str>		yUNSIGNED	"unsigned"
597 %token<str>		yUNTIL		"until"
598 %token<str>		yUNTIL_WITH	"until_with"
599 %token<str>		yUNTYPED	"untyped"
600 %token<str>		yVAR		"var"
601 %token<str>		yVECTORED	"vectored"
602 %token<str>		yVIRTUAL__CLASS	"virtual-then-class"
603 %token<str>		yVIRTUAL__ETC	"virtual"
604 %token<str>		yVIRTUAL__INTERFACE	"virtual-then-interface"
605 %token<str>		yVIRTUAL__LEX	"virtual-in-lex"
606 %token<str>		yVIRTUAL__anyID	"virtual-then-identifier"
607 %token<str>		yVOID		"void"
608 %token<str>		yWAIT		"wait"
609 %token<str>		yWAIT_ORDER	"wait_order"
610 %token<str>		yWAND		"wand"
611 %token<str>		yWEAK		"weak"
612 %token<str>		yWHILE		"while"
613 %token<str>		yWILDCARD	"wildcard"
614 %token<str>		yWIRE		"wire"
615 %token<str>		yWITHIN		"within"
616 %token<str>		yWITH__BRA	"with-then-["
617 %token<str>		yWITH__CUR	"with-then-{"
618 %token<str>		yWITH__ETC	"with"
619 %token<str>		yWITH__LEX	"with-in-lex"
620 %token<str>		yWITH__PAREN	"with-then-("
621 %token<str>		yWOR		"wor"
622 %token<str>		yXNOR		"xnor"
623 %token<str>		yXOR		"xor"
624 
625 %token<str>		yD_ERROR	"$error"
626 %token<str>		yD_FATAL	"$fatal"
627 %token<str>		yD_INFO		"$info"
628 %token<str>		yD_ROOT		"$root"
629 %token<str>		yD_UNIT		"$unit"
630 %token<str>		yD_WARNING	"$warning"
631 
632 %token<str>		yP_TICK		"'"
633 %token<str>		yP_TICKBRA	"'{"
634 %token<str>		yP_OROR		"||"
635 %token<str>		yP_ANDAND	"&&"
636 %token<str>		yP_NOR		"~|"
637 %token<str>		yP_XNOR		"^~"
638 %token<str>		yP_NAND		"~&"
639 %token<str>		yP_EQUAL	"=="
640 %token<str>		yP_NOTEQUAL	"!="
641 %token<str>		yP_CASEEQUAL	"==="
642 %token<str>		yP_CASENOTEQUAL	"!=="
643 %token<str>		yP_WILDEQUAL	"==?"
644 %token<str>		yP_WILDNOTEQUAL	"!=?"
645 %token<str>		yP_GTE		">="
646 %token<str>		yP_LTE		"<="
647 %token<str>		yP_LTE__IGNORE	"<=-ignored"	// Used when expr:<= means assignment
648 %token<str>		yP_SLEFT	"<<"
649 %token<str>		yP_SRIGHT	">>"
650 %token<str>		yP_SSRIGHT	">>>"
651 %token<str>		yP_POW		"**"
652 
653 %token<str>		yP_PAR__IGNORE	"(-ignored"	// Used when sequence_expr:expr:( is ignored
654 %token<str>		yP_PAR__STRENGTH "(-for-strength"
655 
656 %token<str>		yP_LTMINUSGT	"<->"
657 %token<str>		yP_PLUSCOLON	"+:"
658 %token<str>		yP_MINUSCOLON	"-:"
659 %token<str>		yP_MINUSGT	"->"
660 %token<str>		yP_MINUSGTGT	"->>"
661 %token<str>		yP_EQGT		"=>"
662 %token<str>		yP_ASTGT	"*>"
663 %token<str>		yP_ANDANDAND	"&&&"
664 %token<str>		yP_POUNDPOUND	"##"
665 %token<str>		yP_POUNDMINUSPD	"#-#"
666 %token<str>		yP_POUNDEQPD	"#=#"
667 %token<str>		yP_DOTSTAR	".*"
668 
669 %token<str>		yP_ATAT		"@@"
670 %token<str>		yP_COLONCOLON	"::"
671 %token<str>		yP_COLONEQ	":="
672 %token<str>		yP_COLONDIV	":/"
673 %token<str>		yP_ORMINUSGT	"|->"
674 %token<str>		yP_OREQGT	"|=>"
675 %token<str>		yP_BRASTAR	"[*"
676 %token<str>		yP_BRAEQ	"[="
677 %token<str>		yP_BRAMINUSGT	"[->"
678 %token<str>		yP_BRAPLUSKET	"[+]"
679 
680 %token<str>		yP_PLUSPLUS	"++"
681 %token<str>		yP_MINUSMINUS	"--"
682 %token<str>		yP_PLUSEQ	"+="
683 %token<str>		yP_MINUSEQ	"-="
684 %token<str>		yP_TIMESEQ	"*="
685 %token<str>		yP_DIVEQ	"/="
686 %token<str>		yP_MODEQ	"%="
687 %token<str>		yP_ANDEQ	"&="
688 %token<str>		yP_OREQ		"|="
689 %token<str>		yP_XOREQ	"^="
690 %token<str>		yP_SLEFTEQ	"<<="
691 %token<str>		yP_SRIGHTEQ	">>="
692 %token<str>		yP_SSRIGHTEQ	">>>="
693 
694 // '( is not a operator, as "' (" is legal
695 
696 //********************
697 // Verilog op precedence
698 
699 %token<str>	prUNARYARITH
700 %token<str>	prREDUCTION
701 %token<str>	prNEGATION
702 %token<str>	prEVENTBEGIN
703 %token<str>	prTAGGED
704 
705 // These prevent other conflicts
706 %left		yP_ANDANDAND
707 %left		yMATCHES
708 %left		prTAGGED
709 %left		prSEQ_CLOCKING
710 
711 // Lowest precedence
712 // These are in IEEE 17.7.1
713 %nonassoc	yALWAYS yS_ALWAYS yEVENTUALLY yS_EVENTUALLY yACCEPT_ON yREJECT_ON ySYNC_ACCEPT_ON ySYNC_REJECT_ON
714 
715 %right		yP_ORMINUSGT yP_OREQGT yP_POUNDMINUSPD yP_POUNDEQPD
716 %right		yUNTIL yS_UNTIL yUNTIL_WITH yS_UNTIL_WITH yIMPLIES
717 %right		yIFF
718 %left		yOR
719 %left		yAND
720 %nonassoc	yNOT yNEXTTIME yS_NEXTTIME
721 %left		yINTERSECT
722 %left		yWITHIN
723 %right		yTHROUGHOUT
724 %left		prPOUNDPOUND_MULTI
725 %left		yP_POUNDPOUND
726 %left		yP_BRASTAR yP_BRAEQ yP_BRAMINUSGT yP_BRAPLUSKET
727 
728 // Not specified, but needed higher than yOR, lower than normal non-pexpr expressions
729 %left		yPOSEDGE yNEGEDGE yEDGE
730 
731 %left		'{' '}'
732 //%nonassoc	'=' yP_PLUSEQ yP_MINUSEQ yP_TIMESEQ yP_DIVEQ yP_MODEQ yP_ANDEQ yP_OREQ yP_XOREQ yP_SLEFTEQ yP_SRIGHTEQ yP_SSRIGHTEQ yP_COLONEQ yP_COLONDIV yP_LTE
733 %right		yP_MINUSGT yP_LTMINUSGT
734 %right		'?' ':'
735 %left		yP_OROR
736 %left		yP_ANDAND
737 %left		'|' yP_NOR
738 %left		'^' yP_XNOR
739 %left		'&' yP_NAND
740 %left		yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
741 %left		'>' '<' yP_GTE yP_LTE yP_LTE__IGNORE yINSIDE yDIST
742 %left		yP_SLEFT yP_SRIGHT yP_SSRIGHT
743 %left		'+' '-'
744 %left		'*' '/' '%'
745 %left		yP_POW
746 %left		prUNARYARITH yP_MINUSMINUS yP_PLUSPLUS prREDUCTION prNEGATION
747 %left		'.'
748 // Not in IEEE, but need to avoid conflicts; TICK should bind tightly just lower than COLONCOLON
749 %left		yP_TICK
750 //%left		'(' ')' '[' ']' yP_COLONCOLON '.'
751 
752 %nonassoc prLOWER_THAN_ELSE
753 %nonassoc yELSE
754 
755 //BISONPRE_TYPES
756 //  Blank lines for type insertion
757 //  Blank lines for type insertion
758 //  Blank lines for type insertion
759 //  Blank lines for type insertion
760 //  Blank lines for type insertion
761 //  Blank lines for type insertion
762 //  Blank lines for type insertion
763 //  Blank lines for type insertion
764 //  Blank lines for type insertion
765 //  Blank lines for type insertion
766 //  Blank lines for type insertion
767 //  Blank lines for type insertion
768 //  Blank lines for type insertion
769 //  Blank lines for type insertion
770 //  Blank lines for type insertion
771 //  Blank lines for type insertion
772 //  Blank lines for type insertion
773 //  Blank lines for type insertion
774 //  Blank lines for type insertion
775 //  Blank lines for type insertion
776 //  Blank lines for type insertion
777 //  Blank lines for type insertion
778 //  Blank lines for type insertion
779 //  Blank lines for type insertion
780 //  Blank lines for type insertion
781 //  Blank lines for type insertion
782 //  Blank lines for type insertion
783 //  Blank lines for type insertion
784 //  Blank lines for type insertion
785 //  Blank lines for type insertion
786 
787 %start source_text
788 
789 %%
790 //**********************************************************************
791 // Feedback to the Lexer
792 // Note we read a parenthesis ahead, so this may not change the lexer at the right point.
793 
794 statePushVlg:			// For PSL lexing, escape current state into Verilog state
795 		/* empty */			 	{ }
796 	;
797 statePop:			// Return to previous lexing state
798 		/* empty */			 	{ }
799 	;
800 
801 //**********************************************************************
802 // Files
803 
804 source_text:			// ==IEEE: source_text
805 		/* empty */				{ }
806 	//			// timeunits_declaration moved into description:package_item
807 	|	descriptionList				{ }
808 	;
809 
810 descriptionList:		// IEEE: part of source_text
811 		description				{ }
812 	|	descriptionList description		{ }
813 	;
814 
815 description:			// ==IEEE: description
816 		module_declaration			{ }
817 	//			// udp_declaration moved into module_declaration
818 	|	interface_declaration			{ }
819 	|	program_declaration			{ }
820 	|	package_declaration			{ }
821 	|	package_item				{ }
822 	|	bind_directive				{ }
823 	//	unsupported	// IEEE: config_declaration
824 	|	error					{ }
825 	;
826 
827 timeunits_declaration:		// ==IEEE: timeunits_declaration
828 		yTIMEUNIT yaTIMENUM ';'			{ }
829 	|	yTIMEUNIT yaTIMENUM '/' yaTIMENUM ';'	{ NEED_S09($<fl>1,"timeunit /"); }
830 	| 	yTIMEPRECISION  yaTIMENUM ';'		{ }
831 	;
832 
833 //**********************************************************************
834 // Packages
835 
836 package_declaration:		// ==IEEE: package_declaration
837 		packageFront package_itemListE yENDPACKAGE endLabelE
838 			{ PARSEP->endpackageCb($<fl>3,$3);
839 			  PARSEP->symPopScope(VAstType::PACKAGE); }
840 	;
841 
842 packageFront:
843 	//			// Lifetime is 1800-2009
844 		yPACKAGE lifetimeE idAny ';'
845 			{ PARSEP->symPushNew(VAstType::PACKAGE, $3);
846 			  PARSEP->packageCb($<fl>1,$1, $3); }
847 	;
848 
849 package_itemListE:		// IEEE: [{ package_item }]
850 		/* empty */				{ }
851 	|	package_itemList			{ }
852 	;
853 
854 package_itemList:		// IEEE: { package_item }
855 		package_item				{ }
856 	|	package_itemList package_item		{ }
857 	;
858 
859 package_item:			// ==IEEE: package_item
860 		package_or_generate_item_declaration	{ }
861 	|	anonymous_program			{ }
862 	|	package_export_declaration		{ }
863 	|	timeunits_declaration			{ }
864 	;
865 
866 package_or_generate_item_declaration:	// ==IEEE: package_or_generate_item_declaration
867 		net_declaration				{ }
868 	|	data_declaration			{ }
869 	|	task_declaration			{ }
870 	|	function_declaration			{ }
871 	|	checker_declaration			{ }
872 	|	dpi_import_export			{ }
873 	|	extern_constraint_declaration		{ }
874 	|	class_declaration			{ }
875 	//			// class_constructor_declaration is part of function_declaration
876 	|	local_parameter_declaration ';'		{ }
877 	|	parameter_declaration ';'		{ }
878 	|	covergroup_declaration			{ }
879 	|	overload_declaration			{ }
880 	|	assertion_item_declaration		{ }
881 	|	';'					{ }
882 	;
883 
884 package_import_declarationList:
885 		package_import_declaration		{ }
886 	|	package_import_declarationList package_import_declaration { }
887 	;
888 
889 package_import_declaration:	// ==IEEE: package_import_declaration
890 		yIMPORT package_import_itemList ';'	{ }
891 	;
892 
893 package_import_itemList:
894 		package_import_item			{ }
895 	|	package_import_itemList ',' package_import_item { }
896 	;
897 
898 package_import_item:		// ==IEEE: package_import_item
899 		yaID__aPACKAGE yP_COLONCOLON package_import_itemObj
900 			{ PARSEP->syms().import($<fl>1,$1,$3);
901 			  PARSEP->importCb($<fl>1,$1,$3); }
902 	;
903 
904 package_import_itemObj<str>:	// IEEE: part of package_import_item
905 		idAny					{ $<fl>$=$<fl>1; $$=$1; }
906 	|	'*'					{ $<fl>$=$<fl>1; $$=$1; }
907 	;
908 
909 package_export_declaration<str>: // IEEE: package_export_declaration
910 		yEXPORT '*' yP_COLONCOLON '*' ';'	{ }
911 	|	yEXPORT package_import_itemList ';'	{ }
912 	;
913 
914 //**********************************************************************
915 // Module headers
916 
917 module_declaration:		// ==IEEE: module_declaration
918 	//			// timeunits_declaration instead in module_item
919 	//			// IEEE: module_nonansi_header + module_ansi_header
920 		modFront importsAndParametersE portsStarE ';'
921 			module_itemListE yENDMODULE endLabelE
922 			{ PARSEP->endmoduleCb($<fl>6,$6);
923 			  PARSEP->symPopScope(VAstType::MODULE); }
924 	//
925 	|	yEXTERN modFront importsAndParametersE portsStarE ';'
926 			{ PARSEP->symPopScope(VAstType::MODULE); }
927 	;
928 
929 modFront:
930 	//			// General note: all *Front functions must call symPushNew before
931 	//			// any formal arguments, as the arguments must land in the new scope.
932 		yMODULE lifetimeE idAny
933 			{ PARSEP->symPushNew(VAstType::MODULE, $3);
934 			  PARSEP->moduleCb($<fl>1,$1,$3,false,PARSEP->inCellDefine()); }
935 	;
936 
937 importsAndParametersE:		// IEEE: common part of module_declaration, interface_declaration, program_declaration
938 	//			// { package_import_declaration } [ parameter_port_list ]
939 		parameter_port_listE			{ }
940 	|	package_import_declarationList parameter_port_listE	{ }
941 	;
942 
943 parameter_value_assignmentE:	// IEEE: [ parameter_value_assignment ]
944 		/* empty */				{ }
945 	|	'#' '(' cellpinList ')'			{ }
946 	//			// Side effect of combining *_instantiations
947 	|	'#' delay_value				{ }
948 	;
949 
950 parameter_port_listE:		// IEEE: parameter_port_list + empty == parameter_value_assignment
951 		/* empty */				{ }
952 	|	'#' '(' ')'				{ }
953 	//			// IEEE: '#' '(' list_of_param_assignments { ',' parameter_port_declaration } ')'
954 	//			// IEEE: '#' '(' parameter_port_declaration { ',' parameter_port_declaration } ')'
955 	//			// Can't just do that as "," conflicts with between vars and between stmts, so
956 	//			// split into pre-comma and post-comma parts
957 	|	'#' '(' {VARRESET_LIST("parameter");} paramPortDeclOrArgList ')'	{ VARRESET_NONLIST(""); }
958 	//			// Note legal to start with "a=b" with no parameter statement
959 	;
960 
961 paramPortDeclOrArgList:		// IEEE: list_of_param_assignments + { parameter_port_declaration }
962 		paramPortDeclOrArg			{ }
963 	|	paramPortDeclOrArgList ',' paramPortDeclOrArg	{ }
964 	;
965 
966 paramPortDeclOrArg:		// IEEE: param_assignment + parameter_port_declaration
967 	//			// We combine the two as we can't tell which follows a comma
968 		param_assignment			{ }
969 	|	parameter_port_declarationFront param_assignment	{ }
970 	;
971 
972 portsStarE:			// IEEE: .* + list_of_ports + list_of_port_declarations + empty
973 		/* empty */					{ }
974 	//			// .* expanded from module_declaration
975 	//			// '(' ')' handled by list_of_ports:portE
976 	|	'(' yP_DOTSTAR ')'				{ }
977 	|	'(' {VARRESET_LIST("");} list_of_portsE ')'	{ VARRESET_NONLIST(""); }
978 	;
979 
980 list_of_portsE:			// IEEE: list_of_ports + list_of_port_declarations
981 		portE					{ }
982 	|	list_of_portsE ',' portE 		{ }
983 	;
984 
985 portE:				// ==IEEE: [ port ]
986 	//			// Though not type for interfaces, we factor out the port direction and type
987 	//			// so we can simply handle it in one place
988 	//
989 	//			// IEEE: interface_port_header port_identifier { unpacked_dimension }
990 	//			// Expanded interface_port_header
991 	//			// We use instantCb here because the non-port form looks just like a module instantiation
992 		/* empty */				{ }
993 	|	portDirNetE id/*interface*/                      idAny/*port*/ variable_dimensionListE sigAttrListE
994 			{ VARDTYPE($2); VARIO("interface"); VARDONE($<fl>2, $3, $4, ""); PINNUMINC();
995 			  PARSEP->instantCb($<fl>2, $2, $3, $4); PARSEP->endcellCb($<fl>2,""); }
996 	|	portDirNetE yINTERFACE                           idAny/*port*/ variable_dimensionListE sigAttrListE
997 			{ VARDTYPE($2); VARIO("interface"); VARDONE($<fl>2, $3, $4, ""); PINNUMINC(); }
998 	|	portDirNetE id/*interface*/ '.' idAny/*modport*/ idAny/*port*/ variable_dimensionListE sigAttrListE
999 			{ VARDTYPE($2+"."+$4); VARIO("interface"); VARDONE($<fl>2, $5, $6, ""); PINNUMINC();
1000 			  PARSEP->instantCb($<fl>2, $2, $5, $6); PARSEP->endcellCb($<fl>2,""); }
1001 	|	portDirNetE yINTERFACE      '.' idAny/*modport*/ idAny/*port*/ variable_dimensionListE sigAttrListE
1002 			{ VARDTYPE($2+"."+$4); VARIO("interface"); VARDONE($<fl>2, $5, $6, ""); PINNUMINC(); }
1003 	//
1004 	//			// IEEE: ansi_port_declaration, with [port_direction] removed
1005 	//			//   IEEE: [ net_port_header | interface_port_header ] port_identifier { unpacked_dimension } [ '=' constant_expression ]
1006 	//			//   IEEE: [ net_port_header | variable_port_header ] '.' port_identifier '(' [ expression ] ')'
1007 	//			//   IEEE: [ variable_port_header ] port_identifier { variable_dimension } [ '=' constant_expression ]
1008 	//			//   Substitute net_port_header = [ port_direction ] net_port_type
1009 	//			//   Substitute variable_port_header = [ port_direction ] variable_port_type
1010 	//			//   Substitute net_port_type = [ net_type ] data_type_or_implicit
1011 	//			//   Substitute variable_port_type = var_data_type
1012 	//			//     [ [ port_direction ] net_port_type | interface_port_header            ] port_identifier { unpacked_dimension }
1013 	//			//     [ [ port_direction ] var_data_type                                    ] port_identifier variable_dimensionListE [ '=' constant_expression ]
1014 	//			//     [ [ port_direction ] net_port_type | [ port_direction ] var_data_type ] '.' port_identifier '(' [ expression ] ')'
1015 	//
1016 	//			// Remove optional '[...] id' is in portAssignment
1017 	//			// Remove optional '[port_direction]' is in port
1018 	//			//     net_port_type | interface_port_header            port_identifier { unpacked_dimension }
1019 	//			//     net_port_type | interface_port_header            port_identifier { unpacked_dimension }
1020 	//			//     var_data_type                                    port_identifier variable_dimensionListE [ '=' constExpr ]
1021 	//			//     net_port_type | [ port_direction ] var_data_type '.' port_identifier '(' [ expr ] ')'
1022 	//			// Expand implicit_type
1023 	//
1024 	//			// IEEE-2012: Since a net_type_identifier is a data_type, it falls into
1025 	//			// the rules here without change.
1026 	//
1027 	//			// variable_dimensionListE instead of rangeListE to avoid conflicts
1028 	//
1029 	//			// Note implicit rules looks just line declaring additional followon port
1030 	//			// No VARDECL("port") for implicit, as we don't want to declare variables for them
1031 	|	portDirNetE var_data_type       '.' portSig '(' portAssignExprE ')' sigAttrListE
1032 			{ VARDTYPE($2); VARDONE($<fl>4, $4, "", ""); PINNUMINC(); }
1033 	|	portDirNetE signing '.' portSig '(' portAssignExprE ')' sigAttrListE
1034 			{ VARDTYPE($2); VARDONE($<fl>4, $4, "", ""); PINNUMINC(); }
1035 	|	portDirNetE signingE variable_dimensionList  '.' portSig '(' portAssignExprE ')' sigAttrListE
1036 			{ VARDTYPE(SPACED($2,$3)); VARDONE($<fl>5, $5, "", ""); PINNUMINC(); }
1037 	|	portDirNetE yINTERCONNECT signingE variable_dimensionListE '.' portSig '(' portAssignExprE ')' sigAttrListE
1038 			{ VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>6, $6, "", ""); PINNUMINC(); }
1039 	|	portDirNetE /*implicit*/        '.' portSig '(' portAssignExprE ')' sigAttrListE
1040 			{ /*VARDTYPE-same*/ VARDONE($<fl>3, $3, "", ""); PINNUMINC(); }
1041 	//
1042 	|	portDirNetE var_data_type       portSig variable_dimensionListE sigAttrListE
1043 			{ VARDTYPE($2); VARDONE($<fl>3, $3, $4, ""); PINNUMINC(); }
1044 	|	portDirNetE signing  portSig variable_dimensionListE sigAttrListE
1045 			{ VARDTYPE($2); VARDONE($<fl>3, $3, $4, ""); PINNUMINC(); }
1046 	|	portDirNetE signingE variable_dimensionList  portSig variable_dimensionListE sigAttrListE
1047 			{ VARDTYPE(SPACED($2,$3)); VARDONE($<fl>4, $4, $5, ""); PINNUMINC(); }
1048 	|	portDirNetE yINTERCONNECT signingE variable_dimensionList  portSig variable_dimensionListE sigAttrListE
1049 			{ VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>5, $5, $6, ""); PINNUMINC(); }
1050 	|	portDirNetE /*implicit*/        portSig variable_dimensionListE sigAttrListE
1051 			{ /*VARDTYPE-same*/ VARDONE($<fl>2, $2, $3, ""); PINNUMINC(); }
1052 	//
1053 	|	portDirNetE var_data_type       portSig variable_dimensionListE sigAttrListE '=' constExpr
1054 			{ VARDTYPE($2); VARDONE($<fl>3, $3, $4, $7); PINNUMINC(); }
1055 	|	portDirNetE signing  portSig variable_dimensionListE sigAttrListE '=' constExpr
1056 			{ VARDTYPE($2); VARDONE($<fl>3, $3, $4, $7); PINNUMINC(); }
1057 	|	portDirNetE signingE variable_dimensionList  portSig variable_dimensionListE sigAttrListE '=' constExpr
1058 			{ VARDTYPE(SPACED($2,$3)); VARDONE($<fl>4, $4, $5, $8); PINNUMINC(); }
1059 	|	portDirNetE yINTERCONNECT signingE variable_dimensionList  portSig variable_dimensionListE sigAttrListE '=' constExpr
1060 			{ VARDTYPE(SPACED(SPACED($2,$3),$4)); VARDONE($<fl>5, $5, $6, $9); PINNUMINC(); }
1061 	|	portDirNetE /*implicit*/        portSig variable_dimensionListE sigAttrListE '=' constExpr
1062 			{ /*VARDTYPE-same*/ VARDONE($<fl>2, $2, $3, $6); PINNUMINC(); }
1063 	//
1064 	|	'{' list_of_portsE '}'			{ }
1065 	;
1066 
1067 portDirNetE:			// IEEE: part of port, optional net type and/or direction
1068 		/* empty */				{ }
1069 	//			// Per spec, if direction given default the nettype.
1070 	//			// The higher level rule may override this VARDTYPE with one later in the parse.
1071 	|	port_direction				{ VARDTYPE(""/*default_nettype*/); }
1072 	|	port_direction net_type			{ VARDTYPE(""/*default_nettype*/); } // net_type calls VARNET
1073 	|	net_type				{ } // net_type calls VARNET
1074 	;
1075 
1076 port_declNetE:			// IEEE: part of port_declaration, optional net type
1077 		/* empty */				{ }
1078 	|	net_type				{ } // net_type calls VARNET
1079 	;
1080 
1081 portAssignExprE:		// IEEE: part of port, optional expression
1082 		/* empty */				{ }
1083 	|	expr					{ }
1084 	;
1085 
1086 portSig<str>:
1087 		id/*port*/				{ $<fl>$=$<fl>1; $$=$1; }
1088 	|	idSVKwd					{ $<fl>$=$<fl>1; $$=$1; }
1089 	;
1090 
1091 //**********************************************************************
1092 // Interface headers
1093 
1094 interface_declaration:		// IEEE: interface_declaration + interface_nonansi_header + interface_ansi_header:
1095 	//			// timeunits_delcarationE is instead in interface_item
1096 		intFront importsAndParametersE portsStarE ';'
1097 			interface_itemListE yENDINTERFACE endLabelE
1098 			{ PARSEP->endinterfaceCb($<fl>6, $6);
1099 			  PARSEP->symPopScope(VAstType::INTERFACE); }
1100 	|	yEXTERN	intFront importsAndParametersE portsStarE ';'	{ }
1101 	;
1102 
1103 intFront:
1104 		yINTERFACE lifetimeE idAny/*new_interface*/
1105 			{ PARSEP->symPushNew(VAstType::INTERFACE,$3);
1106 			  PARSEP->interfaceCb($<fl>1,$1,$3); }
1107 	;
1108 
1109 interface_itemListE:
1110 		/* empty */				{ }
1111 	|	interface_itemList			{ }
1112 	;
1113 
1114 interface_itemList:
1115 		interface_item				{ }
1116 	|	interface_itemList interface_item	{ }
1117 	;
1118 
1119 interface_item:			// IEEE: interface_item + non_port_interface_item
1120 		port_declaration ';'			{ }
1121 	//			// IEEE: non_port_interface_item
1122 	|	generate_region				{ }
1123 	|	interface_or_generate_item		{ }
1124 	|	program_declaration			{ }
1125 	//			// IEEE 1800-2017: modport_item
1126 	//			// See instead old 2012 position in interface_or_generate_item
1127 	|	interface_declaration			{ }
1128 	|	timeunits_declaration			{ }
1129 	//			// See note in interface_or_generate item
1130 	|	module_common_item			{ }
1131 	;
1132 
1133 interface_or_generate_item:	// ==IEEE: interface_or_generate_item
1134 	//			// module_common_item in interface_item, as otherwise duplicated
1135 	//			// with module_or_generate_item:module_common_item
1136 	//			// IEEE 1800-2017 removes modport_declaration here
1137 	//			// but for 2012 compatibility we retain it
1138 		modport_declaration			{ }
1139 	|	extern_tf_declaration			{ }
1140 	;
1141 
1142 //**********************************************************************
1143 // Program headers
1144 
1145 anonymous_program:		// ==IEEE: anonymous_program
1146 	//			// See the spec - this doesn't change the scope, items still go up "top"
1147 		yPROGRAM ';' anonymous_program_itemListE yENDPROGRAM	{ }
1148 	;
1149 
1150 anonymous_program_itemListE:	// IEEE: { anonymous_program_item }
1151 		/* empty */				{ }
1152 	|	anonymous_program_itemList		{ }
1153 	;
1154 
1155 anonymous_program_itemList:	// IEEE: { anonymous_program_item }
1156 		anonymous_program_item			{ }
1157 	|	anonymous_program_itemList anonymous_program_item	{ }
1158 	;
1159 
1160 anonymous_program_item:		// ==IEEE: anonymous_program_item
1161 		task_declaration			{ }
1162 	|	function_declaration			{ }
1163 	|	class_declaration			{ }
1164 	|	covergroup_declaration			{ }
1165 	//			// class_constructor_declaration is part of function_declaration
1166 	|	';'					{ }
1167 	;
1168 
1169 program_declaration:		// IEEE: program_declaration + program_nonansi_header + program_ansi_header:
1170 	//			// timeunits_delcarationE is instead in program_item
1171 		pgmFront importsAndParametersE portsStarE ';'
1172 			program_itemListE yENDPROGRAM endLabelE
1173 			{ PARSEP->endprogramCb($<fl>6,$6);
1174 			  PARSEP->symPopScope(VAstType::PROGRAM); }
1175 	|	yEXTERN	pgmFront importsAndParametersE portsStarE ';'
1176 			{ PARSEP->symPopScope(VAstType::PROGRAM); }
1177 	;
1178 
1179 pgmFront:
1180 		yPROGRAM lifetimeE idAny/*new_program*/
1181 			{ PARSEP->symPushNew(VAstType::PROGRAM,$3);
1182 			  PARSEP->programCb($<fl>1,$1, $3);
1183 			 }
1184 	;
1185 
1186 program_itemListE:		// ==IEEE: [{ program_item }]
1187 		/* empty */				{ }
1188 	|	program_itemList			{ }
1189 	;
1190 
1191 program_itemList:		// ==IEEE: { program_item }
1192 		program_item				{ }
1193 	|	program_itemList program_item		{ }
1194 	;
1195 
1196 program_item:			// ==IEEE: program_item
1197 		port_declaration ';'			{ }
1198 	|	non_port_program_item			{ }
1199 	;
1200 
1201 non_port_program_item:		// ==IEEE: non_port_program_item
1202 		continuous_assign			{ }
1203 	|	module_or_generate_item_declaration	{ }
1204 	|	initial_construct			{ }
1205 	|	final_construct				{ }
1206 	|	concurrent_assertion_item		{ }
1207 	|	timeunits_declaration			{ }
1208 	|	program_generate_item			{ }
1209 	;
1210 
1211 program_generate_item:		// ==IEEE: program_generate_item
1212 		loop_generate_construct			{ }
1213 	|	conditional_generate_construct		{ }
1214 	|	generate_region				{ }
1215 	|	elaboration_system_task			{ }
1216 	;
1217 
1218 extern_tf_declaration:		// ==IEEE: extern_tf_declaration
1219 		yEXTERN task_prototype ';'		{ }
1220 	|	yEXTERN function_prototype ';'		{ }
1221 	|	yEXTERN yFORKJOIN task_prototype ';'	{ }
1222 	;
1223 
1224 modport_declaration:		// ==IEEE: modport_declaration
1225 		yMODPORT modport_itemList ';'		{ }
1226 	;
1227 
1228 modport_itemList:		// IEEE: part of modport_declaration
1229 		modport_item				{ }
1230 	|	modport_itemList ',' modport_item	{ }
1231 	;
1232 
1233 modport_item:			// ==IEEE: modport_item
1234 		modport_idFront '(' {VARRESET_LIST("");} modportPortsDeclList ')'
1235 			{ VARRESET_NONLIST("");
1236 			  PARSEP->endmodportCb($<fl>1, "endmodport");
1237 			  PARSEP->symPopScope(VAstType::MODPORT); }
1238 	;
1239 
1240 modport_idFront:
1241 		id/*new-modport*/
1242 			{ PARSEP->symPushNew(VAstType::MODPORT,$1);
1243 			  PARSEP->modportCb($<fl>1,"modport",$1); }
1244 	;
1245 
1246 modportPortsDeclList:
1247 		modportPortsDecl			{ }
1248 	|	modportPortsDeclList ',' modportPortsDecl	{ }
1249 	;
1250 
1251 // IEEE: modport_ports_declaration  + modport_simple_ports_declaration
1252 //	+ (modport_tf_ports_declaration+import_export) + modport_clocking_declaration
1253 // We've expanded the lists each take to instead just have standalone ID ports.
1254 // We track the type as with the V2k series of defines, then create as each ID is seen.
1255 modportPortsDecl:
1256 	//			// IEEE: modport_simple_ports_declaration
1257 		port_direction modportSimplePort	{ }
1258 	//			// IEEE: modport_clocking_declaration
1259 	|	yCLOCKING idAny/*clocking_identifier*/	{ }
1260 	|	yIMPORT modport_tf_port			{ }
1261 	|	yEXPORT modport_tf_port			{ }
1262 	// Continuations of above after a comma.
1263 	//			// IEEE: modport_simple_ports_declaration
1264 	|	modportSimplePort			{ }
1265 	;
1266 
1267 modportSimplePort:		// IEEE: modport_simple_port or modport_tf_port, depending what keyword was earlier
1268 	//			// Note 'init' field is used to say what to connect to
1269 		id					{ VARDONE($<fl>1,$1,"",$1); PINNUMINC(); }
1270 	|	'.' idAny '(' ')'			{ VARDONE($<fl>1,$2,"",""); PINNUMINC(); }
1271 	|	'.' idAny '(' expr ')'			{ VARDONE($<fl>1,$2,"",$4); PINNUMINC(); }
1272 	;
1273 
1274 modport_tf_port:		// ==IEEE: modport_tf_port
1275 		id/*tf_identifier*/			{ }
1276 	|	method_prototype			{ }
1277 	;
1278 
1279 //************************************************
1280 // Variable Declarations
1281 
1282 genvar_declaration:		// ==IEEE: genvar_declaration
1283 		yGENVAR list_of_genvar_identifiers ';'	{ }
1284 	;
1285 
1286 list_of_genvar_identifiers:	// IEEE: list_of_genvar_identifiers (for declaration)
1287 		genvar_identifierDecl			{ }
1288 	|	list_of_genvar_identifiers ',' genvar_identifierDecl	{ }
1289 	;
1290 
1291 genvar_identifierDecl:		// IEEE: genvar_identifier (for declaration)
1292 		id/*new-genvar_identifier*/ sigAttrListE	{ VARRESET_NONLIST("genvar"); VARDONE($<fl>1, $1, "", ""); }
1293 	;
1294 
1295 local_parameter_declaration:	// IEEE: local_parameter_declaration
1296 	//			// See notes in parameter_declaration
1297 		local_parameter_declarationFront list_of_param_assignments	{ }
1298 	;
1299 
1300 parameter_declaration:		// IEEE: parameter_declaration
1301 	//			// IEEE: yPARAMETER yTYPE list_of_type_assignments ';'
1302 	//			// Instead of list_of_type_assignments
1303 	//			// we use list_of_param_assignments because for port handling
1304 	//			// it already must accept types, so simpler to have code only one place
1305 		parameter_declarationFront list_of_param_assignments	{ }
1306 	;
1307 
1308 local_parameter_declarationFront: // IEEE: local_parameter_declaration w/o assignment
1309 		varLParamReset implicit_typeE 		{ VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1310 	|	varLParamReset data_type		{ VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1311 	|	varLParamReset yTYPE			{ VARRESET(); VARDECL("localparam"); VARDTYPE($2); }
1312 	;
1313 
1314 parameter_declarationFront:	// IEEE: parameter_declaration w/o assignment
1315 		varGParamReset implicit_typeE 		{ VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1316 	|	varGParamReset data_type		{ VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1317 	|	varGParamReset yTYPE			{ VARRESET(); VARDECL("parameter"); VARDTYPE($2); }
1318 	;
1319 
1320 parameter_port_declarationFront: // IEEE: parameter_port_declaration w/o assignment
1321 	//			// IEEE: parameter_declaration (minus assignment)
1322 		parameter_declarationFront		{ }
1323 	|	local_parameter_declarationFront	{ /*NEED_S09(CURLINE(),"port localparams");*/ }
1324 	//
1325 	|	data_type				{ VARDTYPE($1); }
1326 	|	yTYPE 					{ VARDTYPE($1); }
1327 	;
1328 
1329 net_declaration:		// IEEE: net_declaration - excluding implict
1330 		net_declarationFront netSigList ';'	{ }
1331 	;
1332 
1333 net_declarationFront:		// IEEE: beginning of net_declaration
1334 		net_declRESET net_type strengthSpecE net_scalaredE net_dataType { VARDTYPE(SPACED($4,$5)); }
1335 	|	net_declRESET yINTERCONNECT signingE rangeListE { VARNET($2); VARDTYPE(SPACED($3,$4)); }
1336 	;
1337 
1338 net_declRESET:
1339 		/* empty */ 				{ VARRESET_NONLIST("net"); }
1340 	;
1341 
1342 net_scalaredE<str>:
1343 		/* empty */ 				{ $$=""; }
1344 	|	ySCALARED			 	{ $<fl>$=$<fl>1; $$=$1; }
1345 	|	yVECTORED				{ $<fl>$=$<fl>1; $$=$1; }
1346 	;
1347 
1348 net_dataType<str>:
1349 	//			// If there's a SV data type there shouldn't be a delay on this wire
1350 	//			// Otherwise #(...) can't be determined to be a delay or parameters
1351 	//			// Submit this as a footnote to the committee
1352 		var_data_type	 			{ $<fl>$=$<fl>1; $$=$1; }
1353 	|	signingE rangeList delayE 		{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1354 	|	signing delayE 				{ $<fl>$=$<fl>1; $$=$1; }
1355 	|	/*implicit*/ delayE 			{ $<fl>$=$<fl>1; $$=""; }
1356 	;
1357 
1358 net_type:			// ==IEEE: net_type
1359 		ySUPPLY0				{ VARNET($1); }
1360 	|	ySUPPLY1				{ VARNET($1); }
1361 	|	yTRI 					{ VARNET($1); }
1362 	|	yTRI0 					{ VARNET($1); }
1363 	|	yTRI1 					{ VARNET($1); }
1364 	|	yTRIAND 				{ VARNET($1); }
1365 	|	yTRIOR 					{ VARNET($1); }
1366 	|	yTRIREG 				{ VARNET($1); }
1367 	|	yWAND 					{ VARNET($1); }
1368 	|	yWIRE 					{ VARNET($1); }
1369 	|	yWOR 					{ VARNET($1); }
1370 	;
1371 
1372 varGParamReset:
1373 		yPARAMETER				{ VARRESET_NONLIST($1); }
1374 	;
1375 
1376 varLParamReset:
1377 		yLOCALPARAM				{ VARRESET_NONLIST($1); }
1378 	;
1379 
1380 port_direction:			// ==IEEE: port_direction + tf_port_direction
1381 	//			// IEEE 19.8 just "input" FIRST forces type to wire - we'll ignore that here
1382 		yINPUT					{ VARIO($1); }
1383 	|	yOUTPUT					{ VARIO($1); }
1384 	|	yINOUT					{ VARIO($1); }
1385 	|	yREF					{ VARIO($1); }
1386 	|	yCONST__REF yREF			{ VARIO($1); }
1387 	;
1388 
1389 port_directionReset:		// IEEE: port_direction that starts a port_declaraiton
1390 	//			// Used only for declarations outside the port list
1391 		yINPUT					{ VARRESET_NONLIST(""); VARIO($1); }
1392 	|	yOUTPUT					{ VARRESET_NONLIST(""); VARIO($1); }
1393 	|	yINOUT					{ VARRESET_NONLIST(""); VARIO($1); }
1394 	|	yREF					{ VARRESET_NONLIST(""); VARIO($1); }
1395 	|	yCONST__REF yREF			{ VARRESET_NONLIST(""); VARIO($1); }
1396 	;
1397 
1398 port_declaration:		// ==IEEE: port_declaration
1399 	//			// Used inside block; followed by ';'
1400 	//			// SIMILAR to tf_port_declaration
1401 	//
1402 	//			// IEEE: inout_declaration
1403 	//			// IEEE: input_declaration
1404 	//			// IEEE: output_declaration
1405 	//			// IEEE: ref_declaration
1406 		port_directionReset port_declNetE var_data_type       { VARDTYPE($3); } list_of_variable_decl_assignments	{ }
1407 	|	port_directionReset port_declNetE signingE rangeList  { VARDTYPE(SPACED($3,$4)); } list_of_variable_decl_assignments	{ }
1408 	|	port_directionReset port_declNetE signing	      { VARDTYPE($3); } list_of_variable_decl_assignments	{ }
1409 	|	port_directionReset port_declNetE /*implicit*/        { VARDTYPE("");/*default_nettype*/} list_of_variable_decl_assignments	{ }
1410 	//			// IEEE: interface_declaration
1411 	//			// Looks just like variable declaration unless has a period
1412 	//			// See etcInst
1413 	;
1414 
1415 tf_port_declaration:		// ==IEEE: tf_port_declaration
1416 	//			// Used inside function; followed by ';'
1417 	//			// SIMILAR to port_declaration
1418 	//
1419 		port_directionReset var_data_type	{ VARDTYPE($2); }  list_of_tf_variable_identifiers ';'	{ }
1420 	|	port_directionReset implicit_typeE	{ VARDTYPE($2); }  list_of_tf_variable_identifiers ';'	{ }
1421 	;
1422 
1423 integer_atom_type<str>:		// ==IEEE: integer_atom_type
1424 		yBYTE					{ $<fl>$=$<fl>1; $$=$1; }
1425 	|	ySHORTINT				{ $<fl>$=$<fl>1; $$=$1; }
1426 	|	yINT					{ $<fl>$=$<fl>1; $$=$1; }
1427 	|	yLONGINT				{ $<fl>$=$<fl>1; $$=$1; }
1428 	|	yINTEGER				{ $<fl>$=$<fl>1; $$=$1; }
1429 	|	yTIME					{ $<fl>$=$<fl>1; $$=$1; }
1430 	;
1431 
1432 integer_vector_type<str>:	// ==IEEE: integer_atom_type
1433 		yBIT					{ $<fl>$=$<fl>1; $$=$1; }
1434 	|	yLOGIC					{ $<fl>$=$<fl>1; $$=$1; }
1435 	|	yREG					{ $<fl>$=$<fl>1; $$=$1; }
1436 	;
1437 
1438 non_integer_type<str>:		// ==IEEE: non_integer_type
1439 		ySHORTREAL				{ $<fl>$=$<fl>1; $$=$1; }
1440 	|	yREAL					{ $<fl>$=$<fl>1; $$=$1; }
1441 	|	yREALTIME				{ $<fl>$=$<fl>1; $$=$1; }
1442 	;
1443 
1444 signingE<str>:			// IEEE: signing - plus empty
1445 		/*empty*/ 				{ $$=""; }
1446 	|	signing					{ $<fl>$=$<fl>1; $$=$1; }
1447 	;
1448 
1449 signing<str>:			// ==IEEE: signing
1450 		ySIGNED					{ $<fl>$=$<fl>1; $$=$1; }
1451 	|	yUNSIGNED				{ $<fl>$=$<fl>1; $$=$1; }
1452 	;
1453 
1454 //************************************************
1455 // Data Types
1456 
1457 casting_type<str>:		// IEEE: casting_type
1458 		simple_type				{ $<fl>$=$<fl>1; $$=$1; }
1459 	//			// IEEE: constant_primary
1460 	//			// In expr:cast this is expanded to just "expr"
1461 	//
1462 	//			// IEEE: signing
1463 	|	ySIGNED					{ $<fl>$=$<fl>1; $$=$1; }
1464 	|	yUNSIGNED				{ $<fl>$=$<fl>1; $$=$1; }
1465 	|	ySTRING					{ $<fl>$=$<fl>1; $$=$1; }
1466 	|	yCONST__ETC/*then `*/			{ $<fl>$=$<fl>1; $$=$1; }
1467 	;
1468 
1469 simple_type<str>:		// ==IEEE: simple_type
1470 	//			// IEEE: integer_type
1471 		integer_atom_type			{ $<fl>$=$<fl>1; $$=$1; }
1472 	|	integer_vector_type			{ $<fl>$=$<fl>1; $$=$1; }
1473 	|	non_integer_type			{ $<fl>$=$<fl>1; $$=$1; }
1474 	//			// IEEE: ps_type_identifier
1475 	//			// IEEE: ps_parameter_identifier (presumably a PARAMETER TYPE)
1476 	|	package_scopeIdFollowsE yaID__aTYPE	{ $<fl>$=$<fl>1; $$=$1+$2; }
1477 	//			// { generate_block_identifer ... } '.'
1478 	//			// Need to determine if generate_block_identifier can be lex-detected
1479 	;
1480 
1481 data_typeVar<str>:		// IEEE: data_type + virtual_interface_declaration
1482 		data_type				{ $<fl>$=$<fl>1; $$=$1; }
1483 	//			// IEEE-2009: virtual_interface_declaration
1484 	//			// IEEE-2012: part of data_type
1485 	|	yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ parameter_value_assignmentE '.' id/*modport*/
1486 			{ $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1487 	|	yVIRTUAL__anyID id/*interface*/ parameter_value_assignmentE '.' id/*modport*/
1488 			{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1489 	;
1490 
1491 data_type<str>:			// ==IEEE: data_type, excluding class_type etc references
1492 		integer_vector_type signingE rangeListE	{ $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1493 	|	integer_atom_type signingE		{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1494 	|	non_integer_type			{ $<fl>$=$<fl>1; $$=$1; }
1495 	|	ySTRUCT        packedSigningE '{' { PARSEP->symPushNewAnon(VAstType::STRUCT); }
1496 	/*cont*/	struct_union_memberList '}' packed_dimensionListE
1497 			{ $<fl>$=$<fl>1; $$=$1; PARSEP->symPopScope(VAstType::STRUCT); }
1498 	|	yUNION taggedE packedSigningE '{' { PARSEP->symPushNewAnon(VAstType::UNION); }
1499 	/*cont*/	struct_union_memberList '}' packed_dimensionListE
1500 			{ $<fl>$=$<fl>1; $$=$1; PARSEP->symPopScope(VAstType::UNION); }
1501 	|	enumDecl				{ $<fl>$=$<fl>1; $$=$1; }
1502 	|	ySTRING					{ $<fl>$=$<fl>1; $$=$1; }
1503 	|	yCHANDLE				{ $<fl>$=$<fl>1; $$=$1; }
1504 	//			// Rules overlap virtual_interface_declaration
1505 	//			// Parameters here are SV2009
1506 	//			// IEEE has ['.' modport] but that will conflict with port
1507 	//			// declarations which decode '.' modport themselves, so
1508 	//			// instead see data_typeVar
1509 	|	yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ parameter_value_assignmentE
1510  			{ $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1511 	|	yVIRTUAL__anyID                id/*interface*/ parameter_value_assignmentE
1512 			{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1513 	//
1514 	//			// IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
1515 	//			// See data_type
1516 	//			// IEEE: class_type
1517 	//			// See data_type
1518 	|	yEVENT					{ $<fl>$=$<fl>1; $$=$1; }
1519 	|	type_reference				{ $<fl>$=$<fl>1; $$=$1; }
1520 	//
1521 	//----------------------
1522 	//			// REFERENCES
1523 	//
1524 	//			// IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
1525 	//			// IEEE: class_type
1526 	//			// IEEE: ps_covergroup_identifier
1527 	//			// Don't distinguish between types and classes so all these combined
1528 	|	package_scopeIdFollowsE class_typeOneList packed_dimensionListE	{ $<fl>$=$<fl>1; $$=$<str>1+$<str>2+$3; }
1529 	;
1530 
1531 // IEEE: struct_union - not needed, expanded in data_type
1532 
1533 data_type_or_void<str>:		// ==IEEE: data_type_or_void
1534 		data_type				{ $<fl>$=$<fl>1; $$=$1; }
1535 	|	yVOID					{ $<fl>$=$<fl>1; $$=$1; }
1536 	;
1537 
1538 var_data_type<str>:		// ==IEEE: var_data_type
1539 		data_type				{ $<fl>$=$<fl>1; $$=$1; }
1540 	|	yVAR data_type				{ $<fl>$=$<fl>1; $$=$1; }
1541 	|	yVAR implicit_typeE			{ $<fl>$=$<fl>1; $$=$1; }
1542 	;
1543 
1544 type_reference<str>:		// ==IEEE: type_reference
1545 		yTYPE '(' exprOrDataType ')'		{ $<fl>$=$<fl>1; $$="type("+$3+")"; }
1546 	;
1547 
1548 struct_union_memberList:	// IEEE: { struct_union_member }
1549 		struct_union_member				{ }
1550 	|	struct_union_memberList struct_union_member	{ }
1551 	;
1552 
1553 struct_union_member:		// ==IEEE: struct_union_member
1554 		random_qualifierE data_type_or_void
1555 			{ VARS_PUSH(); // Structs can be recursive, or under a parameter typs
1556 			  VARRESET_NONLIST("member"); VARDTYPE(SPACED($1,$2)); }
1557 	/*cont*/	list_of_variable_decl_assignments ';'
1558 			{ VARS_POP(); }
1559 	;
1560 
1561 list_of_variable_decl_assignments:	// ==IEEE: list_of_variable_decl_assignments
1562 		variable_decl_assignment			{ }
1563 	|	list_of_variable_decl_assignments ',' variable_decl_assignment	{ }
1564 	;
1565 
1566 variable_decl_assignment:	// ==IEEE: variable_decl_assignment
1567 		id variable_dimensionListE sigAttrListE
1568 			{ VARDONE($<fl>1, $1, $2, ""); }
1569 	|	id variable_dimensionListE sigAttrListE '=' variable_declExpr
1570 			{ VARDONE($<fl>1, $1, $2, $5); }
1571 	|	idSVKwd					{ }
1572 	//
1573 	//			// IEEE: "dynamic_array_variable_identifier '[' ']' [ '=' dynamic_array_new ]"
1574 	//			// Matches above with variable_dimensionE = "[]"
1575 	//			// IEEE: "class_variable_identifier [ '=' class_new ]"
1576 	//			// variable_dimensionE must be empty
1577 	//			// Pushed into variable_declExpr:dynamic_array_new
1578 	//
1579 	//			// IEEE: "[ covergroup_variable_identifier ] '=' class_new
1580 	//			// Pushed into variable_declExpr:class_new
1581 	|	'=' class_new				{ }
1582 	;
1583 
1584 list_of_tf_variable_identifiers: // ==IEEE: list_of_tf_variable_identifiers
1585 		tf_variable_identifier			{ }
1586 	|	list_of_tf_variable_identifiers ',' tf_variable_identifier	{ }
1587 	;
1588 
1589 tf_variable_identifier:		// IEEE: part of list_of_tf_variable_identifiers
1590 		id variable_dimensionListE sigAttrListE
1591 			{ VARDONE($<fl>1, $1, $2, ""); }
1592 	|	id variable_dimensionListE sigAttrListE '=' expr
1593 			{ VARDONE($<fl>1, $1, $2, $5); }
1594 	;
1595 
1596 variable_declExpr<str>:		// IEEE: part of variable_decl_assignment - rhs of expr
1597 		expr					{ $<fl>$=$<fl>1; $$=$1; }
1598 	|	dynamic_array_new			{ $<fl>$=$<fl>1; $$=$1; }
1599 	|	class_new				{ $<fl>$=$<fl>1; $$=$1; }
1600 	;
1601 
1602 variable_dimensionListE<str>:	// IEEE: variable_dimension + empty
1603 		/*empty*/				{ $$=""; }
1604 	|	variable_dimensionList			{ $<fl>$=$<fl>1; $$=$1; }
1605 	;
1606 
1607 variable_dimensionList<str>:	// IEEE: variable_dimension + empty
1608 		variable_dimension			{ $<fl>$=$<fl>1; $$=$1; }
1609 	|	variable_dimensionList variable_dimension	{ $<fl>$=$<fl>1; $$=$1+$2; }
1610 	;
1611 
1612 variable_dimension<str>:	// ==IEEE: variable_dimension
1613 	//			// IEEE: unsized_dimension
1614 		'[' ']'					{ $<fl>$=$<fl>1; $$=""; }
1615 	//			// IEEE: unpacked_dimension
1616 	|	anyrange				{ $<fl>$=$<fl>1; $$=$1; }
1617 	//			// IEEE: unpacked_dimension (if const_expr)
1618 	//			// IEEE: associative_dimension (if data_type)
1619 	//			// Can't tell which until see if expr is data type or not
1620 	|	'[' exprOrDataType ']'			{ $<fl>$=$<fl>1; $$="["+$2+"]"; }
1621 	|	yP_BRASTAR ']'				{ $<fl>$=$<fl>1; $$="[*]"; }
1622 	|	'[' '*' ']'				{ $<fl>$=$<fl>1; $$="[*]"; }
1623 	//			// IEEE: queue_dimension
1624 	//			// '[' '$' ']' -- $ is part of expr
1625 	//			// '[' '$' ':' expr ']' -- anyrange:expr:$
1626 	;
1627 
1628 random_qualifierE<str>:		// IEEE: random_qualifier + empty
1629 		/*empty*/				{ $$=""; }
1630 	|	random_qualifier			{ $<fl>$=$<fl>1; $$=$1; }
1631 	;
1632 
1633 random_qualifier<str>:		// ==IEEE: random_qualifier
1634 		yRAND					{ $<fl>$=$<fl>1; $$=$1; }
1635 	|	yRANDC					{ $<fl>$=$<fl>1; $$=$1; }
1636 	;
1637 
1638 taggedE:
1639 		/*empty*/				{ }
1640 	|	yTAGGED					{ }
1641 	;
1642 
1643 packedSigningE:
1644 		/*empty*/				{ }
1645 	|	yPACKED signingE			{ }
1646 	;
1647 
1648 //************************************************
1649 // enum
1650 
1651 // IEEE: part of data_type
1652 enumDecl<str>:
1653 		yENUM enum_base_typeE '{' enum_nameList '}' rangeListE { $$=$2; }
1654 	;
1655 
1656 enum_base_typeE<str>:	// IEEE: enum_base_type
1657 		/* empty */				{ $$="enum"; }
1658 	//			// Not in spec, but obviously "enum [1:0]" should work
1659 	//			// implicit_type expanded, without empty
1660 	|	signingE rangeList			{ $<fl>$=$<fl>1; $$=$1+$2; }
1661 	|	signing					{ $<fl>$=$<fl>1; $$=$1; }
1662 	//
1663 	|	integer_atom_type signingE		{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1664 	|	integer_vector_type signingE regrangeE	{ $<fl>$=$<fl>1; $$=SPACED($1,SPACED($2,$3)); }
1665 	//			// below can be idAny or yaID__aTYPE
1666 	//			// IEEE requires a type, though no shift conflict if idAny
1667 	//			// IEEE: type_identifier [ packed_dimension ]
1668 	//			// however other simulators allow [ class_scope | package_scope ] type_identifier
1669 	|	idAny regrangeE			{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
1670 	|	package_scopeIdFollows idAny rangeListE
1671 			{ $<fl>$=$<fl>1; $$ = $<str>1+$<str>2+$3; }
1672 	;
1673 
1674 enum_nameList:
1675 		enum_name_declaration			{ }
1676 	|	enum_nameList ',' enum_name_declaration	{ }
1677 	;
1678 
1679 enum_name_declaration:		// ==IEEE: enum_name_declaration
1680 		idAny/*enum_identifier*/ enumNameRangeE enumNameStartE	{ }
1681 	;
1682 
1683 enumNameRangeE:			// IEEE: second part of enum_name_declaration
1684 		/* empty */				{ }
1685 	|	'[' intnumAsConst ']'			{ }
1686 	|	'[' intnumAsConst ':' intnumAsConst ']'	{ }
1687 	;
1688 
1689 enumNameStartE:			// IEEE: third part of enum_name_declaration
1690 		/* empty */				{ }
1691 	|	'=' constExpr				{ }
1692 	;
1693 
1694 intnumAsConst:
1695 		yaINTNUM				{ }
1696 	;
1697 
1698 //************************************************
1699 // Typedef
1700 
1701 data_declaration:		// ==IEEE: data_declaration
1702 	//			// VARRESET can't be called here - conflicts
1703 		data_declarationVar			{ }
1704 	|	type_declaration			{ }
1705 	|	package_import_declaration		{ }
1706 	//			// IEEE 2005: virtual_interface_declaration
1707 	//			// IEEE 2009 removed this
1708 	//			// "yVIRTUAL yID yID" looks just like a data_declaration
1709 	//			// Therefore the virtual_interface_declaration term isn't used
1710 	//			// 1800-2009:
1711 	|	net_type_declaration			{ }
1712 	;
1713 
1714 class_property:			// ==IEEE: class_property, which is {property_qualifier} data_declaration
1715 		memberQualResetListE data_declarationVarClass		{ }
1716 	|	memberQualResetListE type_declaration			{ }
1717 	|	memberQualResetListE package_import_declaration	{ }
1718 	//			// IEEE: virtual_interface_declaration
1719 	//			// "yVIRTUAL yID yID" looks just like a data_declaration
1720 	//			// Therefore the virtual_interface_declaration term isn't used
1721 	;
1722 
1723 data_declarationVar:		// IEEE: part of data_declaration
1724 	//			// The first declaration has complications between assuming what's the type vs ID declaring
1725 		data_declarationVarFront list_of_variable_decl_assignments ';'	{ }
1726 	;
1727 
1728 data_declarationVarClass:	// IEEE: part of data_declaration (for class_property)
1729 	//			// The first declaration has complications between assuming what's the type vs ID declaring
1730 		data_declarationVarFrontClass list_of_variable_decl_assignments ';'	{ }
1731 	;
1732 
1733 data_declarationVarFront:	// IEEE: part of data_declaration
1734 	//			// implicit_type expanded into /*empty*/ or "signingE rangeList"
1735 		constE yVAR lifetimeE data_type	 { VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,$4)); }
1736 	|	constE yVAR lifetimeE		 { VARRESET(); VARDECL("var"); VARDTYPE($1); }
1737 	|	constE yVAR lifetimeE signingE rangeList { VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,SPACED($4,$5))); }
1738 	//
1739 	//			// Expanded: "constE lifetimeE data_type"
1740 	|	/**/		      data_typeVar	{ VARRESET(); VARDECL("var"); VARDTYPE($1); }
1741 	|	/**/	    lifetime  data_typeVar	{ VARRESET(); VARDECL("var"); VARDTYPE($2); }
1742 	|	yCONST__ETC lifetimeE data_typeVar	{ VARRESET(); VARDECL("var"); VARDTYPE(SPACED($1,$3)); }
1743 	//			// = class_new is in variable_decl_assignment
1744 	//
1745 	//			// IEEE: virtual_interface_declaration
1746 	//			// data_type includes VIRTUAL_INTERFACE, so added to data_typeVar
1747 	;
1748 
1749 data_declarationVarFrontClass:	// IEEE: part of data_declaration (for class_property)
1750 	//			// VARRESET called before this rule
1751 	//			// yCONST is removed, added to memberQual rules
1752 	//			// implicit_type expanded into /*empty*/ or "signingE rangeList"
1753 		yVAR lifetimeE data_type	 { VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, $3)); }
1754 	|	yVAR lifetimeE			 { VARDECL("var"); VARDTYPE(GRAMMARP->m_var.m_dtype); }
1755 	|	yVAR lifetimeE signingE rangeList { VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, SPACED($3, $4))); }
1756 	//
1757 	//			// Expanded: "constE lifetimeE data_type"
1758 	|	/**/		      data_typeVar	{ VARDECL("var"); VARDTYPE(SPACED(GRAMMARP->m_var.m_dtype, $1)); }
1759 	//			// lifetime is removed, added to memberQual rules to avoid conflict
1760 	//			// yCONST is removed, added to memberQual rules to avoid conflict
1761 	//			// = class_new is in variable_decl_assignment
1762 	;
1763 
1764 net_type_declaration:		// IEEE: net_type_declaration
1765 		yNETTYPE data_type idAny/*net_type_identifier*/ ';'
1766 							{ PARSEP->syms().replaceInsert(VAstType::TYPE, $3); }
1767 	//			// package_scope part of data_type
1768 	|	yNETTYPE data_type idAny yWITH__ETC package_scopeIdFollowsE id/*tf_identifier*/ ';'
1769 							{ PARSEP->syms().replaceInsert(VAstType::TYPE, $3); }
1770 	|	yNETTYPE package_scopeIdFollowsE id/*net_type_identifier*/ idAny/*net_type_identifier*/ ';'
1771 							{ PARSEP->syms().replaceInsert(VAstType::TYPE, $4); }
1772 	;
1773 
1774 constE<str>:			// IEEE: part of data_declaration
1775 		/* empty */				{ $$ = ""; }
1776 	|	yCONST__ETC				{ $$ = $1; }
1777 	;
1778 
1779 implicit_typeE<str>:		// IEEE: part of *data_type_or_implicit
1780 	//			// Also expanded in data_declaration
1781 		/* empty */				{ $$ = ""; }
1782 	|	signingE rangeList			{ $$ = SPACED($1,$2); }
1783 	|	signing					{ $$ = $1; }
1784 	;
1785 
1786 assertion_variable_declaration: // IEEE: assertion_variable_declaration
1787 	//			// IEEE: var_data_type expanded
1788 		var_data_type list_of_variable_decl_assignments ';'	{ }
1789 	;
1790 
1791 type_declaration:		// ==IEEE: type_declaration
1792 	//			// Use idAny, as we can redeclare a typedef on an existing typedef
1793 		yTYPEDEF data_type idAny variable_dimensionListE ';'
1794 			{ VARDONETYPEDEF($<fl>1,$3,$2,$4); }
1795 	|	yTYPEDEF id/*interface*/ bit_selectE '.' idAny/*type*/ idAny/*type*/ ';'
1796 			{ VARDONETYPEDEF($<fl>1,$6,$2+$3+"."+$5,""); }
1797 	//			// Combines into above "data_type id" rule
1798 	|	yTYPEDEF id ';'				{ VARDONETYPEDEF($<fl>1,$2,"",""); }
1799 	|	yTYPEDEF yENUM idAny ';'		{ PARSEP->syms().replaceInsert(VAstType::ENUM, $3); }
1800 	|	yTYPEDEF ySTRUCT idAny ';'		{ PARSEP->syms().replaceInsert(VAstType::STRUCT, $3); }
1801 	|	yTYPEDEF yUNION idAny ';'		{ PARSEP->syms().replaceInsert(VAstType::UNION, $3); }
1802 	|	yTYPEDEF yCLASS idAny ';'		{ PARSEP->syms().replaceInsert(VAstType::CLASS, $3); }
1803 	|	yTYPEDEF yINTERFACE yCLASS idAny ';'	{ PARSEP->syms().replaceInsert(VAstType::CLASS, $3); }
1804 	;
1805 
1806 //************************************************
1807 // Module Items
1808 
1809 module_itemListE:		// IEEE: Part of module_declaration
1810 		/* empty */				{ }
1811 	|	module_itemList				{ }
1812 	;
1813 
1814 module_itemList:		// IEEE: Part of module_declaration
1815 		module_item				{ }
1816 	|	module_itemList module_item		{ }
1817 	;
1818 
1819 module_item:			// ==IEEE: module_item
1820 		port_declaration ';'			{ }
1821 	|	non_port_module_item			{ }
1822 	;
1823 
1824 non_port_module_item:		// ==IEEE: non_port_module_item
1825 		generate_region				{ }
1826 	|	module_or_generate_item			{ }
1827 	|	specify_block				{ }
1828 	|	specparam_declaration			{ }
1829 	|	program_declaration			{ }
1830 	|	module_declaration			{ }
1831 	|	interface_declaration			{ }
1832 	|	timeunits_declaration			{ }
1833 	;
1834 
1835 module_or_generate_item:	// ==IEEE: module_or_generate_item
1836 	//			// IEEE: parameter_override
1837 		yDEFPARAM list_of_defparam_assignments ';'	{ }
1838 	//			// IEEE: gate_instantiation + udp_instantiation + module_instantiation
1839 	//			// not here, see etcInst in module_common_item
1840 	//			// We joined udp & module definitions, so this goes here
1841 	|	combinational_body			{ }
1842 	//			// This module_common_item shared with interface_or_generate_item:module_common_item
1843 	|	module_common_item			{ }
1844 	;
1845 
1846 module_common_item:		// ==IEEE: module_common_item
1847 		module_or_generate_item_declaration	{ }
1848 	//			// IEEE: interface_instantiation
1849 	//			// + IEEE: program_instantiation
1850 	//			// + module_instantiation from module_or_generate_item
1851 	|	etcInst					{ }
1852 	|	assertion_item				{ }
1853 	|	bind_directive				{ }
1854 	|	continuous_assign			{ }
1855 	//			// IEEE: net_alias
1856 	|	yALIAS variable_lvalue aliasEqList ';'	{ }
1857 	|	initial_construct			{ }
1858 	|	final_construct				{ }
1859 	//			// IEEE: always_construct
1860 	|	yALWAYS stmtBlock			{ }
1861 	|	loop_generate_construct			{ }
1862 	|	conditional_generate_construct		{ }
1863 	|	elaboration_system_task			{ }
1864 	//
1865 	|	error ';'				{ }
1866 	;
1867 
1868 continuous_assign:		// IEEE: continuous_assign
1869 		yASSIGN strengthSpecE delayE assignList ';'	{ }
1870 	;
1871 
1872 initial_construct:		// IEEE: initial_construct
1873 		yINITIAL stmtBlock			{ }
1874 	;
1875 
1876 final_construct:		// IEEE: final_construct
1877 		yFINAL stmtBlock			{ }
1878 	;
1879 
1880 module_or_generate_item_declaration:	// ==IEEE: module_or_generate_item_declaration
1881 		package_or_generate_item_declaration	{ }
1882 	| 	genvar_declaration			{ }
1883 	|	clocking_declaration			{ }
1884 	|	yDEFAULT yCLOCKING idAny/*new-clocking_identifier*/ ';'	{ }
1885 	|	yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';'	{ }
1886 	;
1887 
1888 aliasEqList:			// IEEE: part of net_alias
1889 		'=' variable_lvalue			{ }
1890 	|	aliasEqList '=' variable_lvalue		{ }
1891 	;
1892 
1893 bind_directive:			// ==IEEE: bind_directive + bind_target_scope
1894 	//			// ';' - Note IEEE grammar is wrong, includes extra ';' - it's already in module_instantiation
1895 	//			// We merged the rules - id may be a bind_target_instance or module_identifier or interface_identifier
1896 		yBIND bind_target_instance bind_instantiation	{ }
1897 	|	yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation	{ }
1898 	;
1899 
1900 bind_target_instance_list:	// ==IEEE: bind_target_instance_list
1901 		bind_target_instance			{ }
1902 	|	bind_target_instance_list ',' bind_target_instance	{ }
1903 	;
1904 
1905 bind_target_instance:		// ==IEEE: bind_target_instance
1906 		hierarchical_identifierBit		{ }
1907 	;
1908 
1909 bind_instantiation:		// ==IEEE: bind_instantiation
1910 	//			// IEEE: program_instantiation
1911 	//			// IEEE: + module_instantiation
1912 	//			// IEEE: + interface_instantiation
1913 		etcInst					{ }
1914 	;
1915 
1916 //************************************************
1917 // Generates
1918 //
1919 // Way down in generate_item is speced a difference between module,
1920 // interface and checker generates.  modules and interfaces are almost
1921 // identical (minus DEFPARAMs) so we overlap them.  Checkers are too
1922 // different, so we copy all rules for checkers.
1923 
1924 generate_region:		// ==IEEE: generate_region
1925 		yGENERATE ~c~genItemList yENDGENERATE	{ }
1926 	|	yGENERATE yENDGENERATE			{ }
1927 	;
1928 
1929 c_generate_region:		// IEEE: generate_region (for checkers)
1930 		BISONPRE_COPY(generate_region,{s/~c~/c_/g})	// {copied}
1931 	;
1932 
1933 generate_block:			// IEEE: generate_block
1934 	//			// Either a single item, or a begin-end block
1935 		~c~generate_item			{ }
1936 	|	~c~genItemBegin				{ }
1937 	;
1938 
1939 c_generate_block:		// IEEE: generate_block (for checkers)
1940 		BISONPRE_COPY(generate_block,{s/~c~/c_/g})	// {copied}
1941 	;
1942 
1943 genItemBegin:			// IEEE: part of generate_block
1944 		yBEGIN ~c~genItemList yEND		{ }
1945 	|	yBEGIN yEND				{ }
1946 	|	id ':' yBEGIN ~c~genItemList yEND endLabelE	{ }
1947 	|	id ':' yBEGIN                yEND endLabelE	{ }
1948 	|	yBEGIN ':' idAny ~c~genItemList yEND endLabelE	{ }
1949 	|	yBEGIN ':' idAny                yEND endLabelE	{ }
1950 	;
1951 
1952 c_genItemBegin:			// IEEE: part of generate_block (for checkers)
1953 		BISONPRE_COPY(genItemBegin,{s/~c~/c_/g})		// {copied}
1954 	;
1955 
1956 genItemOrBegin:			// Not in IEEE, but our begin isn't under generate_item
1957 		~c~generate_item			{ }
1958 	|	~c~genItemBegin				{ }
1959 	;
1960 
1961 c_genItemOrBegin:		// (for checkers)
1962 		BISONPRE_COPY(genItemOrBegin,{s/~c~/c_/g})	// {copied}
1963 	;
1964 
1965 genItemList:
1966 		~c~genItemOrBegin			{ }
1967 	|	~c~genItemList ~c~genItemOrBegin	{ }
1968 	;
1969 
1970 c_genItemList:			// (for checkers)
1971 		BISONPRE_COPY(genItemList,{s/~c~/c_/g})		// {copied}
1972 	;
1973 
1974 generate_item:			// IEEE: module_or_interface_or_generate_item
1975 	//			// Only legal when in a generate under a module (or interface under a module)
1976 		module_or_generate_item			{ }
1977 	//			// Only legal when in a generate under an interface
1978 	|	interface_or_generate_item		{ }
1979 	//			// IEEE: checker_or_generate_item
1980 	//			// Only legal when in a generate under a checker
1981 	//			// so below in c_generate_item
1982 	;
1983 
1984 c_generate_item:			// IEEE: generate_item (for checkers)
1985 		checker_or_generate_item		{ }
1986 	;
1987 
1988 conditional_generate_construct:	// ==IEEE: conditional_generate_construct
1989 	//			// IEEE: case_generate_construct
1990 		yCASE  '(' expr ')' yENDCASE	{ }
1991 	|	yCASE  '(' expr ')' ~c~case_generate_itemList yENDCASE	{ }
1992 	//			// IEEE: if_generate_construct
1993 	|	yIF '(' expr ')' ~c~generate_block	%prec prLOWER_THAN_ELSE	{ }
1994 	|	yIF '(' expr ')' ~c~generate_block yELSE ~c~generate_block	{ }
1995 	;
1996 
1997 c_conditional_generate_construct:	// IEEE: conditional_generate_construct (for checkers)
1998 		BISONPRE_COPY(conditional_generate_construct,{s/~c~/c_/g})	// {copied}
1999 	;
2000 
2001 loop_generate_construct:	// ==IEEE: loop_generate_construct
2002 		yFOR '(' genvar_initialization ';' expr ';' genvar_iteration ')' ~c~generate_block
2003 			{ }
2004 	;
2005 
2006 c_loop_generate_construct:	// IEEE: loop_generate_construct (for checkers)
2007 		BISONPRE_COPY(loop_generate_construct,{s/~c~/c_/g})	// {copied}
2008 	;
2009 
2010 genvar_initialization:		// ==IEEE: genvar_initalization
2011 	        id '=' constExpr			{ }
2012 	|	yGENVAR genvar_identifierDecl '=' constExpr	{ }
2013 	;
2014 
2015 genvar_iteration:		// ==IEEE: genvar_iteration
2016 	//			// IEEE: assignment_operator plus IDs
2017 	|	id '=' 		expr			{ }
2018 	|	id yP_PLUSEQ	expr			{ }
2019 	|	id yP_MINUSEQ	expr			{ }
2020 	|	id yP_TIMESEQ	expr			{ }
2021 	|	id yP_DIVEQ	expr			{ }
2022 	|	id yP_MODEQ	expr			{ }
2023 	|	id yP_ANDEQ	expr			{ }
2024 	|	id yP_OREQ	expr			{ }
2025 	|	id yP_XOREQ	expr			{ }
2026 	|	id yP_SLEFTEQ	expr			{ }
2027 	|	id yP_SRIGHTEQ	expr			{ }
2028 	|	id yP_SSRIGHTEQ	expr			{ }
2029 	//			// inc_or_dec_operator
2030 	|	yP_PLUSPLUS id				{ }
2031 	|	yP_MINUSMINUS id			{ }
2032 	|	id yP_PLUSPLUS				{ }
2033 	|	id yP_MINUSMINUS			{ }
2034 	;
2035 
2036 case_generate_itemList:		// IEEE: { case_generate_item }
2037 		~c~case_generate_item			{ }
2038 	|	~c~case_generate_itemList ~c~case_generate_item	{ }
2039 	;
2040 
2041 c_case_generate_itemList:	// IEEE: { case_generate_item } (for checkers)
2042 		BISONPRE_COPY(case_generate_itemList,{s/~c~/c_/g})	// {copied}
2043 	;
2044 
2045 case_generate_item:		// ==IEEE: case_generate_item
2046 		caseCondList ':' ~c~generate_block	{ }
2047 	|	yDEFAULT ':' ~c~generate_block		{ }
2048 	|	yDEFAULT ~c~generate_block		{ }
2049 	;
2050 
2051 c_case_generate_item:		// IEEE: case_generate_item (for checkers)
2052 		BISONPRE_COPY(case_generate_item,{s/~c~/c_/g})	// {copied}
2053 	;
2054 
2055 //************************************************
2056 // Assignments and register declarations
2057 
2058 assignList:
2059 		assignOne				{ }
2060 	|	assignList ',' assignOne		{ }
2061 	;
2062 
2063 assignOne:
2064 		variable_lvalue '=' expr		{ PARSEP->contassignCb($<fl>2,"assign",$1,$3); }
2065 	;
2066 
2067 delay_or_event_controlE:			// IEEE: delay_or_event_control plus empty
2068 		/* empty */				{ }
2069 	|	delay_control				{ } /* ignored */
2070 	|	event_control				{ } /* ignored */
2071 	|	yREPEAT '(' expr ')' event_control	{ } /* ignored */
2072 	;
2073 
2074 delayE:
2075 		/* empty */				{ }
2076 	|	delay_control				{ } /* ignored */
2077 	;
2078 
2079 delay_control:			// ==IEEE: delay_control
2080 		'#' delay_value				{ } /* ignored */
2081 	|	'#' '(' minTypMax ')'			{ } /* ignored */
2082 	|	'#' '(' minTypMax ',' minTypMax ')'		{ } /* ignored */
2083 	|	'#' '(' minTypMax ',' minTypMax ',' minTypMax ')'	{ } /* ignored */
2084 	;
2085 
2086 delay_value:			// ==IEEE:delay_value
2087 	//			// IEEE: ps_identifier
2088 		ps_id_etc	 			{ }
2089 	|	yaINTNUM 				{ }
2090 	|	yaFLOATNUM 				{ }
2091 	|	yaTIMENUM 				{ }
2092 	;
2093 
2094 delayExpr:
2095 		expr					{ }
2096 	;
2097 
2098 minTypMax:			// IEEE: mintypmax_expression and constant_mintypmax_expression
2099 		delayExpr				{ }
2100 	|	delayExpr ':' delayExpr ':' delayExpr	{ }
2101 	;
2102 
2103 netSigList:			// IEEE: list_of_port_identifiers
2104 		netSig  				{ }
2105 	|	netSigList ',' netSig		       	{ }
2106 	;
2107 
2108 netSig:				// IEEE: net_decl_assignment -  one element from list_of_port_identifiers
2109 		netId sigAttrListE			{ VARDONE($<fl>1, $1, "", ""); }
2110 	|	netId sigAttrListE '=' expr		{ VARDONE($<fl>1, $1, "", $4); }
2111 	|	netId variable_dimensionList sigAttrListE	{ VARDONE($<fl>1, $1, $2, ""); }
2112 	;
2113 
2114 netId<str>:
2115 		id/*new-net*/				{ $<fl>$=$<fl>1; $$=$1; }
2116 	|	idSVKwd					{ $<fl>$=$<fl>1; $$=$1; }
2117 	;
2118 
2119 sigAttrListE:
2120 		/* empty */				{ }
2121 	;
2122 
2123 rangeListE<str>:		// IEEE: [{packed_dimension}]
2124 		/* empty */				{ $$=""; }
2125 	|	rangeList				{ $<fl>$=$<fl>1; $$ = $1; }
2126 	;
2127 
2128 rangeList<str>:			// IEEE: {packed_dimension}
2129 		anyrange				{ $<fl>$=$<fl>1; $$ = $1; }
2130 	|	rangeList anyrange			{ $<fl>$=$<fl>1; $$ = $1+$2; }
2131 	;
2132 
2133 regrangeE<str>:
2134 		/* empty */    		               	{ $$=""; }
2135 	|	anyrange 				{ $<fl>$=$<fl>1; $$=$1; }
2136 	;
2137 
2138 bit_selectE<str>:		// IEEE: constant_bit_select (IEEE included empty)
2139 		/* empty */				{ $$ = ""; }
2140 	|	'[' constExpr ']'			{ $<fl>$=$<fl>1; $$ = "["+$2+"]"; }
2141 	;
2142 
2143 // IEEE: select
2144 // Merged into more general idArray
2145 
2146 anyrange<str>:
2147 		'[' constExpr ':' constExpr ']'		{ $<fl>$=$<fl>1; $$ = "["+$2+":"+$4+"]"; }
2148 	;
2149 
2150 packed_dimensionListE<str>:	// IEEE: [{ packed_dimension }]
2151 		/* empty */				{ $$=""; }
2152 	|	packed_dimensionList			{ $<fl>$=$<fl>1; $$=$1; }
2153 	;
2154 
2155 packed_dimensionList<str>:	// IEEE: { packed_dimension }
2156 		packed_dimension			{ $<fl>$=$<fl>1; $$=$1; }
2157 	|	packed_dimensionList packed_dimension	{ $<fl>$=$<fl>1; $$=$1+$2; }
2158 	;
2159 
2160 packed_dimension<str>:		// ==IEEE: packed_dimension
2161 		anyrange				{ $<fl>$=$<fl>1; $$=$1; }
2162 	|	'[' ']'					{ $$="[]"; }
2163 	;
2164 
2165 //************************************************
2166 // Parameters
2167 
2168 param_assignment:		// ==IEEE: param_assignment
2169 	//			// IEEE: constant_param_expression
2170 	//			// param_expression: '$' is in expr
2171 		id/*new-parameter*/ variable_dimensionListE sigAttrListE '=' exprOrDataTypeOrMinTypMax
2172 			{ $<fl>$=$<fl>1; VARDONE($<fl>1, $1, $2, $5); }
2173 	//			// only legal in port list; throws error if not set
2174 	|	id/*new-parameter*/ variable_dimensionListE sigAttrListE
2175 			{ $<fl>$=$<fl>1; VARDONE($<fl>1, $1, $2, ""); NEED_S09($<fl>1,"optional parameter defaults"); }
2176 	;
2177 
2178 list_of_param_assignments:	// ==IEEE: list_of_param_assignments
2179 		param_assignment			{ }
2180 	|	list_of_param_assignments ',' param_assignment	{ }
2181 	;
2182 
2183 list_of_defparam_assignments:	// ==IEEE: list_of_defparam_assignments
2184 		defparam_assignment			{ }
2185 	|	list_of_defparam_assignments ',' defparam_assignment	{ }
2186 	;
2187 
2188 defparam_assignment:		// ==IEEE: defparam_assignment
2189 		hierarchical_identifier/*parameter*/ '=' expr	{ PARSEP->defparamCb($<fl>2,"defparam",$1,$3); }
2190 	;
2191 
2192 //************************************************
2193 // Instances
2194 // We don't know identifier types, so this matches all module,udp,etc instantiation
2195 //   module_id      [#(params)]   name  (pins) [, name ...] ;	// module_instantiation
2196 //   gate (strong0) [#(delay)]   [name] (pins) [, (pins)...] ;	// gate_instantiation
2197 //   program_id     [#(params}]   name ;			// program_instantiation
2198 //   interface_id   [#(params}]   name ;			// interface_instantiation
2199 //   checker_id			  name  (pins) ;		// checker_instantiation
2200 
2201 etcInst:			// IEEE: module_instantiation + gate_instantiation + udp_instantiation
2202 		instName { INSTPREP($1,1,0); } strengthSpecE parameter_value_assignmentE { INSTPREP($1,0,1); } instnameList ';'
2203 			{ INSTDONE(); }
2204 	//			// IEEE: interface_identifier' .' modport_identifier list_of_interface_identifiers
2205 	|	instName { INSTPREP($1,1,0); } '.' id {INSTPREP($1,0,0);} mpInstnameList ';'
2206 			{ INSTDONE(); }
2207 	;
2208 
2209 instName<str>:
2210 		gateKwd					{ $<fl>$=$<fl>1; $$=$1; }
2211 	//			// id is-a: interface_identifier
2212 	//			//       or program_identifier
2213 	//			//       or udp_identifier
2214 	//			//       or module_identifier
2215 	|	id					{ $<fl>$=$<fl>1; $$=$1; }
2216 	;
2217 
2218 mpInstnameList:			// Similar to instnameList, but for modport instantiations which have no parenthesis
2219 		mpInstnameParen				{ }
2220 	|	mpInstnameList ',' mpInstnameParen	{ }
2221 	;
2222 
2223 mpInstnameParen:		// Similar to instnameParen, but for modport instantiations which have no parenthesis
2224 		mpInstname				{ PARSEP->endcellCb($<fl>1,""); }
2225 	;
2226 
2227 mpInstname:			// Similar to instname, but for modport instantiations which have no parenthesis
2228 	//			// id is-a: interface_port_identifier   (interface.modport)
2229 		id instRangeListE			{ PARSEP->instantCb($<fl>1, GRAMMARP->m_cellMod, $1, $2); }
2230 	;
2231 
2232 instnameList:
2233 		instnameParen				{ }
2234 	|	instnameList ',' instnameParen		{ }
2235 	;
2236 
2237 instnameParen:
2238 		instname cellpinList ')'		{ PARSEP->endcellCb($<fl>3,""); }
2239 	;
2240 
2241 instname:
2242 	//			// id is-a: hierarchical_instance (interface)
2243 	//			// 	 or instance_identifier   (module)
2244 	//			// 	 or instance_identifier   (program)
2245 	//			// 	 or udp_instance	  (udp)
2246 		id instRangeListE '(' 			{ PARSEP->instantCb($<fl>1, GRAMMARP->m_cellMod, $1, $2); PINPARAMS(); }
2247 	|	instRangeListE '(' 			{ PARSEP->instantCb($<fl>2, GRAMMARP->m_cellMod, "", $1); PINPARAMS(); } // UDP
2248 	;
2249 
2250 instRangeListE<str>:
2251 		/* empty */				{ $$ = ""; }
2252 	|	instRangeList				{ $<fl>$=$<fl>1; $$ = $1; }
2253 	;
2254 
2255 instRangeList<str>:
2256 		instRange				{ $<fl>$=$<fl>1; $$ = $1; }
2257 	|	instRangeList instRange			{ $<fl>$=$<fl>1; $$ = $1+$2; }
2258 	;
2259 
2260 instRange<str>:
2261 		'[' constExpr ']'			{ $<fl>$=$<fl>1; $$ = "["+$2+"]"; }
2262 	|	'[' constExpr ':' constExpr ']'		{ $<fl>$=$<fl>1; $$ = "["+$2+":"+$4+"]"; }
2263 	;
2264 
2265 cellpinList:
2266 		{ VARRESET_LIST(""); } cellpinItList	{ VARRESET_NONLIST(""); GRAMMARP->m_withinPin = false; }
2267 	;
2268 
2269 cellpinItList:			// IEEE: list_of_port_connections + list_of_parameter_assignmente
2270 		{ GRAMMARP->m_portNextNetName.clear(); }	cellpinItemE	{ }
2271 	|	cellpinItList ',' cellpinItemE		{ }
2272 	;
2273 
2274 cellpinItemE:			// IEEE: named_port_connection + named_parameter_assignment + empty
2275 		/* empty: ',,' is legal */		{ PINNUMINC(); }  /*PINDONE(yylval.fl,"",""); <- No, as then () implies a pin*/
2276 	|	yP_DOTSTAR				{ PINDONE($<fl>1,"*","*");PINNUMINC(); }
2277 	|	'.' idSVKwd				{ PINDONE($<fl>1,$2,$2);  PINNUMINC(); }
2278 	|	'.' idAny				{ PINDONE($<fl>1,$2,$2);  PINNUMINC(); }
2279 	|	'.' idAny '(' ')'			{ PINDONE($<fl>1,$2,"");  PINNUMINC(); }
2280 	//			// mintypmax is expanded here, as it might be a UDP or gate primitive
2281 	//			// For checkers, this needs to not just expr, but include events + properties
2282 	|	'.' idAny '(' pev_expr ')'		{ PINDONE($<fl>1,$2,$4);  PINNUMINC(); }
2283 	|	'.' idAny '(' pev_expr ':' expr ')'	{ PINDONE($<fl>1,$2,$4);  PINNUMINC(); }
2284 	|	'.' idAny '(' pev_expr ':' expr ':' expr ')' { PINDONE($<fl>1,$2,$4);  PINNUMINC(); }
2285 	//			// For parameters
2286 	|	'.' idAny '(' data_type ')'		{ PINDONE($<fl>1,$2,$4);  PINNUMINC(); }
2287 	//			// For parameters
2288 	|	data_type				{ PINDONE($<fl>1,"",$1);  PINNUMINC(); }
2289 	//
2290 	|	expr					{ PINDONE($<fl>1,"",$1);  PINNUMINC(); }
2291 	|	expr ':' expr				{ PINDONE($<fl>1,"",$1);  PINNUMINC(); }
2292 	|	expr ':' expr ':' expr			{ PINDONE($<fl>1,"",$1);  PINNUMINC(); }
2293 	;
2294 
2295 //************************************************
2296 // EventControl lists
2297 
2298 event_control:			// ==IEEE: event_control
2299 		'@' '(' event_expression ')'		{ }
2300 	|	'@' '*'					{ }
2301 	|	'@' '(' '*' ')'				{ }
2302 	//			// IEEE: hierarchical_event_identifier
2303 	|	'@' idClassSel/*event_id or ps_or_hierarchical_sequence_identifier*/		{ }
2304 	//			// IEEE: ps_or_hierarchical_sequence_identifier
2305 	//			// sequence_instance without parens matches idClassSel above.
2306 	//			// Ambiguity: "'@' sequence (-for-sequence" versus expr:delay_or_event_controlE "'@' id (-for-expr
2307 	//			// For now we avoid this, as it's very unlikely someone would mix
2308 	//			// 1995 delay with a sequence with parameters.
2309 	//			// Alternatively split this out of event_control, and delay_or_event_controlE
2310 	//			// and anywhere delay_or_event_controlE is called allow two expressions
2311 	;
2312 
2313 event_expression:		// IEEE: event_expression - split over several
2314 	//			// ',' rules aren't valid in port lists - ev_expr is there.
2315 	//			// Also eliminates left recursion to appease conflicts
2316 		ev_expr					{ }
2317 	|	event_expression ',' ev_expr %prec yOR	{ }	/* Verilog 2001 */
2318 	;
2319 
2320 senitemEdge<str>:		// IEEE: part of event_expression
2321 	//			// Also called by pev_expr
2322 		yPOSEDGE expr				{ $<fl>$=$<fl>1; $$=$1+" "+$2; }
2323 	|	yPOSEDGE expr yIFF expr			{ $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; }
2324 	|	yNEGEDGE expr				{ $<fl>$=$<fl>1; $$=$1+" "+$2; }
2325 	|	yNEGEDGE expr yIFF expr			{ $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; }
2326 	|	yEDGE expr				{ $<fl>$=$<fl>1; $$=$1+" "+$2; NEED_S09($<fl>1,"edge"); }
2327 	|	yEDGE expr yIFF expr			{ $<fl>$=$<fl>1; $$=$1+" "+$2+" iff "+$4; NEED_S09($<fl>1,"edge"); }
2328 	;
2329 
2330 //************************************************
2331 // Statements
2332 
2333 stmtBlock:			// IEEE: statement + seq_block + par_block
2334 		stmt					{ }
2335 	;
2336 
2337 seq_block:			// ==IEEE: seq_block
2338 	//			// IEEE doesn't allow declarations in unnamed blocks, but several simulators do.
2339 		seq_blockFront blockDeclStmtList yEND endLabelE	{ PARSEP->symPopScope(VAstType::BLOCK); }
2340 	|	seq_blockFront /**/		 yEND endLabelE	{ PARSEP->symPopScope(VAstType::BLOCK); }
2341 	;
2342 
2343 par_block:			// ==IEEE: par_block
2344 		par_blockFront blockDeclStmtList yJOIN endLabelE { PARSEP->symPopScope(VAstType::FORK); }
2345 	|	par_blockFront /**/		 yJOIN endLabelE { PARSEP->symPopScope(VAstType::FORK); }
2346 	;
2347 
2348 seq_blockFront:			// IEEE: part of seq_block
2349 		yBEGIN					 	{ PARSEP->symPushNewAnon(VAstType::BLOCK); }
2350 	|	yBEGIN ':' idAny/*new-block_identifier*/	{ PARSEP->symPushNew(VAstType::BLOCK,$1); }
2351 	;
2352 
2353 par_blockFront:			// IEEE: part of par_block
2354 		yFORK					{ PARSEP->symPushNewAnon(VAstType::FORK); }
2355 	|	yFORK ':' idAny/*new-block_identifier*/	{ PARSEP->symPushNew(VAstType::FORK,$1); }
2356 	;
2357 
2358 blockDeclStmtList:		// IEEE: { block_item_declaration } { statement or null }
2359 	//			// The spec seems to suggest a empty declaration isn't ok, but most simulators take it
2360 		block_item_declarationList		{ }
2361 	|	block_item_declarationList stmtList	{ }
2362 	|	stmtList				{ }
2363 	;
2364 
2365 block_item_declarationList:	// IEEE: [ block_item_declaration ]
2366 		block_item_declaration			{ }
2367 	|	block_item_declarationList block_item_declaration	{ }
2368 	;
2369 
2370 block_item_declaration:		// ==IEEE: block_item_declaration
2371 		data_declaration 			{ }
2372 	|	local_parameter_declaration ';'		{ }
2373 	|	parameter_declaration ';' 		{ }
2374 	|	overload_declaration 			{ }
2375 	|	let_declaration 			{ }
2376 	;
2377 
2378 stmtList:
2379 		stmtBlock				{ }
2380 	|	stmtList stmtBlock			{ }
2381 	;
2382 
2383 stmt:				// IEEE: statement_or_null == function_statement_or_null
2384 		statement_item				{ }
2385 	//			// S05 block creation rule
2386 	|	id/*block_identifier*/ ':' statement_item	{ }
2387 	//			// from _or_null
2388 	|	';'					{ }
2389 	;
2390 
2391 statement_item:			// IEEE: statement_item
2392 	//			// IEEE: operator_assignment
2393 		foperator_assignment ';'		{ }
2394 	//
2395 	//		 	// IEEE: blocking_assignment
2396 	//			// 1800-2009 restricts LHS of assignment to new to not have a range
2397 	//			// This is ignored to avoid conflicts
2398 	|	fexprLvalue '=' class_new ';'		{ }
2399 	|	fexprLvalue '=' dynamic_array_new ';'	{ }
2400 	//
2401 	//			// IEEE: nonblocking_assignment
2402 	|	fexprLvalue yP_LTE delay_or_event_controlE expr ';'	{ }
2403 	//
2404 	//			// IEEE: procedural_continuous_assignment
2405 	|	yASSIGN expr '=' delay_or_event_controlE expr ';'	{ }
2406 	|	yDEASSIGN variable_lvalue ';'		{ }
2407 	|	yFORCE expr '=' expr ';'		{ }
2408 	|	yRELEASE variable_lvalue ';'		{ }
2409 	//
2410 	//			// IEEE: case_statement
2411 	|	unique_priorityE caseStart caseAttrE case_itemListE yENDCASE	{ }
2412 	|	unique_priorityE caseStart caseAttrE yMATCHES case_patternListE yENDCASE	{ }
2413 	|	unique_priorityE caseStart caseAttrE yINSIDE  case_insideListE yENDCASE	{ }
2414 	//
2415 	//			// IEEE: conditional_statement
2416 	|	unique_priorityE yIF '(' expr ')' stmtBlock	%prec prLOWER_THAN_ELSE	{ }
2417 	|	unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock		{ }
2418 	//
2419 	|	finc_or_dec_expression ';'		{ }
2420 	//			// IEEE: inc_or_dec_expression
2421 	//			// Below under expr
2422 	//
2423 	//			// IEEE: subroutine_call_statement
2424 	|	yVOID yP_TICK '(' function_subroutine_callNoMethod ')' ';' { }
2425 	|	yVOID yP_TICK '(' expr '.' function_subroutine_callNoMethod ')' ';' { }
2426 	//			// Expr included here to resolve our not knowing what is a method call
2427 	//			// Expr here must result in a subroutine_call
2428 	|	task_subroutine_callNoMethod ';'	{ }
2429 	|	fexpr '.' array_methodNoRoot ';'	{ }
2430 	|	fexpr '.' task_subroutine_callNoMethod ';'	{ }
2431 	|	fexprScope ';'				{ }
2432 	//			// Not here in IEEE; from class_constructor_declaration
2433 	//			// Because we've joined class_constructor_declaration into generic functions
2434 	//			// Way over-permissive;
2435 	//			// IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ]
2436 	|	fexpr '.' class_new ';'		{ }
2437 	//
2438 	//			// IEEE: disable_statement
2439 	|	yDISABLE hierarchical_identifier/*task_or_block*/ ';'	{ }
2440 	|	yDISABLE yFORK ';'			{ }
2441 	//			// IEEE: event_trigger
2442 	|	yP_MINUSGT hierarchical_identifier/*event*/ ';'	{ }
2443 	|	yP_MINUSGTGT delay_or_event_controlE hierarchical_identifier/*event*/ ';'	{ }
2444 	//			// IEEE: loop_statement
2445 	|	yFOREVER stmtBlock			{ }
2446 	|	yREPEAT '(' expr ')' stmtBlock		{ }
2447 	|	yWHILE '(' expr ')' stmtBlock		{ }
2448 	//			// for's first ';' is in for_initalization
2449 	|	yFOR '(' for_initialization expr ';' for_stepE ')' stmtBlock
2450 				{ }
2451 	|	yFOR '(' for_initialization ';' for_stepE ')' stmtBlock
2452 				{ }
2453 	|	yDO stmtBlock yWHILE '(' expr ')' ';'	{ }
2454 	//			// IEEE says array_identifier here, but dotted accepted in VMM and 1800-2009
2455 	|	yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' stmt	{ }
2456 	//
2457 	//			// IEEE: jump_statement
2458 	|	yRETURN ';'				{ }
2459 	|	yRETURN expr ';'			{ }
2460 	|	yBREAK ';'				{ }
2461 	|	yCONTINUE ';'				{ }
2462 	//
2463 	|	par_block				{ }
2464 	//			// IEEE: procedural_timing_control_statement + procedural_timing_control
2465 	|	delay_control stmtBlock			{ }
2466 	|	event_control stmtBlock			{ }
2467 	|	cycle_delay stmtBlock			{ }
2468 	//
2469 	|	seq_block				{ }
2470 	//
2471 	//			// IEEE: wait_statement
2472 	|	yWAIT '(' expr ')' stmtBlock		{ }
2473 	|	yWAIT yFORK ';'				{ }
2474 	|	yWAIT_ORDER '(' hierarchical_identifierList ')' action_block	{ }
2475 	//
2476 	//			// IEEE: procedural_assertion_statement
2477 	|	procedural_assertion_statement		{ }
2478 	//
2479 	//			// IEEE: clocking_drive ';'
2480 	//			// clockvar_expression made to fexprLvalue to prevent reduce conflict
2481 	//			// Note LTE in this context is highest precedence, so first on left wins
2482 	|	fexprLvalue yP_LTE cycle_delay expr ';'	{ }
2483 	//
2484 	|	randsequence_statement			{ }
2485 	//
2486 	//			// IEEE: randcase_statement
2487 	|	yRANDCASE case_itemList yENDCASE	{ }
2488 	//
2489 	|	expect_property_statement		{ }
2490 	//
2491 	|	error ';'				{ }
2492 	;
2493 
2494 operator_assignment:		// IEEE: operator_assignment
2495 		~f~exprLvalue '=' delay_or_event_controlE expr { }
2496 	|	~f~exprLvalue yP_PLUSEQ    expr		{ }
2497 	|	~f~exprLvalue yP_MINUSEQ   expr		{ }
2498 	|	~f~exprLvalue yP_TIMESEQ   expr		{ }
2499 	|	~f~exprLvalue yP_DIVEQ     expr		{ }
2500 	|	~f~exprLvalue yP_MODEQ     expr		{ }
2501 	|	~f~exprLvalue yP_ANDEQ     expr		{ }
2502 	|	~f~exprLvalue yP_OREQ      expr		{ }
2503 	|	~f~exprLvalue yP_XOREQ     expr		{ }
2504 	|	~f~exprLvalue yP_SLEFTEQ   expr		{ }
2505 	|	~f~exprLvalue yP_SRIGHTEQ  expr		{ }
2506 	|	~f~exprLvalue yP_SSRIGHTEQ expr		{ }
2507 	;
2508 
2509 foperator_assignment<str>:	// IEEE: operator_assignment (for first part of expression)
2510 		BISONPRE_COPY(operator_assignment,{s/~f~/f/g})	// {copied}
2511 	;
2512 
2513 inc_or_dec_expression<str>:	// ==IEEE: inc_or_dec_expression
2514 	//			// Need fexprScope instead of variable_lvalue to prevent conflict
2515 		~l~exprScope yP_PLUSPLUS		{ $<fl>$=$<fl>1; $$ = $1+$2; }
2516 	|	~l~exprScope yP_MINUSMINUS		{ $<fl>$=$<fl>1; $$ = $1+$2; }
2517 	//			// Need expr instead of variable_lvalue to prevent conflict
2518 	|	yP_PLUSPLUS	expr			{ $<fl>$=$<fl>1; $$ = $1+$2; }
2519 	|	yP_MINUSMINUS	expr			{ $<fl>$=$<fl>1; $$ = $1+$2; }
2520 	;
2521 
2522 finc_or_dec_expression<str>:	// IEEE: inc_or_dec_expression (for first part of expression)
2523 		BISONPRE_COPY(inc_or_dec_expression,{s/~l~/f/g})	// {copied}
2524 	;
2525 
2526 sinc_or_dec_expression<str>:	// IEEE: inc_or_dec_expression (for sequence_expression)
2527 		BISONPRE_COPY(inc_or_dec_expression,{s/~l~/s/g})	// {copied}
2528 	;
2529 
2530 pinc_or_dec_expression<str>:	// IEEE: inc_or_dec_expression (for property_expression)
2531 		BISONPRE_COPY(inc_or_dec_expression,{s/~l~/p/g})	// {copied}
2532 	;
2533 
2534 ev_inc_or_dec_expression<str>:	// IEEE: inc_or_dec_expression (for ev_expr)
2535 		BISONPRE_COPY(inc_or_dec_expression,{s/~l~/ev_/g})	// {copied}
2536 	;
2537 
2538 pev_inc_or_dec_expression<str>:	// IEEE: inc_or_dec_expression (for pev_expr)
2539 		BISONPRE_COPY(inc_or_dec_expression,{s/~l~/pev_/g})	// {copied}
2540 	;
2541 
2542 class_new<str>:			// ==IEEE: class_new
2543 	//			// Special precence so (...) doesn't match expr
2544 		yNEW__ETC				{ $<fl>$=$<fl>1; $$ = $1; }
2545 	|	yNEW__ETC expr				{ $<fl>$=$<fl>1; $$ = $1+" "+$2; }
2546 	//			// Grammer abiguity; we assume "new (x)" the () are a argument, not expr
2547 	|	yNEW__PAREN '(' list_of_argumentsE ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2548 	;
2549 
2550 dynamic_array_new<str>:		// ==IEEE: dynamic_array_new
2551 		yNEW__ETC '[' expr ']'			{ $<fl>$=$<fl>1; $$=$1+"["+$3+"]"; }
2552 	|	yNEW__ETC '[' expr ']' '(' expr ')'	{ $<fl>$=$<fl>1; $$=$1+"["+$3+"]("+$6+")"; }
2553 	;
2554 
2555 //************************************************
2556 // Case/If
2557 
2558 unique_priorityE:		// IEEE: unique_priority + empty
2559 		/*empty*/				{ }
2560 	|	yPRIORITY				{ }
2561 	|	yUNIQUE					{ }
2562 	|	yUNIQUE0				{ NEED_S09($<fl>1, "unique0"); }
2563 	;
2564 
2565 action_block:			// ==IEEE: action_block
2566 		stmt	%prec prLOWER_THAN_ELSE		{ }
2567 	|	stmt yELSE stmt				{ }
2568 	|	yELSE stmt				{ }
2569 	;
2570 
2571 caseStart:			// IEEE: part of case_statement
2572 	 	yCASE  '(' expr ')'	{ }
2573 	|	yCASEX '(' expr ')'	{ }
2574 	|	yCASEZ '(' expr ')'	{ }
2575 	;
2576 
2577 caseAttrE:
2578 	 	/*empty*/				{ }
2579 	;
2580 
2581 case_patternListE:		// IEEE: case_pattern_item
2582 	//	&&& is part of expr so aliases to case_itemList
2583 		case_itemListE				{ }
2584 	;
2585 
2586 case_itemListE:			// IEEE: [ { case_item } ]
2587 		/* empty */				{ }
2588 	|	case_itemList				{ }
2589 	;
2590 
2591 case_insideListE:		// IEEE: [ { case_inside_item } ]
2592 		/* empty */				{ }
2593 	|	case_inside_itemList			{ }
2594 	;
2595 
2596 case_itemList:			// IEEE: { case_item + ... }
2597 		caseCondList ':' stmtBlock		{ }
2598 	|	yDEFAULT ':' stmtBlock			{ }
2599 	|	yDEFAULT stmtBlock			{ }
2600 	|	case_itemList caseCondList ':' stmtBlock	{ }
2601 	|       case_itemList yDEFAULT stmtBlock		{ }
2602 	|	case_itemList yDEFAULT ':' stmtBlock		{ }
2603 	;
2604 
2605 case_inside_itemList:		// IEEE: { case_inside_item + open_range_list ... }
2606 		open_range_list ':' stmtBlock		{ }
2607 	|	yDEFAULT ':' stmtBlock			{ }
2608 	|	yDEFAULT stmtBlock			{ }
2609 	|	case_inside_itemList open_range_list ':' stmtBlock { }
2610 	|       case_inside_itemList yDEFAULT stmtBlock	{ }
2611 	|	case_inside_itemList yDEFAULT ':' stmtBlock	{ }
2612 	;
2613 
2614 open_range_list:		// ==IEEE: open_range_list + open_value_range
2615 		open_value_range			{ }
2616 	|	open_range_list ',' open_value_range	{ }
2617 	;
2618 
2619 open_value_range:		// ==IEEE: open_value_range
2620 		value_range				{ }
2621 	;
2622 
2623 value_range:			// ==IEEE: value_range
2624 		expr					{ }
2625 	|	'[' expr ':' expr ']'			{ }
2626 	;
2627 
2628 covergroup_value_range:		// ==IEEE-2012: covergroup_value_range
2629 		cgexpr					{ }
2630 	|	'[' cgexpr ':' cgexpr ']'		{ }
2631 	;
2632 
2633 caseCondList:			// IEEE: part of case_item
2634 		expr 					{ }
2635 	|	caseCondList ',' expr			{ }
2636 	;
2637 
2638 patternNoExpr<str>:		// IEEE: pattern **Excluding Expr*
2639 		'.' id/*variable*/			{ $<fl>$=$<fl>1; $$="."+$2; }
2640 	|	yP_DOTSTAR				{ $<fl>$=$<fl>1; $$=".*"; }
2641 	//			// IEEE: "expr" excluded; expand in callers
2642 	//			// "yTAGGED id [expr]" Already part of expr
2643 	|	yTAGGED id/*member_identifier*/ patternNoExpr		{ $<fl>$=$<fl>1; $$=" tagged "+$2+" "+$3; }
2644 	//			// "yP_TICKBRA patternList '}'" part of expr under assignment_pattern
2645 	;
2646 
2647 patternList<str>:		// IEEE: part of pattern
2648 		patternOne				{ $<fl>$=$<fl>1; $$=$1; }
2649 	|	patternList ',' patternOne		{ $<fl>$=$<fl>1; $$=$1+","+$3; }
2650 	;
2651 
2652 patternOne<str>:		// IEEE: part of pattern
2653 		expr					{ $<fl>$=$<fl>1; $$=$1; }
2654 	|	expr '{' argsExprList '}'		{ $<fl>$=$<fl>1; $$=$1; }
2655 	|	patternNoExpr				{ $<fl>$=$<fl>1; $$=$1; }
2656 	;
2657 
2658 patternMemberList<str>:		// IEEE: part of pattern and assignment_pattern
2659 		patternKey ':' expr			{ $<fl>$=$<fl>1; $$=$1+" : "+$2; }
2660 	|	patternKey ':' patternNoExpr		{ $<fl>$=$<fl>1; $$=$1+" : "+$2; }
2661 	|	patternMemberList ',' patternKey ':' expr		{ $<fl>$=$<fl>1; $$=$1+","+$3+":"+$4; }
2662 	|	patternMemberList ',' patternKey ':' patternNoExpr	{ $<fl>$=$<fl>1; $$=$1+","+$3+":"+$4; }
2663 	;
2664 
2665 patternKey<str>:		// IEEE: merge structure_pattern_key, array_pattern_key, assignment_pattern_key
2666 	//			// IEEE: structure_pattern_key
2667 	//			// id/*member*/ is part of constExpr below
2668 		constExpr				{ $<fl>$=$<fl>1; $$=$1; }
2669 	//			// IEEE: assignment_pattern_key
2670 	|	yDEFAULT				{ $<fl>$=$<fl>1; $$=$1; }
2671 	|	simple_type				{ $<fl>$=$<fl>1; $$=$1; }
2672 	//			// simple_type reference looks like constExpr
2673 	;
2674 
2675 assignment_pattern<str>:		// ==IEEE: assignment_pattern
2676 	// This doesn't match the text of the spec.  I think a : is missing, or example code needed
2677 	// yP_TICKBRA constExpr exprList '}'	{ $$="'{"+$2+" "+$3"}"; }
2678 	//			// "'{ const_expression }" is same as patternList with one entry
2679 	//			// From patternNoExpr
2680 	//			// also IEEE: "''{' expression { ',' expression } '}'"
2681 	//			//      matches since patternList includes expr
2682 		yP_TICKBRA patternList '}'		{ $<fl>$=$<fl>1; $$="'{"+$2+"}"; }
2683 	//			// From patternNoExpr
2684 	//			// also IEEE "''{' structure_pattern_key ':' ...
2685 	//			// also IEEE "''{' array_pattern_key ':' ...
2686 	|	yP_TICKBRA patternMemberList '}'	{ $<fl>$=$<fl>1; $$="'{"+$2+"}"; }
2687 	//			// IEEE: Not in grammar, but in VMM
2688 	|	yP_TICKBRA '}'				{ $<fl>$=$<fl>1; $$="'{}"; }
2689 	;
2690 
2691 // "datatype id = x {, id = x }"  |  "yaId = x {, id=x}" is legal
2692 for_initialization:		// ==IEEE: for_initialization + for_variable_declaration + extra terminating ";"
2693 	//			// IEEE: for_variable_declaration
2694 		for_initializationItemList ';'		{ }
2695 	//			// IEEE: 1800-2017 empty initialization
2696 	|	';'					{ }
2697 	;
2698 
2699 for_initializationItemList:	// IEEE: [for_variable_declaration...]
2700 		for_initializationItem			{ }
2701 	|	for_initializationItemList ',' for_initializationItem	{ }
2702 	;
2703 
2704 for_initializationItem:		// IEEE: variable_assignment + for_variable_declaration
2705 	//			// IEEE: for_variable_declaration
2706 		data_type idAny/*new*/ '=' expr		{ VARDTYPE($1); }
2707 	//			// IEEE-2012:
2708 	|	yVAR data_type idAny/*new*/ '=' expr		{ VARDTYPE($1); }
2709 	//			// IEEE: variable_assignment
2710 	|	variable_lvalue '=' expr		{ }
2711 	;
2712 
2713 for_stepE:			// IEEE: for_step + empty
2714 		/* empty */				{ }
2715 	|	for_step				{ }
2716 	;
2717 
2718 for_step:			// IEEE: for_step
2719 		for_step_assignment			{ }
2720 	|	for_step ',' for_step_assignment	{ }
2721 	;
2722 
2723 for_step_assignment:		// ==IEEE: for_step_assignment
2724 		operator_assignment			{ }
2725 	//
2726 	|	inc_or_dec_expression			{ }
2727 	//			// IEEE: subroutine_call
2728 	|	function_subroutine_callNoMethod	{ }
2729 	//			// method_call:array_method requires a '.'
2730 	|	expr '.' array_methodNoRoot		{ }
2731 	|	exprScope				{ }
2732 	;
2733 
2734 loop_variables<str>:			// ==IEEE: loop_variables
2735 		id					{ $<fl>$=$<fl>1; $$=$1; }
2736 	|	loop_variables ',' id			{ $<fl>$=$<fl>1; $$=$1+","+$3; }
2737 	;
2738 
2739 //************************************************
2740 // Functions/tasks
2741 
2742 funcRef<str>:			// IEEE: part of tf_call
2743 	//			// package_scope/hierarchical_... is part of expr, so just need ID
2744 	//			//	making-a		id-is-a
2745 	//			//	-----------------	------------------
2746 	//			//      tf_call			tf_identifier		expr (list_of_arguments)
2747 	//			//      method_call(post .)	function_identifier	expr (list_of_arguments)
2748 	//			//	property_instance	property_identifier	property_actual_arg
2749 	//			//	sequence_instance	sequence_identifier	sequence_actual_arg
2750 	//			//      let_expression		let_identifier		let_actual_arg
2751 	//
2752 		id '(' pev_list_of_argumentsE ')'	{ $<fl>$=$<fl>1; $$=$1+"("+$3+")"; }
2753 	|	package_scopeIdFollows id '(' pev_list_of_argumentsE ')'	{ $<fl>$=$<fl>2; $$=$1+$2+"("+$4+")"; }
2754 	|	class_scope_id '(' pev_list_of_argumentsE ')'	{ $<fl>$=$<fl>1; $$=$<str>1+"("+$3+")"; }
2755 	;
2756 
2757 task_subroutine_callNoMethod<str>:	// function_subroutine_callNoMethod (as task)
2758 	//			// IEEE: tf_call
2759 		funcRef					{ $<fl>$=$<fl>1; $$=$1; }
2760 	|	funcRef yWITH__PAREN '(' expr ')'	{ $<fl>$=$<fl>1; $$=$1+" "+$2+$3+$4+$5; }
2761 	|	system_t_call				{ $<fl>$=$<fl>1; $$=$1; }
2762 	//			// IEEE: method_call requires a "." so is in expr
2763 	//			// IEEE: ['std::'] not needed, as normal std package resolution will find it
2764 	//			// IEEE: randomize_call
2765 	//			// We implement randomize as a normal funcRef, since randomize isn't a keyword
2766 	//			// Note yNULL is already part of expressions, so they come for free
2767 	|	funcRef yWITH__CUR constraint_block	{ $<fl>$=$<fl>1; $$=$1+" with..."; }
2768 	;
2769 
2770 function_subroutine_callNoMethod<str>:	// IEEE: function_subroutine_call (as function)
2771 	//			// IEEE: tf_call
2772 		funcRef					{ $<fl>$=$<fl>1; $$=$1; }
2773 	|	funcRef yWITH__PAREN '(' expr ')'	{ $<fl>$=$<fl>1; $$=$1+" "+$2+$3+$4+$5; }
2774 	|	system_f_call				{ $<fl>$=$<fl>1; $$=$1; }
2775 	//			// IEEE: method_call requires a "." so is in expr
2776 	//			// IEEE: ['std::'] not needed, as normal std package resolution will find it
2777 	//			// IEEE: randomize_call
2778 	//			// We implement randomize as a normal funcRef, since randomize isn't a keyword
2779 	//			// Note yNULL is already part of expressions, so they come for free
2780 	|	funcRef yWITH__CUR constraint_block	{ $<fl>$=$<fl>1; $$=$1+" with..."; }
2781 	;
2782 
2783 system_t_call<str>:		// IEEE: system_tf_call (as task)
2784 		system_f_call				{ $<fl>$=$<fl>1; $$ = $1; }
2785 	;
2786 
2787 system_f_call<str>:		// IEEE: system_tf_call (as func)
2788 		ygenSYSCALL parenE			{ $<fl>$=$<fl>1; $$ = $1; }
2789 	//			// Allow list of data_type to support "x,,,y"
2790 	|	ygenSYSCALL '(' exprOrDataTypeList ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2791 	//			// Standard doesn't explicity list system calls
2792 	//			// But these match elaboration calls in 1800-2009
2793 	|	yD_FATAL parenE				{ $<fl>$=$<fl>1; $$ = $1; }
2794 	|	yD_FATAL '(' exprOrDataTypeList ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2795 	|	yD_ERROR parenE				{ $<fl>$=$<fl>1; $$ = $1; }
2796 	|	yD_ERROR '(' exprOrDataTypeList ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2797 	|	yD_WARNING parenE			{ $<fl>$=$<fl>1; $$ = $1; }
2798 	|	yD_WARNING '(' exprOrDataTypeList ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2799 	|	yD_INFO parenE				{ $<fl>$=$<fl>1; $$ = $1; }
2800 	|	yD_INFO '(' exprOrDataTypeList ')'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; }
2801 	;
2802 
2803 elaboration_system_task<str>:	// IEEE: elaboration_system_task (1800-2009)
2804 	//			// $fatal first argument is exit number, must be constant
2805 		yD_FATAL parenE ';'			{ $<fl>$=$<fl>1; $$ = $1;            NEED_S09($<fl>1,"elaboration system tasks"); }
2806 	|	yD_FATAL '(' exprOrDataTypeList ')' ';'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2807 	|	yD_ERROR parenE	';'			{ $<fl>$=$<fl>1; $$ = $1;            NEED_S09($<fl>1,"elaboration system tasks"); }
2808 	|	yD_ERROR '(' exprOrDataTypeList ')' ';'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2809 	|	yD_WARNING parenE ';'			{ $<fl>$=$<fl>1; $$ = $1;            NEED_S09($<fl>1,"elaboration system tasks"); }
2810 	|	yD_WARNING '(' exprOrDataTypeList ')' ';' {$<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2811 	|	yD_INFO parenE ';'			{ $<fl>$=$<fl>1; $$ = $1;            NEED_S09($<fl>1,"elaboration system tasks"); }
2812 	|	yD_INFO '(' exprOrDataTypeList ')' ';'	{ $<fl>$=$<fl>1; $$ = $1+"("+$3+")"; NEED_S09($<fl>1,"elaboration system tasks"); }
2813 	;
2814 
2815 property_actual_arg<str>:	// ==IEEE: property_actual_arg
2816 	//			// IEEE: property_expr
2817 	//			// IEEE: sequence_actual_arg
2818 		pev_expr				{ $<fl>$=$<fl>1; $$=$1; }
2819 	//			// IEEE: sequence_expr
2820 	//			// property_expr already includes sequence_expr
2821 	;
2822 
2823 task<fl>:
2824 		yTASK__ETC				{ $<fl>$=$<fl>1; }
2825 	|	yTASK__aPUREV				{ $<fl>$=$<fl>1; }
2826 	;
2827 
2828 task_declaration:		// IEEE: task_declaration
2829 		yTASK__ETC lifetimeE taskId tfGuts yENDTASK endLabelE
2830 			{ PARSEP->endtaskfuncCb($<fl>5,$5);
2831 			  PARSEP->symPopScope(VAstType::TASK); }
2832 	|	yTASK__aPUREV lifetimeE taskId tfGutsPureV
2833 			{ PARSEP->endtaskfuncCb($<fl>1,"endtask");
2834 			  PARSEP->symPopScope(VAstType::TASK); }
2835 	;
2836 
2837 task_prototype:			// ==IEEE: task_prototype
2838 	//			// IEEE: has '(' tf_port_list ')'
2839 	//			// However the () should be optional for OVA
2840 		task taskId '(' tf_port_listE ')'	{ PARSEP->symPopScope(VAstType::TASK); PARSEP->endtaskfuncCb($<fl>1,"endtask"); }
2841 	|	task taskId				{ PARSEP->symPopScope(VAstType::TASK); PARSEP->endtaskfuncCb($<fl>1,"endtask"); }
2842 	;
2843 
2844 function<fl>:
2845 		yFUNCTION__ETC				{ $<fl>$=$<fl>1; }
2846 	|	yFUNCTION__aPUREV			{ $<fl>$=$<fl>1; }
2847 	;
2848 
2849 function_declaration:		// IEEE: function_declaration + function_body_declaration
2850 	 	yFUNCTION__ETC lifetimeE funcId tfGuts yENDFUNCTION endLabelE
2851 			{ PARSEP->endtaskfuncCb($<fl>5,$5);
2852 			  PARSEP->symPopScope(VAstType::FUNCTION); }
2853 	| 	yFUNCTION__ETC lifetimeE funcIdNew tfGuts yENDFUNCTION endLabelE
2854 			{ PARSEP->endtaskfuncCb($<fl>5,$5);
2855 			  PARSEP->symPopScope(VAstType::FUNCTION); }
2856 	|	yFUNCTION__aPUREV lifetimeE funcId tfGutsPureV
2857 			{ PARSEP->endtaskfuncCb($<fl>1,"endfunction");
2858 			  PARSEP->symPopScope(VAstType::FUNCTION); }
2859 	| 	yFUNCTION__aPUREV lifetimeE funcIdNew tfGutsPureV
2860 			{ PARSEP->endtaskfuncCb($<fl>1,"endfunction");
2861 			  PARSEP->symPopScope(VAstType::FUNCTION); }
2862 	;
2863 
2864 function_prototype:		// IEEE: function_prototype
2865 	//			// IEEE: has '(' tf_port_list ')'
2866 	//			// However the () should be optional for OVA
2867 		function funcId '(' tf_port_listE ')'	{ PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2868 	|	function funcId 			{ PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2869 	;
2870 
2871 class_constructor_prototype:	// ==IEEE: class_constructor_prototype
2872 		function funcIdNew '(' tf_port_listE ')' ';'	{ PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2873 	|	function funcIdNew ';'				{ PARSEP->symPopScope(VAstType::FUNCTION); PARSEP->endtaskfuncCb($<fl>1,"endfunction"); }
2874 	;
2875 
2876 method_prototype:
2877 		task_prototype				{ }
2878 	|	function_prototype			{ }
2879 	;
2880 
2881 lifetimeE:			// IEEE: [lifetime]
2882 		/* empty */		 		{ }
2883 	|	lifetime		 		{ }
2884 	;
2885 
2886 lifetime:			// ==IEEE: lifetime
2887 	//			// Note lifetime used by members is instead under memberQual
2888 		ySTATIC__ETC		 		{ }
2889 	|	yAUTOMATIC		 		{ }
2890 	;
2891 
2892 taskId:
2893 		tfIdScoped
2894 			{ PARSEP->symPushNewUnder(VAstType::TASK, $<str>1, $<scp>1);
2895 			  PARSEP->taskCb($<fl>1,"task",$<str>1); }
2896 	;
2897 
2898 funcId:				// IEEE: function_data_type_or_implicit + part of function_body_declaration
2899 	//			// IEEE: function_data_type_or_implicit must be expanded here to prevent conflict
2900 	//			// function_data_type expanded here to prevent conflicts with implicit_type:empty vs data_type:ID
2901 		/**/			tfIdScoped
2902 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>1, $<scp>1);
2903 			  PARSEP->functionCb($<fl>1,"function",$<str>1,""); }
2904 	|	signingE rangeList	tfIdScoped
2905 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>3, $<scp>3);
2906 			  PARSEP->functionCb($<fl>3,"function",$<str>3,SPACED($1,$2)); }
2907 	|	signing			tfIdScoped
2908 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2909 			  PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2910 	|	yVOID			tfIdScoped
2911 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2912 			  PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2913 	|	data_type		tfIdScoped
2914 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, $<str>2, $<scp>2);
2915 			  PARSEP->functionCb($<fl>2,"function",$<str>2,$1); }
2916 	;
2917 
2918 funcIdNew:			// IEEE: from class_constructor_declaration
2919 	 	yNEW__ETC
2920 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", NULL);
2921 			  PARSEP->functionCb($<fl>1,"function","new",""); }
2922 	| 	yNEW__PAREN
2923 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", NULL);
2924 			  PARSEP->functionCb($<fl>1,"function","new",""); }
2925 	|	class_scopeWithoutId yNEW__PAREN
2926 			{ PARSEP->symPushNewUnder(VAstType::FUNCTION, "new", $<scp>1);
2927 			  PARSEP->functionCb($<fl>2,"function","new",""); }
2928 	;
2929 
2930 tfIdScoped<str_scp>:		// IEEE: part of function_body_declaration/task_body_declaration
2931  	//			// IEEE: [ interface_identifier '.' | class_scope ] function_identifier
2932 		id					{ $<fl>$=$<fl>1; $<scp>$=NULL;     $<str>$ = $1; }
2933 	|	id/*interface_identifier*/ '.' id	{ $<fl>$=$<fl>1; $<scp>$=NULL;     $<str>$ = $1+"."+$2; }
2934 	|	class_scope_id				{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$ = $<str>1; }
2935 	;
2936 
2937 tfGuts:
2938 		'(' tf_port_listE ')' ';' tfBodyE	{ }
2939 	|	';' tfBodyE				{ }
2940 	;
2941 
2942 tfGutsPureV:
2943 		'(' tf_port_listE ')' ';'		{ }
2944 	|	';'					{ }
2945 	;
2946 
2947 tfBodyE:		// IEEE: part of function_body_declaration/task_body_declaration
2948 		/* empty */				{ }
2949 	|	tf_item_declarationList			{ }
2950 	|	tf_item_declarationList stmtList	{ }
2951 	|	stmtList				{ }
2952 	;
2953 
2954 function_data_type<str>:	// IEEE: function_data_type
2955 		yVOID					{ $$ = $1; }
2956 	|	data_type				{ $$ = $1; }
2957 	;
2958 
2959 tf_item_declarationList:
2960 		tf_item_declaration			{ }
2961 	|	tf_item_declarationList tf_item_declaration	{ }
2962 	;
2963 
2964 tf_item_declaration:		// ==IEEE: tf_item_declaration
2965 		block_item_declaration			{ }
2966 	| 	tf_port_declaration			{ }
2967 	;
2968 
2969 tf_port_listE:			// IEEE: tf_port_list + empty
2970 	//			// Empty covered by tf_port_item
2971 		{ VARRESET_LIST(""); VARIO("input"); }
2972 			tf_port_listList		{ VARRESET_NONLIST(""); }
2973 	;
2974 
2975 tf_port_listList:		// IEEE: part of tf_port_list
2976 		tf_port_item				{ }
2977 	|	tf_port_listList ',' tf_port_item	{ }
2978 	;
2979 
2980 tf_port_item:			// ==IEEE: tf_port_item
2981 	//			// We split tf_port_item into the type and assignment as don't know what follows a comma
2982 		/* empty */				{ PINNUMINC(); }	// For example a ",," port
2983 	|	tf_port_itemFront tf_port_itemAssignment { PINNUMINC(); }
2984 	|	tf_port_itemAssignment 			{ PINNUMINC(); }
2985 	;
2986 
2987 tf_port_itemFront:		// IEEE: part of tf_port_item, which has the data type
2988 		data_type				{ VARDTYPE($1); }
2989 	|	signingE rangeList			{ VARDTYPE(SPACED($1,$2)); }
2990 	|	signing					{ VARDTYPE($1); }
2991 	|	yVAR data_type				{ VARDTYPE($2); }
2992 	|	yVAR implicit_typeE			{ VARDTYPE($2); }
2993 	//
2994 	|	tf_port_itemDir /*implicit*/		{ VARDTYPE(""); /*default_nettype-see spec*/ }
2995 	|	tf_port_itemDir data_type		{ VARDTYPE($2); }
2996 	|	tf_port_itemDir signingE rangeList	{ VARDTYPE(SPACED($2,$3)); }
2997 	|	tf_port_itemDir signing			{ VARDTYPE($2); }
2998 	|	tf_port_itemDir yVAR data_type		{ VARDTYPE($3); }
2999 	|	tf_port_itemDir yVAR implicit_typeE	{ VARDTYPE($3); }
3000 	;
3001 
3002 tf_port_itemDir:		// IEEE: part of tf_port_item, direction
3003 		port_direction				{ }  // port_direction sets VARIO
3004 	;
3005 
3006 tf_port_itemAssignment:		// IEEE: part of tf_port_item, which has assignment
3007 		id variable_dimensionListE sigAttrListE
3008 			{ VARDONE($<fl>1, $1, $2, ""); }
3009 	|	id variable_dimensionListE sigAttrListE '=' expr
3010 			{ VARDONE($<fl>1, $1, $2, $5); }
3011 	;
3012 
3013 parenE:
3014 		/* empty */				{ }
3015 	|	'(' ')'					{ }
3016 	;
3017 
3018 //	method_call:		// ==IEEE: method_call + method_call_body
3019 //				// IEEE: method_call_root '.' method_identifier [ '(' list_of_arguments ')' ]
3020 //				//   "method_call_root '.' method_identifier" looks just like "expr '.' id"
3021 //				//   "method_call_root '.' method_identifier (...)" looks just like "expr '.' tf_call"
3022 //				// IEEE: built_in_method_call
3023 //				//   method_call_root not needed, part of expr resolution
3024 //				// What's left is below array_methodNoRoot
3025 
3026 array_methodNoRoot<str>:	// ==IEEE: built_in_method_call without root
3027 	//			//   method_call_root not needed, part of expr resolution
3028 		array_method_nameNoId method_callWithE	{ $<fl>$=$<fl>1; $$=$1+$2; }
3029 	|	array_method_nameNoId '(' list_of_argumentsE ')' method_callWithE	{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3030 	//			//  "method_call_root '.' randomize_call" matches function_subroutine_call:randomize_call
3031 	;
3032 
3033 method_callWithE<str>:
3034 	//			// Code duplicated elsewhere
3035 		/* empty */				{ $$=""; }
3036 	|	yWITH__PAREN '(' expr ')'		{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3037 	;
3038 
3039 array_method_nameNoId<str>:	// IEEE: array_method_name minus method_identifier
3040 		yUNIQUE					{ $<fl>$=$<fl>1; $$=$1; }
3041 	|	yAND					{ $<fl>$=$<fl>1; $$=$1; }
3042 	|	yOR					{ $<fl>$=$<fl>1; $$=$1; }
3043 	|	yXOR					{ $<fl>$=$<fl>1; $$=$1; }
3044 	;
3045 
3046 dpi_import_export:		// ==IEEE: dpi_import_export
3047 		yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE function_prototype ';'	{ }
3048 	|	yIMPORT yaSTRING dpi_tf_import_propertyE dpi_importLabelE task_prototype ';'	{ }
3049 	|	yEXPORT yaSTRING dpi_importLabelE function idAny ';'	{ }
3050 	|	yEXPORT yaSTRING dpi_importLabelE task     idAny ';'	{ }
3051 	;
3052 
3053 dpi_importLabelE:		// IEEE: part of dpi_import_export
3054 		/* empty */				{ }
3055 	|	idAny/*c_identifier*/ '='		{ }
3056 	;
3057 
3058 dpi_tf_import_propertyE:	// IEEE: [ dpi_function_import_property + dpi_task_import_property ]
3059 		/* empty */				{ }
3060 	|	yCONTEXT				{ }
3061 	|	yPURE					{ }
3062 	;
3063 
3064 overload_declaration:		// ==IEEE: overload_declaration
3065 	//			// OLD: Overloads deprecated in IEEE 1800-2017
3066 		yBIND overload_operator function data_type idAny/*new-function_identifier*/
3067 			'(' overload_proto_formals ')' ';'	{ }
3068 	;
3069 
3070 overload_operator<str>:		// ==IEEE: overload_operator
3071 		"+"		{ $$="+"; }
3072 	|	yP_PLUSPLUS	{ $$="++"; }
3073 	|	"-"		{ $$="-"; }
3074 	|	yP_MINUSMINUS	{ $$="--"; }
3075 	|	"*"		{ $$="*"; }
3076 	|	yP_POW		{ $$="**"; }
3077 	|	"/"		{ $$="/"; }
3078 	|	"%"		{ $$="%"; }
3079 	|	yP_EQUAL	{ $$="=="; }
3080 	|	yP_NOTEQUAL	{ $$="!="; }
3081 	|	"<"		{ $$="<"; }
3082 	|	yP_LTE		{ $$="<="; }
3083 	|	">"		{ $$=">"; }
3084 	|	yP_GTE		{ $$=">="; }
3085 	|	"="		{ $$="="; }
3086 	;
3087 
3088 overload_proto_formals:		// ==IEEE: overload_proto_formals
3089 		data_type				{ }
3090 	|	overload_proto_formals ',' data_type	{ }
3091 	;
3092 
3093 //************************************************
3094 // Expressions
3095 //
3096 // ~l~ means this is the (l)eft hand side of any operator
3097 //     it will get replaced by "", "f" or "s"equence
3098 // ~r~ means this is a (r)ight hand later expansion in the same statement,
3099 //     not under parenthesis for <= disambiguation
3100 //     it will get replaced by "", or "f"
3101 // ~p~ means this is a (p)arenthetized expression
3102 //     it will get replaced by "", or "s"equence
3103 
3104 constExpr<str>:
3105 		expr					{ $<fl>$=$<fl>1; $$ = $1; }
3106 	;
3107 
3108 expr<str>:			// IEEE: part of expression/constant_expression/primary
3109 	// *SEE BELOW*		// IEEE: primary/constant_primary
3110 	//
3111 	//			// IEEE: unary_operator primary
3112 		'+' ~r~expr	%prec prUNARYARITH	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3113 	|	'-' ~r~expr	%prec prUNARYARITH	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3114 	|	'!' ~r~expr	%prec prNEGATION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3115 	|	'&' ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3116 	|	'~' ~r~expr	%prec prNEGATION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3117 	|	'|' ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3118 	|	'^' ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3119 	|	yP_NAND ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3120 	|	yP_NOR  ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3121 	|	yP_XNOR ~r~expr	%prec prREDUCTION	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3122 	//
3123 	//			// IEEE: inc_or_dec_expression
3124 	|	~l~inc_or_dec_expression		{ $<fl>$=$<fl>1; $$ = $1; }
3125 	//
3126 	//			// IEEE: '(' operator_assignment ')'
3127 	//			// Need exprScope of variable_lvalue to prevent conflict
3128 	|	'(' ~p~exprScope '=' 	      expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3129 	|	'(' ~p~exprScope yP_PLUSEQ    expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3130 	|	'(' ~p~exprScope yP_MINUSEQ   expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3131 	|	'(' ~p~exprScope yP_TIMESEQ   expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3132 	|	'(' ~p~exprScope yP_DIVEQ     expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3133 	|	'(' ~p~exprScope yP_MODEQ     expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3134 	|	'(' ~p~exprScope yP_ANDEQ     expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3135 	|	'(' ~p~exprScope yP_OREQ      expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3136 	|	'(' ~p~exprScope yP_XOREQ     expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3137 	|	'(' ~p~exprScope yP_SLEFTEQ   expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3138 	|	'(' ~p~exprScope yP_SRIGHTEQ  expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3139 	|	'(' ~p~exprScope yP_SSRIGHTEQ expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+$3+$4+")"; }
3140 	//
3141 	//			// IEEE: expression binary_operator expression
3142 	|	~l~expr '+' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3143 	|	~l~expr '-' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3144 	|	~l~expr '*' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3145 	|	~l~expr '/' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3146 	|	~l~expr '%' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3147 	|	~l~expr yP_EQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3148 	|	~l~expr yP_NOTEQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3149 	|	~l~expr yP_CASEEQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3150 	|	~l~expr yP_CASENOTEQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3151 	|	~l~expr yP_WILDEQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3152 	|	~l~expr yP_WILDNOTEQUAL ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3153 	|	~l~expr yP_ANDAND ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3154 	|	~l~expr yP_OROR ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3155 	|	~l~expr yP_POW ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3156 	|	~l~expr '<' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3157 	|	~l~expr '>' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3158 	|	~l~expr yP_GTE ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3159 	|	~l~expr '&' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3160 	|	~l~expr '|' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3161 	|	~l~expr '^' ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3162 	|	~l~expr yP_XNOR ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3163 	|	~l~expr yP_NOR  ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3164 	|	~l~expr yP_NAND ~r~expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3165 	|	~l~expr yP_SLEFT ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3166 	|	~l~expr yP_SRIGHT ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3167 	|	~l~expr yP_SSRIGHT ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3168 	|	~l~expr yP_LTMINUSGT ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3169 	//
3170 	//			// IEEE: expr yP_MINUSGT expr  (1800-2009)
3171 	//			// Conflicts with constraint_expression:"expr yP_MINUSGT constraint_set"
3172 	//			// To duplicating expr for constraints, just allow the more general form
3173 	//			// Later Ast processing must ignore constraint terms where inappropriate
3174 	|	~l~expr yP_MINUSGT constraint_set		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3175 	//
3176 	//			// <= is special, as we need to disambiguate it with <= assignment
3177 	//			// We copy all of expr to fexpr and rename this token to a fake one.
3178 	|	~l~expr yP_LTE~f__IGNORE~ ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3179 	//
3180 	//			// IEEE: conditional_expression
3181 	|	~l~expr '?' ~r~expr ':' ~r~expr		{ $<fl>$=$<fl>1; $$ = $1+"?"+$3+":"+$5; }
3182 	//
3183 	//			// IEEE: inside_expression
3184 	|	~l~expr yINSIDE '{' open_range_list '}'	{ $<fl>$=$<fl>1; $$ = $1+" inside {"+$3+"}"; }
3185 	//
3186 	//			// IEEE: tagged_union_expression
3187 	|	yTAGGED id/*member*/ %prec prTAGGED		{ $<fl>$=$<fl>1; $$ = " tagged "+$1; }
3188 	|	yTAGGED id/*member*/ %prec prTAGGED expr	{ $<fl>$=$<fl>1; $$ = " tagged "+$1+" "+$2; }
3189 	//
3190 	//======================// IEEE: primary/constant_primary
3191 	//
3192 	//			// IEEE: primary_literal (minus string, which is handled specially)
3193 	|	yaINTNUM				{ $<fl>$=$<fl>1; $$ = $1; }
3194 	|	yaFLOATNUM				{ $<fl>$=$<fl>1; $$ = $1; }
3195 	|	yaTIMENUM				{ $<fl>$=$<fl>1; $$ = $1; }
3196 	|	strAsInt~noStr__IGNORE~ 		{ $<fl>$=$<fl>1; $$ = $1; }
3197 	//
3198 	//			// IEEE: "... hierarchical_identifier select"  see below
3199 	//
3200 	//			// IEEE: empty_queue (IEEE 1800-2017 empty_unpacked_array_concatenation)
3201 	|	'{' '}'
3202 	//
3203 	//			// IEEE: concatenation/constant_concatenation
3204 	//			// Part of exprOkLvalue below
3205 	//
3206 	//			// IEEE: multiple_concatenation/constant_multiple_concatenation
3207 	|	'{' constExpr '{' cateList '}' '}'	{ $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}"; }
3208 	//			// IEEE: multiple_concatenation/constant_multiple_concatenation+ range_expression (1800-2009)
3209 	|	'{' constExpr '{' cateList '}' '}' '[' expr ']'
3210 			{ $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+"]";        NEED_S09($<fl>6,"{}[]"); }
3211 	|	'{' constExpr '{' cateList '}' '}' '[' expr ':' expr ']'
3212 			{ $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3213 	|	'{' constExpr '{' cateList '}' '}' '[' expr yP_PLUSCOLON  expr ']'
3214 			{ $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3215 	|	'{' constExpr '{' cateList '}' '}' '[' expr yP_MINUSCOLON expr ']'
3216 			{ $<fl>$=$<fl>1; $$ = "{"+$2+"{"+$4+"}}["+$8+$9+$10+"]"; NEED_S09($<fl>6,"{}[]"); }
3217 	//
3218 	|	function_subroutine_callNoMethod	{ $$ = $1; }
3219 	//			// method_call
3220 	|	~l~expr '.' function_subroutine_callNoMethod	{ $<fl>$=$<fl>1; $$=$1+"."+$3; }
3221 	//			// method_call:array_method requires a '.'
3222 	|	~l~expr '.' array_methodNoRoot		{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3223 	//
3224 	//			// IEEE: let_expression
3225 	//			// see funcRef
3226 	//
3227 	//			// IEEE: '(' mintypmax_expression ')'
3228 	|	~noPar__IGNORE~'(' expr ')'			{ $<fl>$=$<fl>1; $$ = "("+$2+")"; }
3229 	|	~noPar__IGNORE~'(' expr ':' expr ':' expr ')'	{ $<fl>$=$<fl>1; $$ = "("+$2+":"+$4+":"+$5+")"; }
3230 	//			// PSL rule
3231 	|	'_' '(' statePushVlg expr statePop ')'	{ $<fl>$=$<fl>1; $$ = "_("+$4+")"; }	// Arbitrary Verilog inside PSL
3232 	//
3233 	//			// IEEE: cast/constant_cast
3234 	|	casting_type yP_TICK '(' expr ')'	{ $<fl>$=$<fl>1; $$ = $1+"'("+$4+")"; }
3235 	//			// Spec only allows primary with addition of a type reference
3236 	//			// We'll be more general, and later assert LHS was a type.
3237 	|	~l~expr yP_TICK '(' expr ')'		{ $<fl>$=$<fl>1; $$ = $1+"'("+$4+")"; }
3238 	//
3239 	//			// IEEE: assignment_pattern_expression
3240 	//			// IEEE: streaming_concatenation
3241 	//			// See exprOkLvalue
3242 	//
3243 	//			// IEEE: sequence_method_call
3244 	//			// Indistinguishable from function_subroutine_call:method_call
3245 	//
3246 	|	'$'					{ $<fl>$=$<fl>1; $$ = "$"; }
3247 	|	yNULL					{ $<fl>$=$<fl>1; $$ = $1; }
3248 	//			// IEEE: yTHIS
3249 	//			// See exprScope
3250 	//
3251 	//----------------------
3252 	//
3253 	//			// Part of expr that may also be used as lvalue
3254 	|	~l~exprOkLvalue				{ $<fl>$=$<fl>1; $$ = $1; }
3255 	//
3256 	//----------------------
3257 	//
3258 	//			// IEEE: cond_predicate - here to avoid reduce problems
3259 	//			// Note expr includes cond_pattern
3260 	|	~l~expr yP_ANDANDAND ~r~expr		{ $<fl>$=$<fl>1; $$ = $1 + "&&&" + $3; }
3261 	//
3262 	//			// IEEE: cond_pattern - here to avoid reduce problems
3263 	//			// "expr yMATCHES pattern"
3264 	//			// IEEE: pattern - expanded here to avoid conflicts
3265 	|	~l~expr yMATCHES patternNoExpr		{ $<fl>$=$<fl>1; $$ = $1 + " matches " + $3; }
3266 	|	~l~expr yMATCHES ~r~expr		{ $<fl>$=$<fl>1; $$ = $1 + " matches " + $3; }
3267 	//
3268 	//			// IEEE: expression_or_dist - here to avoid reduce problems
3269 	//			// "expr yDIST '{' dist_list '}'"
3270 	|	~l~expr yDIST '{' dist_list '}'		{ $<fl>$=$<fl>1; $$ = $1 + " dist " + $3+"..."+$5; }
3271 	;
3272 
3273 fexpr<str>:			// For use as first part of statement (disambiguates <=)
3274 		BISONPRE_COPY(expr,{s/~l~/f/g; s/~r~/f/g; s/~f__IGNORE~/__IGNORE/g;})	// {copied}
3275 	;
3276 
3277 ev_expr<str>:			// IEEE: event_expression
3278 	//			// for yOR/, see event_expression
3279 	//
3280 	//			// IEEE: [ edge_identifier ] expression [ yIFF expression ]
3281 	//			// expr alone see below
3282 		senitemEdge				{ }
3283 	|	ev_expr yIFF expr			{ }
3284 	//
3285 	//			// IEEE: sequence_instance [ yIFF expression ]
3286 	//			// seq_inst is in expr, so matches senitem rule above
3287 	//
3288 	//			// IEEE: event_expression yOR event_expression
3289 	|	ev_expr yOR ev_expr			{ }
3290 	//			// IEEE: event_expression ',' event_expression
3291 	//			// See real event_expression rule
3292 	//
3293 	//---------------------
3294 	//			// IEEE: expr
3295 	|	BISONPRE_COPY(expr,{s/~l~/ev_/g; s/~r~/ev_/g; s/~p~/ev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g;})	// {copied}
3296 	//
3297 	//			// IEEE: '(' event_expression ')'
3298 	//			// expr:'(' x ')' conflicts with event_expression:'(' event_expression ')'
3299 	//			// so we use a special expression class
3300 	|	'(' event_expression ')'		{ $<fl>$=$<fl>1; $$ = "(...)"; }
3301 	//			// IEEE: From normal expr: '(' expr ':' expr ':' expr ')'
3302 	//			// But must avoid conflict
3303 	|	'(' event_expression ':' expr ':' expr ')'	{ $<fl>$=$<fl>1; $$ = "(...)"; }
3304 	;
3305 
3306 //sexpr: See elsewhere
3307 //pexpr: See elsewhere
3308 
3309 exprOkLvalue<str>:		// expression that's also OK to use as a variable_lvalue
3310 		~l~exprScope				{ $<fl>$=$<fl>1; $$ = $1; }
3311 	//			// IEEE: concatenation/constant_concatenation
3312 	|	'{' cateList '}'			{ $<fl>$=$<fl>1; $$ = "{"+$2+"}"; }
3313 	//			// IEEE: concatenation/constant_concatenation+ constant_range_expression (1800-2009)
3314 	|	'{' cateList '}' '[' expr ']'				{ $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+"]";       NEED_S09($<fl>4,"{}[]"); }
3315 	|	'{' cateList '}' '[' expr ':' expr ']'			{ $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3316 	|	'{' cateList '}' '[' expr yP_PLUSCOLON  expr ']'	{ $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3317 	|	'{' cateList '}' '[' expr yP_MINUSCOLON expr ']'	{ $<fl>$=$<fl>1; $$ = "{"+$2+"}["+$5+$6+$7+"]"; NEED_S09($<fl>4,"{}[]"); }
3318 	//			// IEEE: assignment_pattern_expression
3319 	//			// IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
3320 	//			// We allow more here than the spec requires
3321 	|	~l~exprScope assignment_pattern		{ $<fl>$=$<fl>1; $$=$1+$2; }
3322 	|	data_type assignment_pattern		{ $<fl>$=$<fl>1; $$=$1+$2; }
3323 	|	assignment_pattern			{ $<fl>$=$<fl>1; $$=$1; }
3324 	//
3325 	|	streaming_concatenation			{ $<fl>$=$<fl>1; $$ = $1; }
3326 	;
3327 
3328 fexprOkLvalue<str>:		// exprOkLValue, For use as first part of statement (disambiguates <=)
3329 		BISONPRE_COPY(exprOkLvalue,{s/~l~/f/g})	// {copied}
3330 	;
3331 
3332 sexprOkLvalue<str>:		// exprOkLValue, For use by sequence_expr
3333 		BISONPRE_COPY(exprOkLvalue,{s/~l~/s/g})	// {copied}
3334 	;
3335 
3336 pexprOkLvalue<str>:		// exprOkLValue, For use by property_expr
3337 		BISONPRE_COPY(exprOkLvalue,{s/~l~/p/g})	// {copied}
3338 	;
3339 
3340 ev_exprOkLvalue<str>:		// exprOkLValue, For use by ev_expr
3341 		BISONPRE_COPY(exprOkLvalue,{s/~l~/ev_/g})	// {copied}
3342 	;
3343 
3344 pev_exprOkLvalue<str>:		// exprOkLValue, For use by ev_expr
3345 		BISONPRE_COPY(exprOkLvalue,{s/~l~/pev_/g})	// {copied}
3346 	;
3347 
3348 exprLvalue<str>:		// expression that should be a variable_lvalue
3349 		~f~exprOkLvalue				{ $<fl>$=$<fl>1; $$ = $1; }
3350 	;
3351 
3352 fexprLvalue<str>:		// For use as first part of statement (disambiguates <=)
3353 		BISONPRE_COPY(exprLvalue,{s/~f~/f/g})	// {copied}
3354 	;
3355 
3356 exprScope<str>:			// scope and variable for use to inside an expression
3357 	// 			// Here we've split method_call_root | implicit_class_handle | class_scope | package_scope
3358 	//			// from the object being called and let expr's "." deal with resolving it.
3359 	//			// (note method_call_root was simplified to require a primary in 1800-2009)
3360 	//
3361 	//			// IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
3362 	//			// Or method_call_body without parenthesis
3363 	//			// See also varRefClassBit, which is the non-expr version of most of this
3364 		yTHIS					{ $<fl>$=$<fl>1; $$ = $1; }
3365 	|	idArrayed				{ $<fl>$=$<fl>1; $$ = $1; }
3366 	|	package_scopeIdFollows idArrayed	{ $<fl>$=$<fl>1; $$ = $1+$2; }
3367 	|	class_scopeIdFollows idArrayed		{ $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3368 	|	~l~expr '.' idArrayed			{ $<fl>$=$<fl>1; $$ = $1+"."+$3; PORTNET($<fl>1, $$); }
3369 	//			// expr below must be a "yTHIS"
3370 	|	~l~expr '.' ySUPER			{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3371 	//			// Part of implicit_class_handle
3372 	|	ySUPER					{ $<fl>$=$<fl>1; $$ = $1; }
3373 	;
3374 
3375 fexprScope<str>:		// exprScope, For use as first part of statement (disambiguates <=)
3376 		BISONPRE_COPY(exprScope,{s/~l~/f/g})	// {copied}
3377 	;
3378 
3379 sexprScope<str>:		// exprScope, For use by sequence_expr
3380 		BISONPRE_COPY(exprScope,{s/~l~/s/g})	// {copied}
3381 	;
3382 
3383 pexprScope<str>:		// exprScope, For use by property_expr
3384 		BISONPRE_COPY(exprScope,{s/~l~/p/g})	// {copied}
3385 	;
3386 
3387 ev_exprScope<str>:		// exprScope, For use by ev_expr
3388 		BISONPRE_COPY(exprScope,{s/~l~/ev_/g})	// {copied}
3389 	;
3390 
3391 pev_exprScope<str>:		// exprScope, For use by ev_expr
3392 		BISONPRE_COPY(exprScope,{s/~l~/pev_/g})	// {copied}
3393 	;
3394 
3395 // Generic expressions
3396 exprOrDataType<str>:		// expr | data_type: combined to prevent conflicts
3397 		expr					{ $<fl>$=$<fl>1; $$ = $1; }
3398 	//			// data_type includes id that overlaps expr, so special flavor
3399 	|	data_type				{ $<fl>$=$<fl>1; $$ = $1; }
3400 	//			// not in spec, but needed for $past(sig,1,,@(posedge clk))
3401 	|	event_control				{ $$ = "event_control"; }
3402 	;
3403 
3404 exprOrDataTypeOrMinTypMax<str>:	// exprOrDataType or mintypmax_expression
3405 		expr					{ $<fl>$=$<fl>1; $$ = $1; }
3406 	|	expr ':' expr ':' expr			{ $<fl>$=$<fl>1; $$ = $1+$2+$3+$4+$5; }
3407 	//			// data_type includes id that overlaps expr, so special flavor
3408 	|	data_type				{ $<fl>$=$<fl>1; $$ = $1; }
3409 	//			// not in spec, but needed for $past(sig,1,,@(posedge clk))
3410 	|	event_control				{ $$ = "event_control"; }
3411 	;
3412 
3413 
3414 cateList<str>:
3415 	//			// Not just 'expr' to prevent conflict via stream_concOrExprOrType
3416 		stream_expression			{ $<fl>$=$<fl>1; $$ = $1; PIN_CONCAT_APPEND($1); }
3417 	|	cateList ',' stream_expression		{ $<fl>$=$<fl>1; $$ = $1+","+$3; PIN_CONCAT_APPEND($3); }
3418 	;
3419 
3420 exprOrDataTypeList<str>:
3421 		exprOrDataType				{ $<fl>$=$<fl>1; $$ = $1; }
3422 	|	exprOrDataTypeList ',' exprOrDataType	{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3423 	|	exprOrDataTypeList ','			{ $<fl>$=$<fl>1; $$ = $1+","; }   // Verilog::Parser only: ,, is ok
3424 	;
3425 
3426 list_of_argumentsE<str>:	// IEEE: [list_of_arguments]
3427 	//			// See comments under funcRef
3428 		argsDottedList				{ $<fl>$=$<fl>1; $$=$1; }
3429 	|	argsExprListE				{ $<fl>$=$<fl>1; $$=$1; }
3430 	|	argsExprListE ',' argsDottedList	{ $<fl>$=$<fl>1; $$=$1+","+$3; }
3431 	;
3432 
3433 pev_list_of_argumentsE<str>:	// IEEE: [list_of_arguments] - pev_expr at bottom
3434 	//			// See comments under funcRef
3435 		pev_argsDottedList			{ $<fl>$=$<fl>1; $$=$1; }
3436 	|	pev_argsExprListE			{ $<fl>$=$<fl>1; $$=$1; }
3437 	|	pev_argsExprListE ',' pev_argsDottedList	{ $<fl>$=$<fl>1; $$=$1+","+$3; }
3438 	;
3439 
3440 argsExprList<str>:		// IEEE: part of list_of_arguments (used where ,, isn't legal)
3441 		expr					{ $<fl>$=$<fl>1; $$ = $1; }
3442 	|	argsExprList ',' expr			{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3443 	;
3444 
3445 argsExprListE<str>:		// IEEE: part of list_of_arguments
3446 		argsExprOneE				{ $<fl>$=$<fl>1; $$ = $1; }
3447 	|	argsExprListE ',' argsExprOneE		{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3448 	;
3449 
3450 pev_argsExprListE<str>:		// IEEE: part of list_of_arguments - pev_expr at bottom
3451 		pev_argsExprOneE			{ $<fl>$=$<fl>1; $$ = $1; }
3452 	|	pev_argsExprListE ',' pev_argsExprOneE	{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3453 	;
3454 
3455 argsExprOneE<str>:		// IEEE: part of list_of_arguments
3456 		/*empty*/				{ $$ = ""; }	// ,, is legal in list_of_arguments
3457 	|	expr					{ $<fl>$=$<fl>1; $$ = $1; }
3458 	;
3459 
3460 pev_argsExprOneE<str>:		// IEEE: part of list_of_arguments - pev_expr at bottom
3461 		/*empty*/				{ $$ = ""; }	// ,, is legal in list_of_arguments
3462 	|	pev_expr				{ $<fl>$=$<fl>1; $$ = $1; }
3463 	;
3464 
3465 argsDottedList<str>:		// IEEE: part of list_of_arguments
3466 		argsDotted				{ $<fl>$=$<fl>1; $$=$1; }
3467 	|	argsDottedList ',' argsDotted		{ $<fl>$=$<fl>1; $$=$1+","+$3; }
3468 	;
3469 
3470 pev_argsDottedList<str>:	// IEEE: part of list_of_arguments - pev_expr at bottom
3471 		pev_argsDotted				{ $<fl>$=$<fl>1; $$=$1; }
3472 	|	pev_argsDottedList ',' pev_argsDotted	{ $<fl>$=$<fl>1; $$=$1+","+$3; }
3473 	;
3474 
3475 argsDotted<str>:		// IEEE: part of list_of_arguments
3476 		'.' idAny '(' ')'			{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3477 	|	'.' idAny '(' expr ')'			{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3478 	;
3479 
3480 pev_argsDotted<str>:		// IEEE: part of list_of_arguments - pev_expr at bottom
3481 		'.' idAny '(' ')'			{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4; }
3482 	|	'.' idAny '(' pev_expr ')'		{ $<fl>$=$<fl>1; $$=$1+$2+$3+$4+$5; }
3483 	;
3484 
3485 streaming_concatenation<str>:	// ==IEEE: streaming_concatenation
3486 	//	 		// Need to disambiguate {<< expr-{ ... expr-} stream_concat }
3487 	//			// From                 {<< stream-{ ... stream-} }
3488 	//			// Likewise simple_type's idScoped from constExpr's idScope
3489 	//			// Thus we allow always any two operations.  Sorry
3490 	//			// IEEE: "'{' yP_SL/R             stream_concatenation '}'"
3491 	//			// IEEE: "'{' yP_SL/R simple_type stream_concatenation '}'"
3492 	//			// IEEE: "'{' yP_SL/R constExpr	  stream_concatenation '}'"
3493 		'{' yP_SLEFT              stream_concOrExprOrType '}'	{ $<fl>$=$<fl>1; $$="{<<"+$3+"}"; }
3494 	|	'{' yP_SRIGHT             stream_concOrExprOrType '}'	{ $<fl>$=$<fl>1; $$="{>>"+$3+"}"; }
3495 	|	'{' yP_SLEFT  stream_concOrExprOrType stream_concatenation '}'	{ $<fl>$=$<fl>1; $$="{<<"+$3+" "+$4+"}"; }
3496 	|	'{' yP_SRIGHT stream_concOrExprOrType stream_concatenation '}'	{ $<fl>$=$<fl>1; $$="{>>"+$3+" "+$4+"}"; }
3497 	;
3498 
3499 stream_concOrExprOrType<str>:	// IEEE: stream_concatenation | slice_size:simple_type | slice_size:constExpr
3500 		cateList				{ $<fl>$=$<fl>1; $$=$1; }
3501 	|	simple_type				{ $<fl>$=$<fl>1; $$=$1; }
3502 	//			// stream_concatenation found via cateList:stream_expr:'{-normal-concat'
3503 	//			// simple_typeRef found via cateList:stream_expr:expr:id
3504 	//			// constant_expression found via cateList:stream_expr:expr
3505 	;
3506 
3507 stream_concatenation<str>:	// ==IEEE: stream_concatenation
3508 		'{' stream_expressionList '}'		{ $<fl>$=$<fl>1; $$="{"+$2+"}"; }
3509 	;
3510 
3511 stream_expressionList<str>:	// IEEE: part of stream_concatenation
3512 		stream_expression				{ $<fl>$=$<fl>1; $$=$1; }
3513 	|	stream_expressionList ',' stream_expression	{ $<fl>$=$<fl>1; $$=$1+","+$3; }
3514 	;
3515 
3516 stream_expression<str>:		// ==IEEE: stream_expression
3517 	//			// IEEE: array_range_expression expanded below
3518 		expr					{ $<fl>$=$<fl>1; $$=$1; }
3519 	|	expr yWITH__BRA '[' expr ']'		{ $<fl>$=$<fl>1; $$=$1; }
3520 	|	expr yWITH__BRA '[' expr ':' expr ']'	{ $<fl>$=$<fl>1; $$=$1; }
3521 	|	expr yWITH__BRA '[' expr yP_PLUSCOLON  expr ']'	{ $<fl>$=$<fl>1; $$=$1; }
3522 	|	expr yWITH__BRA '[' expr yP_MINUSCOLON expr ']'	{ $<fl>$=$<fl>1; $$=$1; }
3523 	;
3524 
3525 //************************************************
3526 // Gate declarations
3527 
3528 // We can't tell between UDPs and modules as they aren't declared yet.
3529 // For simplicity, assume everything is a module, perhaps nameless,
3530 // and deal with it later.
3531 
3532 // IEEE: cmos_switchtype + enable_gatetype + mos_switchtype
3533 //	+ n_input_gatetype + n_output_gatetype + pass_en_switchtype
3534 //	+ pass_switchtype
3535 gateKwd<str>:
3536 		ygenGATE				{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3537 	|	yAND					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3538 	| 	yBUF					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3539 	|	yNAND					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3540 	|	yNOR					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3541 	|	yNOT					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3542 	|	yOR					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3543 	|	yXNOR					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3544 	|	yXOR					{ $<fl>$=$<fl>1; INSTPREP($1,0,0); }
3545 	;
3546 
3547 // This list is also hardcoded in VParseLex.l
3548 strength:			// IEEE: strength0+strength1 - plus HIGHZ/SMALL/MEDIUM/LARGE
3549 		ygenSTRENGTH				{ }
3550 	|	ySUPPLY0				{ }
3551 	|	ySUPPLY1				{ }
3552 	;
3553 
3554 strengthSpecE:			// IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
3555 		/* empty */				{ }
3556 	|	strengthSpec				{ }
3557 	;
3558 
3559 strengthSpec:			// IEEE: drive_strength + pullup_strength + pulldown_strength + charge_strength - plus empty
3560 		yP_PAR__STRENGTH strength ')'			{ }
3561 	|	yP_PAR__STRENGTH strength ',' strength ')'	{ }
3562 	;
3563 
3564 //************************************************
3565 // Tables
3566 
3567 combinational_body:		// IEEE: combinational_body + sequential_body
3568 		yTABLE tableJunkList yENDTABLE		{ }
3569 	;
3570 
3571 tableJunkList:
3572 		tableJunk 				{ } /* ignored */
3573 	|	tableJunkList tableJunk			{ } /* ignored */
3574 	;
3575 
3576 tableJunk:
BISONPRE_NOT(yTABLE,yENDTABLE)3577 		BISONPRE_NOT(yTABLE,yENDTABLE)		{ }
3578 	|	yTABLE tableJunk yENDTABLE		{ }
3579 	|	error {}
3580 	;
3581 
3582 //************************************************
3583 // Specify
3584 
3585 specify_block:			// ==IEEE: specify_block
3586 		ySPECIFY specifyJunkList yENDSPECIFY	{ }
3587 	|	ySPECIFY yENDSPECIFY			{ }
3588 	;
3589 
3590 specifyJunkList:
3591 		specifyJunk 				{ } /* ignored */
3592 	|	specifyJunkList specifyJunk		{ } /* ignored */
3593 	;
3594 
3595 specifyJunk:
BISONPRE_NOT(ySPECIFY,yENDSPECIFY)3596 		BISONPRE_NOT(ySPECIFY,yENDSPECIFY)	{ }
3597 	|	ySPECIFY specifyJunk yENDSPECIFY	{ }
3598 	|	error {}
3599 	;
3600 
3601 specparam_declaration:		// ==IEEE: specparam_declaration
3602 		ySPECPARAM junkToSemiList ';'		{ }
3603 	;
3604 
3605 junkToSemiList:
3606 		junkToSemi 				{ } /* ignored */
3607 	|	junkToSemiList junkToSemi		{ } /* ignored */
3608 	;
3609 
3610 junkToSemi:
3611 		BISONPRE_NOT(';',yENDSPECIFY,yENDMODULE)	{ }
3612 	|	error {}
3613 	;
3614 
3615 //************************************************
3616 // IDs
3617 
3618 id<str>:
3619 		yaID__ETC				{ $<fl>$=$<fl>1; $$=$1; }
3620 	;
3621 
3622 idAny<str>:			// Any kind of identifier
3623 		yaID__aPACKAGE				{ $<fl>$=$<fl>1; $$=$1; }
3624 	|	yaID__aTYPE				{ $<fl>$=$<fl>1; $$=$1; }
3625 	|	yaID__ETC				{ $<fl>$=$<fl>1; $$=$1; }
3626 	;
3627 
3628 idSVKwd<str>:			// Warn about non-forward compatible Verilog 2001 code
3629 	//			// yBIT, yBYTE won't work here as causes conflicts
3630 		yDO					{ $<fl>$=$<fl>1; $$=$1; ERRSVKWD($<fl>1,$$); }
3631 	|	yFINAL					{ $<fl>$=$<fl>1; $$=$1; ERRSVKWD($<fl>1,$$); }
3632 	;
3633 
3634 variable_lvalue<str>:		// IEEE: variable_lvalue or net_lvalue
3635 	//			// Note many variable_lvalue's must use exprOkLvalue when arbitrary expressions may also exist
3636 		idClassSel				{ $<fl>$=$<fl>1; $$ = $1; }
3637 	|	'{' variable_lvalueConcList '}'		{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3638 	//			// IEEE: [ assignment_pattern_expression_type ] assignment_pattern_variable_lvalue
3639 	//			// We allow more assignment_pattern_expression_types then strictly required
3640 	|	data_type  yP_TICKBRA variable_lvalueList '}'	{ $<fl>$=$<fl>1; $$ = $1+" "+$2+$3+$4; }
3641 	|	idClassSel yP_TICKBRA variable_lvalueList '}'	{ $<fl>$=$<fl>1; $$ = $1+" "+$2+$3+$4; }
3642 	|	/**/       yP_TICKBRA variable_lvalueList '}'	{ $<fl>$=$<fl>1; $$ = $1+$2+$3; }
3643 	|	streaming_concatenation			{ $<fl>$=$<fl>1; $$ = $1; }
3644 	;
3645 
3646 variable_lvalueConcList<str>:	// IEEE: part of variable_lvalue: '{' variable_lvalue { ',' variable_lvalue } '}'
3647 		variable_lvalue					{ $<fl>$=$<fl>1; $$ = $1; }
3648 	|	variable_lvalueConcList ',' variable_lvalue	{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3649 	;
3650 
3651 variable_lvalueList<str>:	// IEEE: part of variable_lvalue: variable_lvalue { ',' variable_lvalue }
3652 		variable_lvalue				{ $<fl>$=$<fl>1; $$ = $1; }
3653 	|	variable_lvalueList ',' variable_lvalue	{ $<fl>$=$<fl>1; $$ = $1+","+$3; }
3654 	;
3655 
3656 idClassSel<str>:		// Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
3657 		idDotted				{ $<fl>$=$<fl>1; $$ = $1; }
3658 	//			// IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
3659 	|	yTHIS '.' idDotted			{ $<fl>$=$<fl>1; $$ = "this."+$3; }
3660 	|	ySUPER '.' idDotted			{ $<fl>$=$<fl>1; $$ = "super."+$3; }
3661 	|	yTHIS '.' ySUPER '.' idDotted		{ $<fl>$=$<fl>1; $$ = "this.super."+$3; }
3662 	//			// Expanded: package_scope idDotted
3663 	|	class_scopeIdFollows idDotted		{ $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3664 	|	package_scopeIdFollows idDotted		{ $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3665 	;
3666 
3667 idClassForeach<str>:		// Misc Ref to dotted, and/or arrayed, no bit range for foreach statement
3668 	//			// We can't just use the more general idClassSel
3669 	//			// because ,'s are allowed in the []'s
3670 		idDottedForeach				{ $<fl>$=$<fl>1; $$ = $1; }
3671 	//			// IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
3672 	|	yTHIS '.' idDottedForeach		{ $<fl>$=$<fl>1; $$ = "this."+$3; }
3673 	|	ySUPER '.' idDottedForeach		{ $<fl>$=$<fl>1; $$ = "super."+$3; }
3674 	|	yTHIS '.' ySUPER '.' idDottedForeach	{ $<fl>$=$<fl>1; $$ = "this.super."+$3; }
3675 	//			// Expanded: package_scope idDotted
3676 	|	class_scopeIdFollows idDottedForeach	{ $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3677 	|	package_scopeIdFollows idDottedForeach	{ $<fl>$=$<fl>1; $$ = $<str>1+$2; }
3678 	;
3679 
3680 hierarchical_identifierList:	// IEEE: part of wait_statement
3681 		hierarchical_identifier			{ }
3682 	|	hierarchical_identifierList ',' hierarchical_identifier		{ }
3683 	;
3684 
3685 hierarchical_identifierBit:	// IEEE: "hierarchical_identifier bit_select"
3686 	//			// Not in grammar but "this." believed legal here
3687 		idClassSel				{ }
3688 	;
3689 
3690 hierarchical_identifier<str>:	// IEEE: hierarchical_identifier, including extra bit_select
3691 	//			//	  +hierarchical_parameter_identifier
3692 	//			// Not in grammar but "this." believed legal here
3693 		idClassSel				{ $<fl>$=$<fl>1; $$ = $1; }
3694 	;
3695 
3696 idDotted<str>:
3697 		yD_ROOT '.' idDottedMore		{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3698 	|	idDottedMore		 		{ $<fl>$=$<fl>1; $$ = $1; }
3699 	;
3700 
3701 idDottedForeach<str>:
3702 		yD_ROOT '.' idDottedForeachMore		{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3703 	|	idDottedForeachMore	 		{ $<fl>$=$<fl>1; $$ = $1; }
3704 	;
3705 
3706 idDottedMore<str>:
3707 		idArrayed 				{ $<fl>$=$<fl>1; $$ = $1; }
3708 	|	idDottedMore '.' idArrayed		{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3709 	;
3710 
3711 idDottedForeachMore<str>:
3712 		idForeach 				{ $<fl>$=$<fl>1; $$ = $1; }
3713 	|	idDottedForeachMore '.' idForeach	{ $<fl>$=$<fl>1; $$ = $1+"."+$3; }
3714 	;
3715 
3716 // Single component of dotted path, maybe [#].
3717 // Due to lookahead constraints, we can't know if [:] or [+:] are valid (last dotted part),
3718 // we'll assume so and cleanup later.
3719 // id below includes:
3720 //	 enum_identifier
3721 idArrayed<str>:			// IEEE: id + select
3722 		id					{ $<fl>$=$<fl>1; $$ = $1; PORTNET($<fl>1, $1);}
3723 	//			// IEEE: part_select_range/constant_part_select_range
3724 	|	idArrayed '[' expr ']'				{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"]"; PORTRANGE($3, $3);}
3725 	|	idArrayed '[' constExpr ':' constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+":"+$5+"]"; PORTRANGE($3, $5);}
3726 	//	 		// IEEE: indexed_range/constant_indexed_range
3727 	|	idArrayed '[' expr yP_PLUSCOLON  constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"+:"+$5+"]"; }
3728 	|	idArrayed '[' expr yP_MINUSCOLON constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"-:"+$5+"]"; }
3729 	;
3730 
3731 idForeach<str>:			// IEEE: id + select + [loop_variables]
3732 	//			// Merge of foreach and idArrayed to prevent conflict
3733 		id					{ $<fl>$=$<fl>1; $$ = $1; }
3734 	//			// IEEE: part_select_range/constant_part_select_range
3735 	|	idForeach '[' expr ']'				{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"]"; }
3736 	|	idForeach '[' constExpr ':' constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+":"+$5+"]"; }
3737 	//	 		// IEEE: indexed_range/constant_indexed_range
3738 	|	idForeach '[' expr yP_PLUSCOLON  constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"+:"+$5+"]"; }
3739 	|	idForeach '[' expr yP_MINUSCOLON constExpr ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+"-:"+$5+"]"; }
3740 	//			// IEEE: part of foreach: [ loop_variables ]
3741 	|	idForeach '[' expr ',' loop_variables ']'	{ $<fl>$=$<fl>1; $$ = $1+"["+$3+","+$5+"]"; }
3742 	;
3743 
3744 strAsInt<str>:
3745 		yaSTRING				{ $<fl>$=$<fl>1; $$ = $1; }
3746 	;
3747 
3748 endLabelE:
3749 		/* empty */				{ }
3750 	|	':' idAny				{ }
3751 	|	':' yNEW__ETC				{ }
3752 	;
3753 
3754 //************************************************
3755 // Clocking
3756 
3757 clocking_declaration:		// IEEE: clocking_declaration
3758 		clockingFront clocking_event ';'
3759 			clocking_itemListE yENDCLOCKING endLabelE { PARSEP->symPopScope(VAstType::CLOCKING); }
3760 	//			// global clocking below - we allow item list, though not in grammar
3761 	;
3762 
3763 clockingFront:			// IEEE: part of class_declaration
3764 		yCLOCKING				{ PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3765 	|	yCLOCKING idAny/*clocking_identifier*/	{ PARSEP->symPushNew(VAstType::CLOCKING,$2); }
3766 	|	yDEFAULT yCLOCKING			{ PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3767 	|	yDEFAULT yCLOCKING idAny/*clocking_identifier*/	{ PARSEP->symPushNew(VAstType::CLOCKING,$3); }
3768 	|	yGLOBAL__CLOCKING yCLOCKING			{ PARSEP->symPushNewAnon(VAstType::CLOCKING); }
3769 	|	yGLOBAL__CLOCKING yCLOCKING idAny/*clocking_identifier*/	{ PARSEP->symPushNew(VAstType::CLOCKING,$3); }
3770 	;
3771 
3772 clocking_event:			// ==IEEE: clocking_event
3773 		'@' id					{ }
3774 	|	'@' '(' event_expression ')'		{ }
3775 	;
3776 
3777 clocking_itemListE:
3778 		/* empty */				{ }
3779 	|	clocking_itemList			{ }
3780 	;
3781 
3782 clocking_itemList:		// IEEE: [ clocking_item ]
3783 		clocking_item				{ }
3784 	|	clocking_itemList clocking_item		{ }
3785 	;
3786 
3787 clocking_item:			// ==IEEE: clocking_item
3788 		yDEFAULT default_skew ';'		{ }
3789 	|	clocking_direction list_of_clocking_decl_assign ';'	{ }
3790 	|	assertion_item_declaration		{ }
3791 	;
3792 
3793 default_skew:			// ==IEEE: default_skew
3794 		yINPUT clocking_skew			{ }
3795 	|	yOUTPUT clocking_skew			{ }
3796 	|	yINPUT clocking_skew yOUTPUT clocking_skew	{ }
3797 	;
3798 
3799 clocking_direction:		// ==IEEE: clocking_direction
3800 		yINPUT clocking_skewE			{ }
3801 	|	yOUTPUT clocking_skewE			{ }
3802 	|	yINPUT clocking_skewE yOUTPUT clocking_skewE	{ }
3803 	|	yINOUT					{ }
3804 	;
3805 
3806 list_of_clocking_decl_assign:	// ==IEEE: list_of_clocking_decl_assign
3807 		clocking_decl_assign			{ }
3808 	|	list_of_clocking_decl_assign ',' clocking_decl_assign	{ }
3809 	;
3810 
3811 clocking_decl_assign:		// ==IEEE: clocking_decl_assign
3812 		idAny/*new-signal_identifier*/		{ }
3813 	|	idAny/*new-signal_identifier*/ '=' expr	{ }
3814 	;
3815 
3816 clocking_skewE:			// IEEE: [clocking_skew]
3817 		/* empty */				{ }
3818 	|	clocking_skew				{ }
3819 	;
3820 
3821 clocking_skew:			// ==IEEE: clocking_skew
3822 		yPOSEDGE				{ }
3823 	|	yPOSEDGE delay_control			{ }
3824 	|	yNEGEDGE				{ }
3825 	|	yNEGEDGE delay_control			{ }
3826 	|	yEDGE					{ NEED_S09($<fl>1,"edge"); }
3827 	|	yEDGE delay_control			{ NEED_S09($<fl>1,"edge"); }
3828 	|	delay_control				{ }
3829 	;
3830 
3831 cycle_delay:			// ==IEEE: cycle_delay
3832 		yP_POUNDPOUND yaINTNUM			{ }
3833 	|	yP_POUNDPOUND id			{ }
3834 	|	yP_POUNDPOUND '(' expr ')'		{ }
3835 	;
3836 
3837 //************************************************
3838 // Asserts
3839 
3840 assertion_item_declaration:	// ==IEEE: assertion_item_declaration
3841 		property_declaration			{ }
3842 	|	sequence_declaration			{ }
3843 	|	let_declaration				{ }
3844 	;
3845 
3846 assertion_item:			// ==IEEE: assertion_item
3847 		concurrent_assertion_item		{ }
3848 	|	deferred_immediate_assertion_item	{ }
3849 	;
3850 
3851 deferred_immediate_assertion_item:	// ==IEEE: deferred_immediate_assertion_item
3852 		deferred_immediate_assertion_statement	{ }
3853 	|	id/*block_identifier*/ ':' deferred_immediate_assertion_statement	{ }
3854 	;
3855 
3856 procedural_assertion_statement:	// ==IEEE: procedural_assertion_statement
3857 		concurrent_assertion_statement		{ }
3858 	|	immediate_assertion_statement		{ }
3859 	//			// IEEE: checker_instantiation
3860 	//			// Unlike modules, checkers are the only "id id (...)" form in statements.
3861 	|	checker_instantiation			{ }
3862 	;
3863 
3864 immediate_assertion_statement:	// ==IEEE: immediate_assertion_statement
3865 		simple_immediate_assertion_statement	{ }
3866 	|	deferred_immediate_assertion_statement	{ }
3867 	;
3868 
3869 simple_immediate_assertion_statement:	// ==IEEE: simple_immediate_assertion_statement
3870 	//			// IEEE: simple_immediate_assert_statement
3871 		yASSERT '(' expr ')' action_block	{ }
3872 	//			// IEEE: simple_immediate_assume_statement
3873 	|	yASSUME '(' expr ')' action_block	{ }
3874 	//			// IEEE: simple_immediate_cover_statement
3875 	|	yCOVER '(' expr ')' stmt 		{ }
3876 	;
3877 
3878 final_zero:			// IEEE: part of deferred_immediate_assertion_statement
3879 		'#' yaINTNUM				{ }  // yaINTNUM is always a '0'
3880 	//			// 1800-2012:
3881 	|	yFINAL					{ }
3882 	;
3883 
3884 deferred_immediate_assertion_statement<nodep>:	// ==IEEE: deferred_immediate_assertion_statement
3885 	//			// IEEE: deferred_immediate_assert_statement
3886 		yASSERT final_zero '(' expr ')' action_block	{ }
3887 	//			// IEEE: deferred_immediate_assume_statement
3888 	|	yASSUME final_zero '(' expr ')' action_block	{ }
3889 	//			// IEEE: deferred_immediate_cover_statement
3890 	|	yCOVER  final_zero '(' expr ')' stmt		{ }
3891 	;
3892 
3893 expect_property_statement:	// ==IEEE: expect_property_statement
3894 		yEXPECT '(' property_spec ')' action_block	{ }
3895 	;
3896 
3897 concurrent_assertion_item:	// IEEE: concurrent_assertion_item
3898 		concurrent_assertion_statement		{ }
3899 	|	id/*block_identifier*/ ':' concurrent_assertion_statement	{ }
3900 	//			// IEEE: checker_instantiation
3901 	//			// identical to module_instantiation; see etcInst
3902 	;
3903 
3904 concurrent_assertion_statement:	// ==IEEE: concurrent_assertion_statement
3905 	//			// IEEE: assert_property_statement
3906 		yASSERT yPROPERTY '(' property_spec ')' action_block	{ }
3907 	//			// IEEE: assume_property_statement
3908 	|	yASSUME yPROPERTY '(' property_spec ')' action_block	{ }
3909 	//			// IEEE: cover_property_statement
3910 	|	yCOVER yPROPERTY '(' property_spec ')' stmtBlock	{ }
3911 	//			// IEEE: cover_sequence_statement
3912 	|	yCOVER ySEQUENCE '(' sexpr ')' stmt	{ }
3913 	//			// IEEE: yCOVER ySEQUENCE '(' clocking_event sexpr ')' stmt
3914 	//			// sexpr already includes "clocking_event sexpr"
3915 	|	yCOVER ySEQUENCE '(' clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt	{ }
3916 	|	yCOVER ySEQUENCE '(' yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' sexpr ')' stmt	{ }
3917 	//			// IEEE: restrict_property_statement
3918 	|	yRESTRICT yPROPERTY '(' property_spec ')' ';'		{ }
3919 	;
3920 
3921 property_declaration:		// ==IEEE: property_declaration
3922 		property_declarationFront property_port_listE ';' property_declarationBody
3923 			yENDPROPERTY endLabelE
3924 			{ PARSEP->symPopScope(VAstType::PROPERTY); }
3925 	;
3926 
3927 property_declarationFront:	// IEEE: part of property_declaration
3928 		yPROPERTY idAny/*property_identifier*/
3929 			{ PARSEP->symPushNew(VAstType::PROPERTY,$2); }
3930 	;
3931 
3932 property_port_listE:		// IEEE: [ ( [ property_port_list ] ) ]
3933 		/* empty */				{ }
3934 	|	'(' {VARRESET_LIST(""); VARIO("input"); } property_port_list ')'
3935 			{ VARRESET_NONLIST(""); }
3936 	;
3937 
3938 property_port_list:		// ==IEEE: property_port_list
3939 		property_port_item			{ }
3940 	|	property_port_list ',' property_port_item	{ }
3941 	;
3942 
3943 property_port_item:		// IEEE: property_port_item/sequence_port_item
3944 	//			// Merged in sequence_port_item
3945 	//			// IEEE: property_lvar_port_direction ::= yINPUT
3946 	//			// prop IEEE: [ yLOCAL [ yINPUT ] ] property_formal_type
3947 	//			//	     id {variable_dimension} [ '=' property_actual_arg ]
3948 	//			// seq IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
3949 	//			//           id {variable_dimension} [ '=' sequence_actual_arg ]
3950 		property_port_itemFront property_port_itemAssignment { }
3951 	;
3952 
3953 property_port_itemFront:	// IEEE: part of property_port_item/sequence_port_item
3954 	//
3955 		property_port_itemDirE property_formal_typeNoDt		{ VARDTYPE($2); }
3956 	//			// data_type_or_implicit
3957 	|	property_port_itemDirE data_type           	{ VARDTYPE($2); }
3958 	|	property_port_itemDirE yVAR data_type      	{ VARDTYPE($3); }
3959 	|	property_port_itemDirE yVAR implicit_typeE 	{ VARDTYPE($3); }
3960 	|	property_port_itemDirE signingE rangeList  	{ VARDTYPE(SPACED($2,$3)); }
3961 	|	property_port_itemDirE /*implicit*/        	{ /*VARDTYPE-same*/ }
3962 	;
3963 
3964 property_port_itemAssignment:	// IEEE: part of property_port_item/sequence_port_item/checker_port_direction
3965 		portSig variable_dimensionListE		{ VARDONE($<fl>1, $1, $2, ""); PINNUMINC(); }
3966 	|	portSig variable_dimensionListE '=' property_actual_arg
3967 			{ VARDONE($<fl>1, $1, $2, $4); PINNUMINC(); }
3968 	;
3969 
3970 property_port_itemDirE:
3971 		/* empty */				{ }
3972 	|	yLOCAL__ETC				{ }
3973 	|	yLOCAL__ETC port_direction		{ }
3974 	;
3975 
3976 property_declarationBody:	// IEEE: part of property_declaration
3977 		assertion_variable_declarationList property_statement_spec	{ }
3978 	//			// IEEE-2012: Incorectly hasyCOVER ySEQUENCE then property_spec here.
3979 	//			// Fixed in IEEE 1800-2017
3980 	|	property_statement_spec			{ }
3981 	;
3982 
3983 assertion_variable_declarationList: // IEEE: part of assertion_variable_declaration
3984 		assertion_variable_declaration		{ }
3985 	|	assertion_variable_declarationList assertion_variable_declaration	{ }
3986 	;
3987 
3988 sequence_declaration:		// ==IEEE: sequence_declaration
3989 		sequence_declarationFront sequence_port_listE ';' sequence_declarationBody
3990 			yENDSEQUENCE endLabelE
3991 			{ PARSEP->symPopScope(VAstType::SEQUENCE); }
3992 	;
3993 
3994 sequence_declarationFront:	// IEEE: part of sequence_declaration
3995 		ySEQUENCE idAny/*new_sequence*/
3996 			{ PARSEP->symPushNew(VAstType::SEQUENCE,$2); }
3997 	;
3998 
3999 sequence_port_listE:		// IEEE: [ ( [ sequence_port_list ] ) ]
4000 	//			// IEEE: sequence_lvar_port_direction ::= yINPUT | yINOUT | yOUTPUT
4001 	//			// IEEE: [ yLOCAL [ sequence_lvar_port_direction ] ] sequence_formal_type
4002 	//			//           id {variable_dimension} [ '=' sequence_actual_arg ]
4003 	//			// All this is almost identically the same as a property.
4004 	//			// Difference is only yINOUT/yOUTPUT (which might be added to 1800-2012)
4005 	//			// and yPROPERTY.  So save some work.
4006 		property_port_listE			{ }
4007 	;
4008 
4009 property_formal_typeNoDt<str>:	// IEEE: property_formal_type (w/o implicit)
4010 		sequence_formal_typeNoDt		{ $$ = $1; }
4011 	|	yPROPERTY				{ $$ = "property"; }
4012 	;
4013 
4014 sequence_formal_typeNoDt<str>:	// ==IEEE: sequence_formal_type (w/o data_type_or_implicit)
4015 	//			// IEEE: data_type_or_implicit
4016 	//			// implicit expanded where used
4017 		ySEQUENCE				{ $$ = "sequence"; }
4018 	//			// IEEE-2009: yEVENT
4019 	//			// already part of data_type.  Removed in 1800-2012.
4020 	|	yUNTYPED				{ $$ = "untyped"; }
4021 	;
4022 
4023 sequence_declarationBody:	// IEEE: part of sequence_declaration
4024 	//			// 1800-2012 makes ';' optional
4025 		assertion_variable_declarationList sexpr	{ }
4026 	|	assertion_variable_declarationList sexpr ';'	{ }
4027 	|	sexpr					{ }
4028 	|	sexpr ';'				{ }
4029 	;
4030 
4031 property_spec:			// IEEE: property_spec
4032 	//			// IEEE: [clocking_event ] [ yDISABLE yIFF '(' expression_or_dist ')' ] property_expr
4033 	//			// matches property_spec: "clocking_event property_expr" so we put it there
4034 		yDISABLE yIFF '(' expr ')' pexpr	{ }
4035 	|	pexpr			 		{ }
4036 	;
4037 
4038 property_statement_spec:	// ==IEEE: property_statement_spec
4039 	//			// IEEE: [ clocking_event ] [ yDISABLE yIFF '(' expression_or_dist ')' ] property_statement
4040 		property_statement			{ }
4041 	|	yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement	{ }
4042 	//			// IEEE: clocking_event property_statement
4043 	//			// IEEE: clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statement
4044 	//			// Both overlap pexpr:"clocking_event pexpr"  the difference is
4045 	//			// property_statement:property_statementCaseIf so replicate it
4046 	|	clocking_event property_statementCaseIf	{ }
4047 	|	clocking_event yDISABLE yIFF '(' expr/*expression_or_dist*/ ')' property_statementCaseIf	{ }
4048 	;
4049 
4050 property_statement:		// ==IEEE: property_statement
4051 	//			// Doesn't make sense to have "pexpr ;" in pexpr rule itself, so we split out case/if
4052 		pexpr ';'				{ }
4053 	//			// Note this term replicated in property_statement_spec
4054 	//			// If committee adds terms, they may need to be there too.
4055 	|	property_statementCaseIf		{ }
4056 	;
4057 
4058 property_statementCaseIf:	// IEEE: property_statement - minus pexpr
4059 		yCASE '(' expr/*expression_or_dist*/ ')' property_case_itemList yENDCASE	{ }
4060 	|	yCASE '(' expr/*expression_or_dist*/ ')' yENDCASE		{ }
4061 	|	yIF '(' expr/*expression_or_dist*/ ')' pexpr  %prec prLOWER_THAN_ELSE	{ }
4062 	|	yIF '(' expr/*expression_or_dist*/ ')' pexpr yELSE pexpr	{ }
4063 	;
4064 
4065 property_case_itemList:		// IEEE: {property_case_item}
4066 		property_case_item			{ }
4067 	|	property_case_itemList ',' property_case_item	{ }
4068 	;
4069 
4070 property_case_item:		// ==IEEE: property_case_item
4071 	//			// IEEE: expression_or_dist { ',' expression_or_dist } ':' property_statement
4072 	//			// IEEE 1800-2012 changed from property_statement to property_expr
4073 	//			// IEEE 1800-2017 changed to require the semicolon
4074 		caseCondList ':' pexpr			{ }
4075 	|	caseCondList ':' pexpr ';'		{ }
4076 	|	yDEFAULT pexpr				{ }
4077 	|	yDEFAULT ':' pexpr ';'			{ }
4078 	;
4079 
4080 pev_expr<str>:			// IEEE: property_actual_arg | expr
4081 	//			//       which expands to pexpr | event_expression
4082 	//			// Used in port and function calls, when we can't know yet if something
4083 	//			// is a function/sequence/property or instance/checker pin.
4084 	//
4085 	//			// '(' pev_expr ')'
4086 	//			// Already in pexpr
4087 	//			// IEEE: event_expression ',' event_expression
4088 	//			// ','s are legal in event_expressions, but parens required to avoid conflict with port-sep-,
4089 	//			// IEEE: event_expression yOR event_expression
4090 	//			// Already in pexpr - needs removal there
4091 	//			// IEEE: event_expression yIFF expr
4092 	//			// Already in pexpr - needs removal there
4093 	//
4094 		senitemEdge				{ $$=$1; }
4095 	//
4096 	//============= pexpr rules copied for pev_expr
4097 	|	BISONPRE_COPY_ONCE(pexpr,{s/~o~p/pev_/g; })	// {copied}
4098 	//
4099 	//============= sexpr rules copied for pev_expr
4100 	|	BISONPRE_COPY_ONCE(sexpr,{s/~p~s/pev_/g; })	// {copied}
4101 	//
4102 	//============= expr rules copied for pev_expr
4103 	|	BISONPRE_COPY_ONCE(expr,{s/~l~/pev_/g; s/~p~/pev_/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; })	// {copied}
4104 	;
4105 
4106 pexpr<str>:			// IEEE: property_expr  (The name pexpr is important as regexps just add an "p" to expr.)
4107 	//
4108 	//			// IEEE: sequence_expr
4109 	//			// Expanded below
4110 	//
4111 	//			// IEEE: '(' pexpr ')'
4112 	//			// Expanded below
4113 	//
4114 		yNOT pexpr %prec prNEGATION		{ }
4115 	|	ySTRONG '(' sexpr ')'			{ }
4116 	|	yWEAK '(' sexpr ')'			{ }
4117 	//			// IEEE: pexpr yOR pexpr
4118 	//			// IEEE: pexpr yAND pexpr
4119 	//			// Under ~p~sexpr and/or ~p~sexpr
4120 	//
4121 	//			// IEEE: "sequence_expr yP_ORMINUSGT pexpr"
4122 	//			// Instead we use pexpr to prevent conflicts
4123 	|	~o~pexpr yP_ORMINUSGT pexpr		{ }
4124 	|	~o~pexpr yP_OREQGT pexpr		{ }
4125 	//
4126 	//			// IEEE-2009: property_statement
4127 	//			// IEEE-2012: yIF and yCASE
4128 	|	property_statementCaseIf		{ }
4129 	//
4130 	|	~o~pexpr/*sexpr*/ yP_POUNDMINUSPD pexpr	{ }
4131 	|	~o~pexpr/*sexpr*/ yP_POUNDEQPD pexpr	{ }
4132 	|	yNEXTTIME pexpr				{ }
4133 	|	yS_NEXTTIME pexpr			{ }
4134 	|	yNEXTTIME '[' expr/*const*/ ']' pexpr %prec yNEXTTIME		{ }
4135 	|	yS_NEXTTIME '[' expr/*const*/ ']' pexpr	%prec yS_NEXTTIME	{ }
4136 	|	yALWAYS pexpr				{ }
4137 	|	yALWAYS '[' cycle_delay_const_range_expression ']' pexpr  %prec yALWAYS	{ }
4138 	|	yS_ALWAYS '[' constant_range ']' pexpr  %prec yS_ALWAYS		{ }
4139 	|	yS_EVENTUALLY pexpr			{ }
4140 	|	yEVENTUALLY '[' constant_range ']' pexpr  %prec yEVENTUALLY	{ }
4141 	|	yS_EVENTUALLY '[' cycle_delay_const_range_expression ']' pexpr  %prec yS_EVENTUALLY	{ }
4142 	|	~o~pexpr yUNTIL pexpr			{ }
4143 	|	~o~pexpr yS_UNTIL pexpr			{ }
4144 	|	~o~pexpr yUNTIL_WITH pexpr		{ }
4145 	|	~o~pexpr yS_UNTIL_WITH pexpr		{ }
4146 	|	~o~pexpr yIMPLIES pexpr			{ }
4147 	//			// yIFF also used by event_expression
4148 	|	~o~pexpr yIFF ~o~pexpr			{ }
4149 	|	yACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr  %prec yACCEPT_ON	{ }
4150 	|	yREJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr  %prec yREJECT_ON	{ }
4151 	|	ySYNC_ACCEPT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_ACCEPT_ON	{ }
4152 	|	ySYNC_REJECT_ON '(' expr/*expression_or_dist*/ ')' pexpr %prec ySYNC_REJECT_ON	{ }
4153 	//
4154 	//			// IEEE: "property_instance"
4155 	//			// Looks just like a function/method call
4156 	//
4157 	//			// Note "clocking_event pexpr" overlaps property_statement_spec: clocking_event property_statement
4158 	//
4159 	//			// Include property_specDisable to match property_spec rule
4160 	|	clocking_event yDISABLE yIFF '(' expr ')' pexpr	%prec prSEQ_CLOCKING	{ }
4161 	//
4162 	//============= sexpr rules copied for property_expr
4163 	|	BISONPRE_COPY_ONCE(sexpr,{s/~p~s/p/g; })	// {copied}
4164 	//
4165 	//============= expr rules copied for property_expr
4166 	|	BISONPRE_COPY_ONCE(expr,{s/~l~/p/g; s/~p~/p/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; })	// {copied}
4167 	;
4168 
4169 
4170 sexpr<str>:			// ==IEEE: sequence_expr  (The name sexpr is important as regexps just add an "s" to expr.)
4171 	//			// ********* RULES COPIED IN sequence_exprProp
4172 	//			// For precedence, see IEEE 17.7.1
4173 	//
4174 	// 			// IEEE: "cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
4175 	//			// IEEE: "sequence_expr cycle_delay_range sequence_expr { cycle_delay_range sequence_expr }"
4176 	//			// Both rules basically mean we can repeat sequences, so make it simpler:
4177 		cycle_delay_range sexpr	 %prec yP_POUNDPOUND	{ }
4178 	|	~p~sexpr cycle_delay_range sexpr %prec prPOUNDPOUND_MULTI	{ }
4179 	//
4180 	//			// IEEE: expression_or_dist [ boolean_abbrev ]
4181 	//			// Note expression_or_dist includes "expr"!
4182 	//			// sexpr/*sexpression_or_dist*/	 --- Hardcoded below
4183 	|	~p~sexpr/*sexpression_or_dist*/ boolean_abbrev	{ }
4184 	//
4185 	//			// IEEE: "sequence_instance [ sequence_abbrev ]"
4186 	//			// version without sequence_abbrev looks just like normal function call
4187 	//			// version w/sequence_abbrev matches above; expression_or_dist:expr:func boolean_abbrev:sequence_abbrev
4188 	//
4189 	//			// IEEE: '(' expression_or_dist {',' sequence_match_item } ')' [ boolean_abbrev ]
4190 	//			// IEEE: '(' sexpr {',' sequence_match_item } ')' [ sequence_abbrev ]
4191 	//			// As sequence_expr includes expression_or_dist, and boolean_abbrev includes sequence_abbrev:
4192 	//			// '(' sequence_expr {',' sequence_match_item } ')' [ boolean_abbrev ]
4193 	//			// "'(' sexpr ')' boolean_abbrev" matches "[sexpr:'(' expr ')'] boolean_abbrev" so we can simply drop it
4194 	|	'(' ~p~sexpr ')'			{ $<fl>$=$<fl>1; $$=$1+$2+$3; }
4195 	|	'(' ~p~sexpr ',' sequence_match_itemList ')'	{ }
4196 	//
4197 	//			// AND/OR are between pexprs OR sexprs
4198 	|	~p~sexpr yAND ~p~sexpr			{ $<fl>$=$<fl>1; $$=$1+$2+$3; }
4199 	|	~p~sexpr yOR ~p~sexpr			{ $<fl>$=$<fl>1; $$=$1+$2+$3; }
4200 	//			// Intersect always has an sexpr rhs
4201 	|	~p~sexpr yINTERSECT sexpr		{ $<fl>$=$<fl>1; $$=$1+$2+$3; }
4202 	//
4203 	|	yFIRST_MATCH '(' sexpr ')'		{ }
4204 	|	yFIRST_MATCH '(' sexpr ',' sequence_match_itemList ')'	{ }
4205 	|	~p~sexpr/*sexpression_or_dist*/ yTHROUGHOUT sexpr		{ }
4206 	//			// Below pexpr's are really sequence_expr, but avoid conflict
4207 	//			// IEEE: sexpr yWITHIN sexpr
4208 	|	~p~sexpr yWITHIN sexpr			{ $<fl>$=$<fl>1; $$=$1+$2+$3; }
4209 	//			// Note concurrent_assertion had duplicate rule for below
4210 	|	clocking_event ~p~sexpr %prec prSEQ_CLOCKING	{ }
4211 	//
4212 	//============= expr rules copied for sequence_expr
4213 	|	BISONPRE_COPY_ONCE(expr,{s/~l~/s/g; s/~p~/s/g; s/~noPar__IGNORE~/yP_PAR__IGNORE /g; })	// {copied}
4214 	;
4215 
4216 cycle_delay_range:		// IEEE: ==cycle_delay_range
4217 	//			// These three terms in 1800-2005 ONLY
4218 		yP_POUNDPOUND yaINTNUM			{ }
4219 	|	yP_POUNDPOUND id			{ }
4220 	|	yP_POUNDPOUND '(' constExpr ')'		{ }
4221 	//			// In 1800-2009 ONLY:
4222 	//			// IEEE: yP_POUNDPOUND constant_primary
4223 	//			// UNSUP: This causes a big grammer ambiguity
4224 	//			// as ()'s mismatch between primary and the following statement
4225 	//			// the sv-ac committee has been asked to clarify  (Mantis 1901)
4226 	|	yP_POUNDPOUND '[' cycle_delay_const_range_expression ']'	{ }
4227 	|	yP_POUNDPOUND yP_BRASTAR ']'		{ }
4228 	|	yP_POUNDPOUND yP_BRAPLUSKET		{ }
4229 	;
4230 
4231 sequence_match_itemList:	// IEEE: [sequence_match_item] part of sequence_expr
4232 		sequence_match_item			{ }
4233 	|	sequence_match_itemList ',' sequence_match_item	{ }
4234 	;
4235 
4236 sequence_match_item:		// ==IEEE: sequence_match_item
4237 	//			// IEEE says: operator_assignment
4238 	//			// IEEE says: inc_or_dec_expression
4239 	//			// IEEE says: subroutine_call
4240 	//			// This is the same list as...
4241 		for_step_assignment			{ }
4242 	;
4243 
4244 boolean_abbrev:			// ==IEEE: boolean_abbrev
4245 	//			// IEEE: consecutive_repetition
4246 		yP_BRASTAR const_or_range_expression ']'	{ }
4247 	|	yP_BRASTAR ']'				{ }
4248 	|	yP_BRAPLUSKET				{ }
4249 	//			// IEEE: non_consecutive_repetition
4250 	|	yP_BRAEQ const_or_range_expression ']'		{ }
4251 	//			// IEEE: goto_repetition
4252 	|	yP_BRAMINUSGT const_or_range_expression ']'	{ }
4253 	;
4254 
4255 const_or_range_expression:	// ==IEEE: const_or_range_expression
4256 		constExpr				{ }
4257 	|	cycle_delay_const_range_expression	{ }
4258 	;
4259 
4260 
4261 constant_range:			// ==IEEE: constant_range
4262 		constExpr ':' constExpr			{ }
4263 	;
4264 
4265 cycle_delay_const_range_expression:	// ==IEEE: cycle_delay_const_range_expression
4266 	//				// Note '$' is part of constExpr
4267 		constExpr ':' constExpr			{ }
4268 	;
4269 
4270 //************************************************
4271 // Let
4272 
4273 let_declaration:		// ==IEEE: let_declaration
4274 		let_declarationFront let_port_listE '=' expr ';'
4275 			{ PARSEP->symPopScope(VAstType::LET); }
4276 	;
4277 
4278 let_declarationFront:		// IEEE: part of let_declaration
4279 		yLET idAny/*let_identifier*/
4280 			{ PARSEP->symPushNew(VAstType::LET,$2); }
4281 	;
4282 
4283 let_port_listE:			// ==IEEE: let_port_list
4284 		/* empty */
4285 	//			// IEEE: let_port_list
4286 	//			// No significant difference from task ports
4287 	|	'(' tf_port_listE ')'
4288 			{ VARRESET_NONLIST(""); }
4289 	;
4290 
4291 //************************************************
4292 // Covergroup
4293 
4294 covergroup_declaration:		// ==IEEE: covergroup_declaration
4295 		covergroup_declarationFront coverage_eventE ';' coverage_spec_or_optionListE
4296 			yENDGROUP endLabelE
4297 			{ PARSEP->endgroupCb($<fl>5,$5);
4298 			  PARSEP->symPopScope(VAstType::COVERGROUP); }
4299 	|	covergroup_declarationFront '(' tf_port_listE ')' coverage_eventE ';' coverage_spec_or_optionListE
4300 			yENDGROUP endLabelE
4301 			{ PARSEP->endgroupCb($<fl>8,$8);
4302 			  PARSEP->symPopScope(VAstType::COVERGROUP); }
4303 	;
4304 
4305 covergroup_declarationFront:	// IEEE: part of covergroup_declaration
4306 		yCOVERGROUP idAny
4307  			{ PARSEP->symPushNew(VAstType::COVERGROUP,$2);
4308 			  PARSEP->covergroupCb($<fl>1,$1,$2); }
4309 	;
4310 
4311 cgexpr<str>:			// IEEE-2012: covergroup_expression, before that just expression
4312 		expr					{ $<fl>$=$<fl>1; $$ = $1; }
4313 	;
4314 
4315 coverage_spec_or_optionListE:	// IEEE: [{coverage_spec_or_option}]
4316 		/* empty */				{ }
4317 	|	coverage_spec_or_optionList		{ }
4318 	;
4319 
4320 coverage_spec_or_optionList:	// IEEE: {coverage_spec_or_option}
4321 		coverage_spec_or_option			{ }
4322 	|	coverage_spec_or_optionList coverage_spec_or_option	{ }
4323 	;
4324 
4325 coverage_spec_or_option:	// ==IEEE: coverage_spec_or_option
4326 	//			// IEEE: coverage_spec
4327 		cover_point				{ }
4328 	|	cover_cross				{ }
4329 	|	coverage_option ';'			{ }
4330 	|	error					{ }
4331 	;
4332 
4333 coverage_option:		// ==IEEE: coverage_option
4334 	//			// option/type_option aren't really keywords
4335 		id/*yOPTION | yTYPE_OPTION*/ '.' idAny/*member_identifier*/ '=' expr	{ }
4336 	;
4337 
4338 cover_point:			// ==IEEE: cover_point
4339 		/**/               yCOVERPOINT expr iffE bins_or_empty	{ }
4340 	//			// IEEE-2012: class_scope before an ID
4341 	|	/**/           /**/ /**/    id  ':' yCOVERPOINT expr iffE bins_or_empty	{ }
4342 	|	class_scope_id ':' yCOVERPOINT expr iffE bins_or_empty	{ }
4343 	|	class_scope_id id data_type id ':' yCOVERPOINT expr iffE bins_or_empty	{ }
4344 	|	class_scope_id id /**/      id ':' yCOVERPOINT expr iffE bins_or_empty	{ }
4345 	|	/**/           id /**/      id ':' yCOVERPOINT expr iffE bins_or_empty	{ }
4346 	//			// IEEE-2012:
4347 	|	bins_or_empty				{ }
4348 	;
4349 
4350 iffE:				// IEEE: part of cover_point, others
4351 		/* empty */				{ }
4352 	|	yIFF '(' expr ')'			{ }
4353 	;
4354 
4355 bins_or_empty:			// ==IEEE: bins_or_empty
4356 		'{' bins_or_optionsList '}'		{ }
4357 	|	'{' '}'					{ }
4358 	|	';'					{ }
4359 	;
4360 
4361 bins_or_optionsList:		// IEEE: { bins_or_options ';' }
4362 		bins_or_options ';'			{ }
4363 	|	bins_or_optionsList bins_or_options ';'	{ }
4364 	;
4365 
4366 bins_or_options:		// ==IEEE: bins_or_options
4367 	//			// Superset of IEEE - we allow []'s in more places
4368 		coverage_option				{ }
4369 	//			// Can't use wildcardE as results in conflicts
4370 	|	/**/      bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE	{ }
4371 	|	yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' iffE	{ }
4372 	|	/**/      bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE	{ }
4373 	|	yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' '{' open_range_list '}' yWITH__CUR '{' cgexpr ')' iffE	{ }
4374 	//
4375 	//			// cgexpr part of trans_list
4376 	//
4377 	|	/**/      bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE	{ }
4378 	|	yWILDCARD bins_keyword id/*bin_identifier*/ bins_orBraE '=' trans_list iffE	{ }
4379 	//
4380 	|	bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT iffE	{ }
4381 	//
4382 	|	bins_keyword id/*bin_identifier*/ bins_orBraE '=' yDEFAULT ySEQUENCE iffE { }
4383 	;
4384 
4385 bins_orBraE:			// IEEE: part of bins_or_options:
4386 		/* empty */				{ }
4387 	|	'[' ']'					{ }
4388 	|	'[' cgexpr ']'				{ }
4389 	;
4390 
4391 bins_keyword:			// ==IEEE: bins_keyword
4392 		yBINS					{ }
4393 	|	yILLEGAL_BINS				{ }
4394 	|	yIGNORE_BINS				{ }
4395 	;
4396 
4397 covergroup_range_list:		// ==IEEE: covergroup_range_list
4398 	 	covergroup_value_range			{ }
4399 	|	covergroup_range_list ',' covergroup_value_range	{ }
4400 	;
4401 
4402 trans_list:			// ==IEEE: trans_list
4403 		'(' trans_set ')'			{ }
4404 	|	trans_list ',' '(' trans_set ')'	{ }
4405 	;
4406 
4407 trans_set:			// ==IEEE: trans_set
4408 		trans_range_list			{ }
4409 	//			// Note the { => } in the grammer, this is really a list
4410 	|	trans_set yP_EQGT trans_range_list	{ }
4411 	;
4412 
4413 trans_range_list:		// ==IEEE: trans_range_list
4414 		trans_item				{ }
4415 	|	trans_item yP_BRASTAR repeat_range ']'	{ }
4416 	|	trans_item yP_BRAMINUSGT repeat_range ']' { }
4417 	|	trans_item yP_BRAEQ repeat_range ']'	{ }
4418 	;
4419 
4420 trans_item:			// ==IEEE: range_list
4421 		covergroup_range_list			{ }
4422 	;
4423 
4424 repeat_range:			// ==IEEE: repeat_range
4425 		cgexpr					{ }
4426 	|	cgexpr ':' cgexpr			{ }
4427 	;
4428 
4429 cover_cross:			// ==IEEE: cover_cross
4430 	 	id/*cover_point_identifier*/ ':' yCROSS list_of_cross_items iffE cross_body	{ }
4431 	|	/**/				 yCROSS list_of_cross_items iffE cross_body	{ }
4432 	;
4433 
4434 list_of_cross_items:		// ==IEEE: list_of_cross_items
4435 		cross_item ',' cross_item		{ }
4436 	|	cross_item ',' cross_item ',' cross_itemList	{ }
4437 	;
4438 
4439 cross_itemList:			// IEEE: part of list_of_cross_items
4440 		cross_item
4441 	|	cross_itemList ',' cross_item		{ }
4442 	;
4443 
4444 cross_item:			// ==IEEE: cross_item
4445 		idAny/*cover_point_identifier or variable_identifier*/		{ }
4446 	;
4447 
4448 cross_body:			// ==IEEE: cross_body
4449 		'{' '}'					{ }
4450 	//			// IEEE-2012: No semicolon here, mistake in spec
4451 	|	'{' cross_body_itemSemiList '}'		{ }
4452 	|	';'					{ }
4453 	;
4454 
4455 cross_body_itemSemiList: 	// IEEE: part of cross_body
4456 		cross_body_item ';'		{ }
4457 	|	cross_body_itemSemiList cross_body_item ';' { }
4458 	;
4459 
4460 cross_body_item:		// ==IEEE: cross_body_item
4461 	//			// IEEE: our semicolon is in the list
4462 		bins_selection_or_option		{ }
4463 	|	function_declaration			{ }
4464 	;
4465 
4466 bins_selection_or_option:	// ==IEEE: bins_selection_or_option
4467 		coverage_option				{ }
4468 	|	bins_selection				{ }
4469 	;
4470 
4471 bins_selection:			// ==IEEE: bins_selection
4472 		bins_keyword idAny/*new-bin_identifier*/ '=' select_expression iffE	{ }
4473 	;
4474 
4475 select_expression:		// ==IEEE: select_expression
4476 	//			// IEEE: select_condition expanded here
4477 		yBINSOF '(' bins_expression ')'		{ }
4478 	|	yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}'	{ }
4479 	|	yWITH__PAREN '(' cgexpr ')'		{ }
4480 	//			// IEEE-2012: Need clarification as to precedence
4481 	//UNSUP	yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr	{ }
4482 	|	'!' yBINSOF '(' bins_expression ')'		{ }
4483 	|	'!' yBINSOF '(' bins_expression ')' yINTERSECT '{' covergroup_range_list '}'	{ }
4484 	|	'!' yWITH__PAREN '(' cgexpr ')'		{ }
4485 	//			// IEEE-2012: Need clarification as to precedence
4486 	//UNSUP	'!' yWITH__PAREN '(' cgexpr ')' yMATCHES cgexpr	{ }
4487 	|	select_expression yP_ANDAND select_expression	{ }
4488 	|	select_expression yP_OROR   select_expression	{ }
4489 	|	'(' select_expression ')'		{ }
4490 	//			// IEEE-2012: cross_identifier
4491 	//			// Part of covergroup_expression - generic identifier
4492 	//			// IEEE-2012: Need clarification as to precedence
4493 	//UNSUP	covergroup_expression [ yMATCHES covergroup_expression ]
4494 	;
4495 
4496 bins_expression:		// ==IEEE: bins_expression
4497 	//			// "cover_point_identifier" and "variable_identifier" look identical
4498 		id/*variable_identifier or cover_point_identifier*/	{ }
4499 	|	id/*cover_point_identifier*/ '.' idAny/*bins_identifier*/	{ }
4500 	;
4501 
4502 coverage_eventE:		// IEEE: [ coverage_event ]
4503 		/* empty */				{ }
4504 	|	clocking_event				{ }
4505 	|	yWITH__ETC function idAny/*"sample"*/ '(' tf_port_listE ')'	{ }
4506 	|	yP_ATAT '(' block_event_expression ')'	{ }
4507 	;
4508 
4509 block_event_expression:		// ==IEEE: block_event_expression
4510 		block_event_expressionTerm		{ }
4511 	|	block_event_expression yOR block_event_expressionTerm	{ }
4512 	;
4513 
4514 block_event_expressionTerm:	// IEEE: part of block_event_expression
4515 		yBEGIN hierarchical_btf_identifier	{ }
4516 	|	yEND   hierarchical_btf_identifier	{ }
4517 	;
4518 
4519 hierarchical_btf_identifier:	// ==IEEE: hierarchical_btf_identifier
4520 	//			// hierarchical_tf_identifier + hierarchical_block_identifier
4521 		hierarchical_identifier/*tf_or_block*/	{ }
4522 	//			// method_identifier
4523 	|	hierarchical_identifier class_scope_id	{ }
4524 	|	hierarchical_identifier id		{ }
4525 	;
4526 
4527 //**********************************************************************
4528 // Randsequence
4529 
4530 randsequence_statement:		// ==IEEE: randsequence_statement
4531 		yRANDSEQUENCE '('    ')' productionList yENDSEQUENCE	{ }
4532 	|	yRANDSEQUENCE '(' id/*production_identifier*/ ')' productionList yENDSEQUENCE	{ }
4533 	;
4534 
4535 productionList:			// IEEE: production+
4536 		production				{ }
4537 	|	productionList production		{ }
4538 	;
4539 
4540 production:			// ==IEEE: production
4541 		productionFront ':' rs_ruleList ';'	{ }
4542 	;
4543 
4544 productionFront:		// IEEE: part of production
4545 		function_data_type id/*production_identifier*/	{ }
4546 	|	/**/		   id/*production_identifier*/	{ }
4547 	|	function_data_type id/*production_identifier*/ '(' tf_port_listE ')'	{ }
4548 	|	/**/		   id/*production_identifier*/ '(' tf_port_listE ')'	{ }
4549 	;
4550 
4551 rs_ruleList:			// IEEE: rs_rule+ part of production
4552 		rs_rule					{ }
4553 	|	rs_ruleList '|' rs_rule			{ }
4554 	;
4555 
4556 rs_rule:			// ==IEEE: rs_rule
4557 		rs_production_list			{ }
4558 	|	rs_production_list yP_COLONEQ weight_specification	{ }
4559 	|	rs_production_list yP_COLONEQ weight_specification rs_code_block	{ }
4560 	;
4561 
4562 rs_production_list:		// ==IEEE: rs_production_list
4563 		rs_prodList				{ }
4564 	|	yRAND yJOIN /**/         production_item production_itemList	{ }
4565 	|	yRAND yJOIN '(' expr ')' production_item production_itemList	{ }
4566 	;
4567 
4568 weight_specification:		// ==IEEE: weight_specification
4569 		yaINTNUM				{ }
4570 	|	idClassSel/*ps_identifier*/		{ }
4571 	|	'(' expr ')'				{ }
4572 	;
4573 
4574 rs_code_block:			// ==IEEE: rs_code_block
4575 		'{' '}'					{ }
4576 	|	'{' rs_code_blockItemList '}'		{ }
4577 	;
4578 
4579 rs_code_blockItemList:		// IEEE: part of rs_code_block
4580 		rs_code_blockItem			{ }
4581 	|	rs_code_blockItemList rs_code_blockItem	{ }
4582 	;
4583 
4584 rs_code_blockItem:		// IEEE: part of rs_code_block
4585 		data_declaration			{ }
4586 	|	stmt					{ }
4587 	;
4588 
4589 rs_prodList:			// IEEE: rs_prod+
4590 		rs_prod					{ }
4591 	|	rs_prodList rs_prod			{ }
4592 	;
4593 
4594 rs_prod:			// ==IEEE: rs_prod
4595 		production_item				{ }
4596 	|	rs_code_block				{ }
4597 	//			// IEEE: rs_if_else
4598 	|	yIF '(' expr ')' production_item %prec prLOWER_THAN_ELSE	{ }
4599 	|	yIF '(' expr ')' production_item yELSE production_item		{ }
4600 	//			// IEEE: rs_repeat
4601 	|	yREPEAT '(' expr ')' production_item	{ }
4602 	//			// IEEE: rs_case
4603 	|	yCASE '(' expr ')' rs_case_itemList yENDCASE	{ }
4604 	;
4605 
4606 production_itemList:		// IEEE: production_item+
4607 		production_item				{ }
4608 	|	production_itemList production_item	{ }
4609 	;
4610 
4611 production_item:		// ==IEEE: production_item
4612 		id/*production_identifier*/ 		{ }
4613 	|	id/*production_identifier*/ '(' list_of_argumentsE ')'	{ }
4614 	;
4615 
4616 rs_case_itemList:		// IEEE: rs_case_item+
4617 		rs_case_item				{ }
4618 	|	rs_case_itemList rs_case_item		{ }
4619 	;
4620 
4621 rs_case_item:			// ==IEEE: rs_case_item
4622 		caseCondList ':' production_item ';'	{ }
4623 	|	yDEFAULT production_item ';'		{ }
4624 	|	yDEFAULT ':' production_item ';'	{ }
4625 	;
4626 
4627 //**********************************************************************
4628 // Checker
4629 
4630 checker_declaration:		// ==IEEE: part of checker_declaration
4631 		checkerFront checker_port_listE ';'
4632 			checker_or_generate_itemListE yENDCHECKER endLabelE
4633 			{ PARSEP->symPopScope(VAstType::CHECKER); }
4634 	;
4635 
4636 checkerFront:			// IEEE: part of checker_declaration
4637 		yCHECKER idAny/*checker_identifier*/
4638 			{ PARSEP->symPushNew(VAstType::CHECKER, $2); }
4639 	;
4640 
4641 checker_port_listE:		// IEEE: [ ( [ checker_port_list ] ) ]
4642 	//			// checker_port_item is basically the same as property_port_item, minus yLOCAL::
4643 	//			// Want to bet 1800-2012 adds local to checkers?
4644 		property_port_listE			{ }
4645 	;
4646 
4647 checker_or_generate_itemListE:	// IEEE: [{ checker_or_generate_itemList }]
4648 		/* empty */				{ }
4649 	|	checker_or_generate_itemList		{ }
4650 	;
4651 
4652 checker_or_generate_itemList:	// IEEE: { checker_or_generate_itemList }
4653 		checker_or_generate_item		{ }
4654 	|	checker_or_generate_itemList checker_or_generate_item	{ }
4655 	;
4656 
4657 checker_or_generate_item:	// ==IEEE: checker_or_generate_item
4658 		checker_or_generate_item_declaration	{ }
4659 	|	initial_construct			{ }
4660 	//			// IEEE: checker_construct
4661 	|	yALWAYS stmtBlock			{ }
4662 	|	final_construct				{ }
4663 	|	assertion_item				{ }
4664 	|	continuous_assign			{ }
4665 	|	checker_generate_item			{ }
4666 	;
4667 
4668 checker_or_generate_item_declaration:	// ==IEEE: checker_or_generate_item_declaration
4669 		data_declaration			{ }
4670 	|	yRAND data_declaration			{ }
4671 	|	function_declaration			{ }
4672 	|	checker_declaration			{ }
4673 	|	assertion_item_declaration		{ }
4674 	|	covergroup_declaration			{ }
4675 	|	overload_declaration			{ }
4676 	|	genvar_declaration			{ }
4677 	|	clocking_declaration			{ }
4678 	|	yDEFAULT yCLOCKING id/*clocking_identifier*/ ';'	{ }
4679 	|	yDEFAULT yDISABLE yIFF expr/*expression_or_dist*/ ';'	{ }
4680 	|	';'					{ }
4681 	;
4682 
4683 checker_generate_item:		// ==IEEE: checker_generate_item
4684 	//			// Specialized for checker so need "c_" prefixes here
4685 		c_loop_generate_construct		{ }
4686 	|	c_conditional_generate_construct	{ }
4687 	|	c_generate_region			{ }
4688 	//
4689 	|	elaboration_system_task			{ }
4690 	;
4691 
4692 checker_instantiation:
4693 	//			// Only used for procedural_assertion_item's
4694 	//			// Version in concurrent_assertion_item looks like etcInst
4695 	//			// Thus instead of *_checker_port_connection we can use etcInst's cellpinList
4696 		id/*checker_identifier*/ id '(' cellpinList ')' ';'	{ }
4697 	;
4698 
4699 //**********************************************************************
4700 // Class
4701 
4702 class_declaration:		// ==IEEE: part of class_declaration
4703 	//			// IEEE-2012: using this also for interface_class_declaration
4704 	//			// The classExtendsE rule relys on classFront having the
4705 	//			// new class scope correct via classFront
4706 		classFront parameter_port_listE classExtendsE classImplementsE ';'
4707 			class_itemListE yENDCLASS endLabelE
4708 			{ PARSEP->endclassCb($<fl>7,$7);
4709 			  PARSEP->symPopScope(VAstType::CLASS); }
4710 	;
4711 
4712 classFront:			// IEEE: part of class_declaration
4713 		classVirtualE yCLASS lifetimeE idAny/*class_identifier*/
4714 			{ PARSEP->symPushNew(VAstType::CLASS, $4);
4715 			  PARSEP->classCb($<fl>2,$2,$4,$1); }
4716 	//			// IEEE: part of interface_class_declaration
4717 	|	yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
4718 			{ PARSEP->symPushNew(VAstType::CLASS, $4);
4719 			  PARSEP->classCb($<fl>2,$2,$4,$1); }
4720 	;
4721 
4722 classVirtualE<str>:
4723 		/* empty */				{ $$=""; }
4724 	|	yVIRTUAL__CLASS				{ $<fl>$=$<fl>1; $$=$1; }
4725 	;
4726 
4727 classExtendsE:			// IEEE: part of class_declaration
4728 	//			// The classExtendsE rule relys on classFront having the
4729 	//			// new class scope correct via classFront
4730 		/* empty */				{ }
4731 	|	yEXTENDS class_typeWithoutId		{ PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4732 	|	yEXTENDS class_typeWithoutId '(' list_of_argumentsE ')'	{ PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4733 	;
4734 
4735 classImplementsE:		// IEEE: part of class_declaration
4736 	//			// All 1800-2012
4737 		/* empty */				{ }
4738 	|	yIMPLEMENTS classImplementsList		{ PARSEP->syms().import($<fl>1,$<str>2,$<scp>2,"*"); }
4739 	;
4740 
4741 classImplementsList:		// IEEE: part of class_declaration
4742 	//			// All 1800-2012
4743 		class_typeWithoutId			{ }
4744 	|	classImplementsList ',' class_typeWithoutId	{ }
4745 	;
4746 
4747 //=========
4748 // Package scoping - to traverse the symbol table properly, the final identifer
4749 // must be included in the rules below.
4750 // Each of these must end with {symsPackageDone | symsClassDone}
4751 
4752 ps_id_etc<str>:			// package_scope + general id
4753 		package_scopeIdFollowsE id		{ $<fl>$=$<fl>1; $$=$1+$2; }
4754 	;
4755 
4756 class_scope_id<str_scp>:	// class_scope + id etc
4757 		class_scopeIdFollows id			{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1+$<str>2; }
4758 	;
4759 
4760 //=== Below rules assume special scoping per above
4761 
4762 class_typeWithoutId<str_scp>:	// as with class_typeWithoutId but allow yaID__aTYPE
4763 	//			// and we thus don't need to resolve it in specified package
4764 		package_scopeIdFollowsE class_typeOneList	{ $<fl>$=$<fl>2; $<scp>$=$<scp>2; $<str>$=$1+$<str>2; }
4765 	;
4766 
4767 class_scopeWithoutId<str_scp>:	// class_type standalone without following id
4768 	//			// and we thus don't need to resolve it in specified package
4769 		class_scopeIdFollows			{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; PARSEP->symTableNextId(NULL); }
4770 	;
4771 
4772 class_scopeIdFollows<str_scp>:	// IEEE: class_scope + type
4773 	//			// IEEE: "class_type yP_COLONCOLON"
4774 	//			// IMPORTANT: The lexer will parse the following ID to be in the found package
4775 	//			// But class_type:'::' conflicts with class_scope:'::' so expand here
4776 		package_scopeIdFollowsE class_typeOneListColonIdFollows	{ $<fl>$=$<fl>2; $<scp>$=$<scp>2; $<str>$=$1+$<str>2; }
4777 	;
4778 
4779 class_typeOneListColonIdFollows<str_scp>: // IEEE: class_type :: but allow yaID__aTYPE
4780 		class_typeOneList yP_COLONCOLON 	{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1+$<str>2; PARSEP->symTableNextId($<scp>1); }
4781 	;
4782 
4783 class_typeOneList<str_scp>:	// IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
4784 	//			// If you follow the rules down, class_type is really a list via ps_class_identifier
4785 	//			// Must propagate scp up for next id
4786 		class_typeOne					{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; }
4787 	|	class_typeOneListColonIdFollows class_typeOne	{ $<fl>$=$<fl>1; $<scp>$=$<scp>2; $<str>$=$<str>1+$<str>2; }
4788 	;
4789 
4790 class_typeOne<str_scp>:		// IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
4791 	//			// If you follow the rules down, class_type is really a list via ps_class_identifier
4792 	//			// Not listed in IEEE, but see bug627 any parameter type maybe a class
4793 		yaID__aTYPE parameter_value_assignmentE
4794 			{ $<fl>$=$<fl>1; $<scp>$=$<scp>1; $<str>$=$<str>1; }
4795 	;
4796 
4797 package_scopeIdFollowsE<str>:	// IEEE: [package_scope]
4798 	//			// IMPORTANT: The lexer will parse the following ID to be in the found package
4799 		/* empty */				{ $$=""; }
4800 	|	package_scopeIdFollows			{ $<fl>$=$<fl>1; $$=$1; }
4801 	;
4802 
4803 package_scopeIdFollows<str>:	// IEEE: package_scope
4804 	//			// IMPORTANT: The lexer will parse the following ID to be in the found package
4805 	//			// class_qualifier := [ yLOCAL '::'  ] [ implicit_class_handle '.' | class_scope ]
4806 	//			//vv mid rule action needed otherwise we might not have NextId in time to parse the id token
4807 		yD_UNIT        { PARSEP->symTableNextId(PARSEP->syms().netlistSymp()); }
4808 	/*cont*/	yP_COLONCOLON	{ $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4809 	|	yaID__aPACKAGE { PARSEP->symTableNextId($<scp>1); }
4810 	/*cont*/	yP_COLONCOLON	{ $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4811 	|	yLOCAL__COLONCOLON { PARSEP->symTableNextId($<scp>1); }
4812 	/*cont*/	yP_COLONCOLON	{ $<fl>$=$<fl>1; $<str>$=$<str>1+$<str>3; }
4813 	;
4814 
4815 //^^^=========
4816 
4817 class_itemListE:
4818 		/* empty */				{ }
4819 	|	class_itemList				{ }
4820 	;
4821 
4822 class_itemList:
4823 		class_item				{ }
4824 	|	class_itemList class_item  		{ }
4825 	;
4826 
4827 class_item:			// ==IEEE: class_item
4828 		class_property				{ }
4829 	|	class_method				{ }
4830 	|	class_constraint			{ }
4831 	//
4832 	|	class_declaration			{ }
4833 	|	timeunits_declaration			{ }
4834 	|	covergroup_declaration			{ }
4835 	|	local_parameter_declaration ';'		{ } // 1800-2009
4836 	|	parameter_declaration ';'		{ } // 1800-2009
4837 	|	';'					{ }
4838 	//
4839 	|	error ';'				{ }
4840 	;
4841 
4842 class_method:			// ==IEEE: class_method
4843 		memberQualResetListE task_declaration			{ }
4844 	|	memberQualResetListE function_declaration		{ }
4845 	//			// 1800-2009 adds yPURE yVIRTUAL, already in memberQualResetListE
4846 	|	yEXTERN memberQualResetListE method_prototype ';'	{ }
4847 	//			// IEEE: "method_qualifierE class_constructor_declaration"
4848 	//			// part of function_declaration
4849 	|	yEXTERN memberQualResetListE class_constructor_prototype	{ }
4850 	;
4851 
4852 // IEEE: class_constructor_prototype
4853 // See function_declaration
4854 
4855 class_item_qualifier<str>:	// IEEE: class_item_qualifier minus ySTATIC
4856 	//			// IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
4857 		yPROTECTED				{ $<fl>$=$<fl>1; $$=$1; }
4858 	|	yLOCAL__ETC				{ $<fl>$=$<fl>1; $$=$1; }
4859 	|	ySTATIC__ETC				{ $<fl>$=$<fl>1; $$=$1; }
4860 	;
4861 
4862 memberQualResetListE:		// Called from class_property for all qualifiers before yVAR
4863 	//			// Also before method declarations, to prevent grammar conflict
4864 	//			// Thus both types of qualifiers (method/property) are here
4865 		/*empty*/				{ VARRESET(); VARDTYPE(""); }
4866 	|	memberQualList				{ VARRESET(); VARDTYPE($1); }
4867 	;
4868 
4869 memberQualList<str>:
4870 		memberQualOne				{ $<fl>$=$<fl>1; $$=$1; }
4871 	|	memberQualList memberQualOne		{ $<fl>$=$<fl>1; $$=SPACED($1,$2); }
4872 	;
4873 
4874 memberQualOne<str>:			// IEEE: property_qualifier + method_qualifier
4875 	//			// Part of method_qualifier and property_qualifier
4876 		class_item_qualifier			{ $<fl>$=$<fl>1; $$=$1; }
4877 	//			// Part of method_qualifier only
4878 	|	yVIRTUAL__ETC				{ $<fl>$=$<fl>1; $$=$1; }
4879 	//			// IMPORTANT: lexer looks for yPURE yVIRTUAL
4880 	|	yPURE yVIRTUAL__ETC			{ $<fl>$=$<fl>1; $$=$1+" "+$2; }
4881 	//			// Part of property_qualifier only
4882 	|	random_qualifier			{ $<fl>$=$<fl>1; $$=$1; }
4883 	//			// Part of lifetime, but here as ySTATIC can be in different positions
4884 	|	yAUTOMATIC		 		{ $<fl>$=$<fl>1; $$=$1; }
4885 	//			// Part of data_declaration, but not in data_declarationVarFrontClass
4886 	|	yCONST__ETC				{ $<fl>$=$<fl>1; $$=$1; }
4887 	;
4888 
4889 //**********************************************************************
4890 // Constraints
4891 
4892 class_constraint:		// ==IEEE: class_constraint
4893 	//			// IEEE: constraint_declaration
4894 		constraintStaticE yCONSTRAINT idAny constraint_block	{ }
4895 	//			// IEEE: constraint_prototype + constraint_prototype_qualifier
4896 	|	constraintStaticE yCONSTRAINT idAny ';'		{ }
4897 	|	yEXTERN constraintStaticE yCONSTRAINT idAny ';'	{ }
4898 	|	yPURE constraintStaticE yCONSTRAINT idAny ';'	{ }
4899 	;
4900 
4901 constraint_block:		// ==IEEE: constraint_block
4902 		'{' constraint_block_itemList '}'	{ }
4903 	;
4904 
4905 constraint_block_itemList:	// IEEE: { constraint_block_item }
4906 		constraint_block_item			{ }
4907 	|	constraint_block_itemList constraint_block_item	{ }
4908 	;
4909 
4910 constraint_block_item:		// ==IEEE: constraint_block_item
4911 		ySOLVE solve_before_list yBEFORE solve_before_list ';'	{ }
4912 	|	constraint_expression			{ }
4913 	;
4914 
4915 solve_before_list:		// ==IEEE: solve_before_list
4916 		constraint_primary			{ }
4917 	|	solve_before_list ',' constraint_primary	{ }
4918 	;
4919 
4920 constraint_primary:		// ==IEEE: constraint_primary
4921 	//			// exprScope more general than: [ implicit_class_handle '.' | class_scope ] hierarchical_identifier select
4922 		exprScope				{ }
4923 	;
4924 
4925 constraint_expressionList<str>:	// ==IEEE: { constraint_expression }
4926 		constraint_expression				{ $$=$1; }
4927 	|	constraint_expressionList constraint_expression	{ $$=$1+" "+$2; }
4928 	;
4929 
4930 constraint_expression<str>:	// ==IEEE: constraint_expression
4931 		expr/*expression_or_dist*/ ';'		{ $$=$1; }
4932 	//			// 1800-2012:
4933 	|	ySOFT expr/*expression_or_dist*/ ';'	{ $$="soft "+$1; }
4934 	//			// 1800-2012:
4935 	//			// IEEE: uniqueness_constraint ';'
4936 	|	yUNIQUE '{' open_range_list '}'		{ $$="unique {...}"; }
4937 	//			// IEEE: expr yP_MINUSGT constraint_set
4938 	//			// Conflicts with expr:"expr yP_MINUSGT expr"; rule moved there
4939 	//
4940 	|	yIF '(' expr ')' constraint_set	%prec prLOWER_THAN_ELSE	{ $$=$1; }
4941 	|	yIF '(' expr ')' constraint_set	yELSE constraint_set	{ $$=$1;}
4942 	//			// IEEE says array_identifier here, but dotted accepted in VMM + 1800-2009
4943 	|	yFOREACH '(' idClassForeach/*array_id[loop_variables]*/ ')' constraint_set	{ $$=$1; }
4944 	//			// soft is 1800-2012
4945 	|	yDISABLE ySOFT expr/*constraint_primary*/ ';'	{ $$="disable soft "+$1; }
4946 	;
4947 
4948 constraint_set<str>:		// ==IEEE: constraint_set
4949 		constraint_expression			{ $$=$1; }
4950 	|	'{' constraint_expressionList '}'	{ $$=$1+$2+$3; }
4951 	;
4952 
4953 dist_list:			// ==IEEE: dist_list
4954 		dist_item				{ }
4955 	|	dist_list ',' dist_item			{ }
4956 	;
4957 
4958 dist_item:			// ==IEEE: dist_item + dist_weight
4959 		value_range				{ }
4960 	|	value_range yP_COLONEQ  expr		{ }
4961 	|	value_range yP_COLONDIV expr		{ }
4962 	;
4963 
4964 extern_constraint_declaration:	// ==IEEE: extern_constraint_declaration
4965 		constraintStaticE yCONSTRAINT class_scope_id constraint_block	{ }
4966 	;
4967 
4968 constraintStaticE:		// IEEE: part of extern_constraint_declaration
4969 		/* empty */				{ }
4970 	|	ySTATIC__CONSTRAINT			{ }
4971 	;
4972 
4973 //**********************************************************************
4974 %%
4975 
4976 int VParseGrammar::parse() {
4977     s_grammarp = this;
4978     return VParseBisonparse();
4979 }
debug(int level)4980 void VParseGrammar::debug(int level) {
4981     VParseBisondebug = level;
4982 }
tokenName(int token)4983 const char* VParseGrammar::tokenName(int token) {
4984 #if YYDEBUG || YYERROR_VERBOSE
4985     if (token >= 255) {
4986 	switch (token) {
4987 	/*BISONPRE_TOKEN_NAMES*/
4988 	default: return yytname[token-255];
4989 	}
4990     } else {
4991 	static char ch[2];  ch[0]=token; ch[1]='\0';
4992 	return ch;
4993     }
4994 #else
4995     return "";
4996 #endif
4997 }
4998 
4999 //YACC = /kits/sources/bison-2.4.1/src/bison --report=lookahead
5000 // --report=lookahead
5001 // --report=itemset
5002 // --graph
5003 //
5004 // Local Variables:
5005 // compile-command: "cd .. ; make -j 8 && make test"
5006 // End:
5007