Parse all class constructs, as still unsupported.

This commit is contained in:
Wilson Snyder 2019-12-23 15:03:04 -05:00
parent c1fb938a61
commit 2cbfe99ad5
5 changed files with 481 additions and 83 deletions

View File

@ -245,6 +245,22 @@ public:
AstRange* rangep() const { return VN_CAST(op2p(), Range); } // op2 = Range of pin
};
class AstClass : public AstNode {
// MEMBERS
string m_name; // Name
public:
AstClass(FileLine* fl, const string& name)
: AstNode(fl)
, m_name(name) {}
ASTNODE_NODE_FUNCS(Class)
virtual string name() const { return m_name; } // * = Var name
virtual void name(const string& name) { m_name = name; }
virtual string verilogKwd() const { return "class"; }
virtual bool maybePointedTo() const { return true; }
AstNode* membersp() const { return op1p(); } // op1 = List of statements
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
};
//######################################################################
//==== Data Types
@ -685,6 +701,45 @@ public:
virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); }
};
class AstClassRefDType : public AstNodeDType {
// Reference to a class
private:
AstClass* m_classp; // data type pointed to, BELOW the AstTypedef
AstPackage* m_packagep; // Package hierarchy
public:
AstClassRefDType(FileLine* fl, AstClass* classp)
: AstNodeDType(fl), m_classp(classp), m_packagep(NULL) {
dtypep(this);
}
ASTNODE_NODE_FUNCS(ClassRefDType)
// METHODS
virtual const char* broken() const {
BROKEN_RTN(m_classp && !m_classp->brokeExists()); return NULL; }
virtual void cloneRelink() {
if (m_classp && m_classp->clonep()) m_classp = m_classp->clonep();
}
virtual bool same(const AstNode* samep) const {
const AstClassRefDType* asamep = static_cast<const AstClassRefDType*>(samep);
return (m_classp == asamep->m_classp
&& m_packagep == asamep->m_packagep); }
virtual bool similarDType(AstNodeDType* samep) const { return this == samep; }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_classp), V3Hash(m_packagep)); }
virtual string name() const { return classp() ? classp()->name() : "<unlinked>"; }
virtual AstBasicDType* basicp() const { return NULL; }
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; }
virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; }
virtual int widthAlignBytes() const { return 0; }
virtual int widthTotalBytes() const { return 0; }
virtual AstNodeDType* virtRefDTypep() const { return NULL; }
virtual void virtRefDTypep(AstNodeDType* nodep) {}
virtual AstNodeDType* subDTypep() const { return NULL; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep = nodep; }
AstClass* classp() const { return m_classp; }
void classp(AstClass* nodep) { m_classp = nodep; }
};
class AstIfaceRefDType : public AstNodeDType {
// Reference to an interface, either for a port, or inside parent cell
private:
@ -844,6 +899,7 @@ public:
class AstStructDType : public AstNodeUOrStructDType {
public:
// AstNumeric below is mispurposed to indicate if packed or not
AstStructDType(FileLine* fl, AstNumeric numericUnpack)
: AstNodeUOrStructDType(fl, numericUnpack) {}
ASTNODE_NODE_FUNCS(StructDType)
@ -853,6 +909,7 @@ public:
class AstUnionDType : public AstNodeUOrStructDType {
public:
//UNSUP: bool isTagged;
// AstNumeric below is mispurposed to indicate if packed or not
AstUnionDType(FileLine* fl, AstNumeric numericUnpack)
: AstNodeUOrStructDType(fl, numericUnpack) {}
ASTNODE_NODE_FUNCS(UnionDType)
@ -1282,37 +1339,6 @@ public:
void declRange(const VNumRange& flag) { m_declRange = flag; }
};
class AstMemberSel : public AstNodeMath {
// Parents: math|stmt
// Children: varref|arraysel, math
private:
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
string m_name;
public:
AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name)
: AstNodeMath(fl), m_name(name) {
setOp1p(fromp);
dtypep(NULL); // V3Width will resolve
}
AstMemberSel(FileLine* fl, AstNode* fromp, AstMemberDType* dtp)
: AstNodeMath(fl) {
setOp1p(fromp);
dtypep(dtp);
m_name = dtp->name();
}
ASTNODE_NODE_FUNCS(MemberSel)
virtual string name() const { return m_name; }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
V3ERROR_NA; /* How can from be a const? */ }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() const { return false; }
virtual bool same(const AstNode* samep) const { return true; } // dtype comparison does it all for us
virtual int instrCount() const { return widthInstrs(); }
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
void fromp(AstNode* nodep) { setOp1p(nodep); }
};
class AstMethodCall : public AstNode {
// A reference to a member task (or function)
// We do not support generic member calls yet, so this is only enough to
@ -2012,6 +2038,47 @@ public:
ASTNODE_NODE_FUNCS(Iface)
};
class AstMemberSel : public AstNodeMath {
// Parents: math|stmt
// Children: varref|arraysel, math
private:
// Don't need the class we are extracting from, as the "fromp()"'s datatype can get us to it
string m_name;
AstVar* m_varp; // Post link, variable within class that is target of selection
public:
AstMemberSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name)
: AstNodeMath(fl)
, m_name(name)
, m_varp(NULL) {
setOp1p(fromp);
dtypep(NULL); // V3Width will resolve
}
AstMemberSel(FileLine* fl, AstNode* fromp, AstNodeDType* dtp)
: AstNodeMath(fl)
, m_name(dtp->name())
, m_varp(NULL) {
setOp1p(fromp);
dtypep(dtp);
}
ASTNODE_NODE_FUNCS(MemberSel)
virtual void cloneRelink() { if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); } }
virtual const char* broken() const {
BROKEN_RTN(m_varp && !m_varp->brokeExists()); return NULL; }
virtual string name() const { return m_name; }
virtual V3Hash sameHash() const { return V3Hash(m_name); }
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
V3ERROR_NA; /* How can from be a const? */ }
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() const { return false; }
virtual bool same(const AstNode* samep) const { return true; } // dtype comparison does it
virtual int instrCount() const { return widthInstrs(); }
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
void fromp(AstNode* nodep) { setOp1p(nodep); }
AstVar* varp() const { return m_varp; }
void varp(AstVar* nodep) { m_varp = nodep; }
};
class AstModportFTaskRef : public AstNode {
// An import/export referenced under a modport
// The storage for the function itself is inside the
@ -3826,6 +3893,25 @@ public:
}
};
class AstNew : public AstNodeMath {
// Parents: math|stmt
// Children: varref|arraysel, math
public:
AstNew(FileLine* fl)
: AstNodeMath(fl) {
dtypep(NULL); // V3Width will resolve
}
ASTNODE_NODE_FUNCS(New)
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
V3ERROR_NA; /* How can from be a const? */ }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual string emitVerilog() { return "new"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() const { return true; }
virtual bool same(const AstNode* samep) const { return true; }
virtual int instrCount() const { return widthInstrs(); }
};
class AstPragma : public AstNode {
private:
AstPragmaType m_pragType; // Type of pragma

View File

@ -70,6 +70,7 @@ struct V3ParseBisonYYSType {
AstCase* casep;
AstCaseItem* caseitemp;
AstCell* cellp;
AstClass* classp;
AstConst* constp;
AstMemberDType* memberp;
AstNodeModule* modulep;
@ -86,6 +87,7 @@ struct V3ParseBisonYYSType {
AstPatMember* patmemberp;
AstPattern* patternp;
AstPin* pinp;
AstRefDType* refdtypep;
AstSenTree* sentreep;
AstVar* varp;
AstVarRef* varrefp;

View File

@ -411,19 +411,21 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"always_comb" { FL; return yALWAYS_COMB; }
"always_ff" { FL; return yALWAYS_FF; }
"always_latch" { FL; return yALWAYS_LATCH; }
"assume" { FL; return yASSUME; }
"assert" { FL; return yASSERT; }
"assume" { FL; return yASSUME; }
"bind" { FL; return yBIND; }
"bit" { FL; return yBIT; }
"break" { FL; return yBREAK; }
"byte" { FL; return yBYTE; }
"chandle" { FL; return yCHANDLE; }
"class" { FL; return yCLASS; }
"clocking" { FL; return yCLOCKING; }
"const" { FL; return yCONST__LEX; }
"context" { FL; return yCONTEXT; }
"continue" { FL; return yCONTINUE; }
"cover" { FL; return yCOVER; }
"do" { FL; return yDO; }
"endclass" { FL; return yENDCLASS; }
"endclocking" { FL; return yENDCLOCKING; }
"endinterface" { FL; return yENDINTERFACE; }
"endpackage" { FL; return yENDPACKAGE; }
@ -431,6 +433,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"endproperty" { FL; return yENDPROPERTY; }
"enum" { FL; return yENUM; }
"export" { FL; return yEXPORT; }
"extends" { FL; return yEXTENDS; }
"extern" { FL; return yEXTERN; }
"final" { FL; return yFINAL; }
"forkjoin" { FL; return yFORKJOIN; }
@ -439,15 +442,18 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"inside" { FL; return yINSIDE; }
"int" { FL; return yINT; }
"interface" { FL; return yINTERFACE; }
"local" { FL; return yLOCAL__LEX; }
"logic" { FL; return yLOGIC; }
"longint" { FL; return yLONGINT; }
"modport" { FL; return yMODPORT; }
"new" { FL; return yNEW__LEX; }
"null" { FL; return yNULL; }
"package" { FL; return yPACKAGE; }
"packed" { FL; return yPACKED; }
"priority" { FL; return yPRIORITY; }
"program" { FL; return yPROGRAM; }
"property" { FL; return yPROPERTY; }
"protected" { FL; return yPROTECTED; }
"pure" { FL; return yPURE; }
"rand" { FL; return yRAND; }
"randc" { FL; return yRANDC; }
@ -460,6 +466,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"static" { FL; return ySTATIC__ETC; }
"string" { FL; return ySTRING; }
"struct" { FL; return ySTRUCT; }
"super" { FL; return ySUPER; }
"this" { FL; return yTHIS; }
"timeprecision" { FL; return yTIMEPRECISION; }
"timeunit" { FL; return yTIMEUNIT; }
"type" { FL; return yTYPE; }
@ -467,6 +475,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"union" { FL; return yUNION; }
"unique" { FL; return yUNIQUE; }
"var" { FL; return yVAR; }
"virtual" { FL; return yVIRTUAL__LEX; }
"void" { FL; return yVOID; }
/* Generic unsupported warnings */
/* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */
@ -474,36 +483,27 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"before" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"bins" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"binsof" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"class" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"constraint" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"covergroup" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"coverpoint" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"cross" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"dist" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"endclass" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"endgroup" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"endsequence" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"expect" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"extends" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"first_match" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"ignore_bins" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"illegal_bins" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"intersect" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"join_any" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"join_none" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"local" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"matches" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"new" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"protected" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"randomize" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"randsequence" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"sequence" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"solve" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"super" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"tagged" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"this" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"throughout" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"virtual" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"wait_order" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"wildcard" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
"with" { ERROR_RSVD_WORD("SystemVerilog 2005"); }
@ -541,7 +541,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* System Verilog 2012 */
<S12,S17,SAX>{
/* Keywords */
"implements" { ERROR_RSVD_WORD("SystemVerilog 2012"); }
"implements" { FL; return yIMPLEMENTS; }
"interconnect" { ERROR_RSVD_WORD("SystemVerilog 2012"); }
"nettype" { ERROR_RSVD_WORD("SystemVerilog 2012"); }
"soft" { ERROR_RSVD_WORD("SystemVerilog 2012"); }
@ -1012,6 +1012,9 @@ void V3ParseImp::lexToken() {
if (token == '('
|| token == yCONST__LEX
|| token == yGLOBAL__LEX
|| token == yLOCAL__LEX
|| token == yNEW__LEX
|| token == yVIRTUAL__LEX
// Never put yID_* here; below symbol table resolution would break
) {
if (debugFlex()>=6) { cout<<" lexToken: reading ahead to find possible strength"<<endl; }
@ -1037,6 +1040,22 @@ void V3ParseImp::lexToken() {
// Avoid 2009 "global" conflicting with old code when we can
else { token = yaID__LEX; yylval.strp = PARSEP->newString("global"); }
}
else if (token == yLOCAL__LEX) {
if (nexttok == yP_COLONCOLON) token = yLOCAL__COLONCOLON;
else token = yLOCAL__ETC;
}
else if (token == yNEW__LEX) {
if (nexttok == '(') token = yNEW__PAREN;
else token = yNEW__ETC;
}
else if (token == yVIRTUAL__LEX) {
if (nexttok == yCLASS) token = yVIRTUAL__CLASS;
else if (nexttok == yINTERFACE) token = yVIRTUAL__INTERFACE;
else if (nexttok == yaID__ETC || nexttok == yaID__LEX)
// || nexttok == yaID__aINTERFACE // but we may not know interfaces yet.
token = yVIRTUAL__anyID;
else token = yVIRTUAL__ETC;
}
// If add to above "else if", also add to "if (token" further above
}
// If an id, change the type based on symbol table
@ -1061,7 +1080,7 @@ void V3ParseImp::lexToken() {
if (VN_IS(scp, Typedef)) token = yaID__aTYPE;
else if (VN_IS(scp, TypedefFwd)) token = yaID__aTYPE;
else if (VN_IS(scp, Package)) token = yaID__aPACKAGE;
//UNSUP else if (VN_IS(scp, NodeClass)) token = yaID__aCLASS;
else if (VN_IS(scp, Class)) token = yaID__aTYPE;
//UNSUP else if (VN_IS(scp, CoverGroup)) token = yaID__aCOVERGROUP;
else token = yaID__ETC;
} else { // Not found

View File

@ -345,6 +345,7 @@ class AstSenTree;
%token<fl> yCASEX "casex"
%token<fl> yCASEZ "casez"
%token<fl> yCHANDLE "chandle"
%token<fl> yCLASS "class"
%token<fl> yCLOCKING "clocking"
%token<fl> yCMOS "cmos"
%token<fl> yCONST__ETC "const"
@ -362,6 +363,7 @@ class AstSenTree;
%token<fl> yELSE "else"
%token<fl> yEND "end"
%token<fl> yENDCASE "endcase"
%token<fl> yENDCLASS "endclass"
%token<fl> yENDCLOCKING "endclocking"
%token<fl> yENDFUNCTION "endfunction"
%token<fl> yENDGENERATE "endgenerate"
@ -377,6 +379,7 @@ class AstSenTree;
%token<fl> yENUM "enum"
%token<fl> yEVENT "event"
%token<fl> yEXPORT "export"
%token<fl> yEXTENDS "extends"
%token<fl> yEXTERN "extern"
%token<fl> yFINAL "final"
%token<fl> yFOR "for"
@ -393,6 +396,7 @@ class AstSenTree;
%token<fl> yGLOBAL__LEX "global-in-lex"
%token<fl> yIF "if"
%token<fl> yIFF "iff"
%token<fl> yIMPLEMENTS "implements"
%token<fl> yIMPORT "import"
%token<fl> yINITIAL "initial"
%token<fl> yINOUT "inout"
@ -403,12 +407,18 @@ class AstSenTree;
%token<fl> yINTERFACE "interface"
%token<fl> yJOIN "join"
%token<fl> yLOCALPARAM "localparam"
%token<fl> yLOCAL__COLONCOLON "local-then-::"
%token<fl> yLOCAL__ETC "local"
%token<fl> yLOCAL__LEX "local-in-lex"
%token<fl> yLOGIC "logic"
%token<fl> yLONGINT "longint"
%token<fl> yMODPORT "modport"
%token<fl> yMODULE "module"
%token<fl> yNAND "nand"
%token<fl> yNEGEDGE "negedge"
%token<fl> yNEW__ETC "new"
%token<fl> yNEW__LEX "new-in-lex"
%token<fl> yNEW__PAREN "new-then-paren"
%token<fl> yNMOS "nmos"
%token<fl> yNOR "nor"
%token<fl> yNOT "not"
@ -426,6 +436,7 @@ class AstSenTree;
%token<fl> yPRIORITY "priority"
%token<fl> yPROGRAM "program"
%token<fl> yPROPERTY "property"
%token<fl> yPROTECTED "protected"
%token<fl> yPULLDOWN "pulldown"
%token<fl> yPULLUP "pullup"
%token<fl> yPURE "pure"
@ -455,10 +466,12 @@ class AstSenTree;
%token<fl> ySTATIC__ETC "static"
%token<fl> ySTRING "string"
%token<fl> ySTRUCT "struct"
%token<fl> ySUPER "super"
%token<fl> ySUPPLY0 "supply0"
%token<fl> ySUPPLY1 "supply1"
%token<fl> yTABLE "table"
%token<fl> yTASK "task"
%token<fl> yTHIS "this"
%token<fl> yTIME "time"
%token<fl> yTIMEPRECISION "timeprecision"
%token<fl> yTIMEUNIT "timeunit"
@ -480,6 +493,11 @@ class AstSenTree;
%token<fl> yUNSIGNED "unsigned"
%token<fl> yVAR "var"
%token<fl> yVECTORED "vectored"
%token<fl> yVIRTUAL__CLASS "virtual-then-class"
%token<fl> yVIRTUAL__ETC "virtual"
%token<fl> yVIRTUAL__INTERFACE "virtual-then-interface"
%token<fl> yVIRTUAL__LEX "virtual-in-lex"
%token<fl> yVIRTUAL__anyID "virtual-then-identifier"
%token<fl> yVOID "void"
%token<fl> yWAIT "wait"
%token<fl> yWAND "wand"
@ -800,7 +818,7 @@ package_or_generate_item_declaration<nodep>: // ==IEEE: package_or_generate_item
//UNSUP checker_declaration { $$ = $1; }
| dpi_import_export { $$ = $1; }
//UNSUP extern_constraint_declaration { $$ = $1; }
//UNSUP class_declaration { $$ = $1; }
| class_declaration { $$ = $1; }
// // class_constructor_declaration is part of function_declaration
| local_parameter_declaration ';' { $$ = $1; }
| parameter_declaration ';' { $$ = $1; }
@ -917,6 +935,11 @@ parameter_value_assignmentE<pinp>: // IEEE: [ parameter_value_assignment ]
// // '#' delay_value { UNSUP }
;
parameter_value_assignmentClass<pinp>: // IEEE: [ parameter_value_assignment ] (for classes)
// // Like parameter_value_assignment, but for classes only, which always have #()
'#' '(' cellparamList ')' { $$ = $3; }
;
parameter_port_listE<nodep>: // IEEE: parameter_port_list + empty == parameter_value_assignment
/* empty */ { $$ = NULL; }
| '#' '(' ')' { $$ = NULL; }
@ -1133,7 +1156,7 @@ anonymous_program_itemList<nodep>: // IEEE: { anonymous_program_item }
anonymous_program_item<nodep>: // ==IEEE: anonymous_program_item
task_declaration { $$ = $1; }
| function_declaration { $$ = $1; }
//UNSUP class_declaration { $$ = $1; }
| class_declaration { $$ = $1; }
//UNSUP covergroup_declaration { $$ = $1; }
// // class_constructor_declaration is part of function_declaration
| ';' { $$ = NULL; }
@ -1478,13 +1501,20 @@ simple_type<dtypep>: // ==IEEE: simple_type
data_type<dtypep>: // ==IEEE: data_type
// // This expansion also replicated elsewhere, IE data_type__AndID
data_typeNoRef { $$ = $1; }
//
// // REFERENCES
//
// // IEEE: [ class_scope | package_scope ] type_identifier { packed_dimension }
| ps_type packed_dimensionListE { $$ = GRAMMARP->createArray($1,$2,true); }
//UNSUP class_scope_type packed_dimensionListE { UNSUP }
// // IEEE: class_type
//UNSUP class_typeWithoutId { $$ = $1; }
// // IEEE: ps_covergroup_identifier
// // we put covergroups under ps_type, so can ignore this
// // Don't distinguish between types and classes so all these combined
| package_scopeIdFollowsE idRefDType packed_dimensionListE
{ $2->packagep($1);
$$ = GRAMMARP->createArray($2, $3, true); }
| package_scopeIdFollowsE idRefDType parameter_value_assignmentClass packed_dimensionListE
{ $2->packagep($1);
BBUNSUP($3->fileline(), "Unsupported: Parameter classes");
$$ = GRAMMARP->createArray($2, $4, true); }
;
data_typeBasic<dtypep>: // IEEE: part of data_type
@ -1502,8 +1532,13 @@ data_typeNoRef<dtypep>: // ==IEEE: data_type, excluding class_type etc referenc
| ySTRING { $$ = new AstBasicDType($1,AstBasicDTypeKwd::STRING); }
| yCHANDLE { $$ = new AstBasicDType($1,AstBasicDTypeKwd::CHANDLE); }
| yEVENT { $$ = new AstBasicDType($1,AstBasicDTypeKwd::BIT); BBUNSUP($1, "Unsupported: event data types"); }
//UNSUP yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { UNSUP }
//UNSUP yVIRTUAL__anyID id/*interface*/ { UNSUP }
// // Rules overlap virtual_interface_declaration
// // Parameters here are SV2009
// // IEEE has ['.' modport] but that will conflict with port
// // declarations which decode '.' modport themselves, so
// // instead see data_typeVar
| yVIRTUAL__INTERFACE yINTERFACE id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual interface"); }
| yVIRTUAL__anyID id/*interface*/ { $$ = NULL; BBUNSUP($1, "Unsupported: virtual data type"); }
//UNSUP type_reference { UNSUP }
// // IEEE: class_scope: see data_type above
// // IEEE: class_type: see data_type above
@ -1521,6 +1556,10 @@ var_data_type<dtypep>: // ==IEEE: var_data_type
| yVAR implicit_typeE { $$ = $2; }
;
//UNSUP type_reference<str>: // ==IEEE: type_reference
//UNSUP yTYPE '(' exprOrDataType ')' { UNSUP }
//UNSUP ;
struct_unionDecl<uorstructp>: // IEEE: part of data_type
// // packedSigningE is NOP for unpacked
ySTRUCT packedSigningE '{' { $<uorstructp>$ = new AstStructDType($1, $2); SYMP->pushNew($<uorstructp>$); }
@ -1568,7 +1607,7 @@ member_decl_assignment<memberp>: // Derived from IEEE: variable_decl_assignment
//
// // IEEE: "[ covergroup_variable_identifier ] '=' class_new
// // Pushed into variable_declExpr:class_new
//UNSUP '=' class_new { UNSUP }
| '=' class_new { NULL; BBUNSUP($1, "Unsupported: member declaration assignment with new()"); }
;
list_of_variable_decl_assignments<nodep>: // ==IEEE: list_of_variable_decl_assignments
@ -1591,7 +1630,7 @@ variable_decl_assignment<varp>: // ==IEEE: variable_decl_assignment
//
// // IEEE: "[ covergroup_variable_identifier ] '=' class_new
// // Pushed into variable_declExpr:class_new
//UNSUP '=' class_new { UNSUP }
| '=' class_new { NULL; BBUNSUP($1, "Unsupported: declaration assignment with new()"); }
;
list_of_tf_variable_identifiers<nodep>: // ==IEEE: list_of_tf_variable_identifiers
@ -1609,8 +1648,8 @@ tf_variable_identifier<varp>: // IEEE: part of list_of_tf_variable_identifiers
variable_declExpr<nodep>: // IEEE: part of variable_decl_assignment - rhs of expr
expr { $$ = $1; }
//UNSUP dynamic_array_new { $$ = $1; }
//UNSUP class_new { $$ = $1; }
| dynamic_array_new { $$ = $1; }
| class_new { $$ = $1; }
;
variable_dimensionListE<rangep>: // IEEE: variable_dimension + empty
@ -1721,11 +1760,25 @@ data_declaration<nodep>: // ==IEEE: data_declaration
// // Therefore the virtual_interface_declaration term isn't used
;
class_property<nodep>: // ==IEEE: class_property, which is {property_qualifier} data_declaration
memberQualResetListE data_declarationVarClass { $$ = $2; }
| memberQualResetListE type_declaration { $$ = $2; }
| memberQualResetListE package_import_declaration { $$ = $2; }
// // IEEE: virtual_interface_declaration
// // "yVIRTUAL yID yID" looks just like a data_declaration
// // Therefore the virtual_interface_declaration term isn't used
;
data_declarationVar<nodep>: // IEEE: part of data_declaration
// // The first declaration has complications between assuming what's the type vs ID declaring
data_declarationVarFront list_of_variable_decl_assignments ';' { $$ = $2; }
;
data_declarationVarClass<nodep>: // IEEE: part of data_declaration (for class_property)
// // The first declaration has complications between assuming what's the type vs ID declaring
data_declarationVarFrontClass list_of_variable_decl_assignments ';' { $$ = $2; }
;
data_declarationVarFront: // IEEE: part of data_declaration
// // Non-ANSI; used inside block followed by ';'
// // SEE ALSO port_declaration, tf_port_declaration, port
@ -1748,6 +1801,21 @@ data_declarationVarFront: // IEEE: part of data_declaration
// // = class_new is in variable_decl_assignment
;
data_declarationVarFrontClass: // IEEE: part of data_declaration (for class_property)
// // VARRESET called before this rule
// // yCONST is removed, added to memberQual rules
// // implicit_type expanded into /*empty*/ or "signingE rangeList"
yVAR lifetimeE data_type { VARRESET_NONLIST(VAR); VARDTYPE($3); }
| yVAR lifetimeE { VARRESET_NONLIST(VAR); }
| yVAR lifetimeE signingE rangeList { /*VARRESET-in-ddVar*/ VARDTYPE(GRAMMARP->addRange(new AstBasicDType($<fl>1, LOGIC_IMPLICIT, $3), $4,true)); }
//
// // Expanded: "constE lifetimeE data_type"
| data_type { VARRESET_NONLIST(VAR); VARDTYPE($1); }
// // lifetime is removed, added to memberQual rules to avoid conflict
// // yCONST is removed, added to memberQual rules to avoid conflict
// // = class_new is in variable_decl_assignment
;
implicit_typeE<dtypep>: // IEEE: part of *data_type_or_implicit
// // Also expanded in data_declaration
/* empty */ { $$ = NULL; }
@ -1767,8 +1835,8 @@ type_declaration<nodep>: // ==IEEE: type_declaration
| yTYPEDEF yENUM idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF ySTRUCT idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF yUNION idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
//UNSUP yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
//UNSUP yTYPEDEF yINTERFACE yCLASS idAny ';' { ... }
| yTYPEDEF yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>3, *$3); SYMP->reinsert($$); PARSEP->tagNodep($$); }
| yTYPEDEF yINTERFACE yCLASS idAny ';' { $$ = NULL; $$ = new AstTypedefFwd($<fl>4, *$4); SYMP->reinsert($$); PARSEP->tagNodep($$); }
;
dtypeAttrListE<nodep>:
@ -1891,8 +1959,8 @@ bind_directive<nodep>: // ==IEEE: bind_directive + bind_target_scope
// // ';' - Note IEEE grammar is wrong, includes extra ';' - it's already in module_instantiation
// // We merged the rules - id may be a bind_target_instance or module_identifier or interface_identifier
yBIND bind_target_instance bind_instantiation { $$ = new AstBind($<fl>2, *$2, $3); }
| yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation {
$$=NULL; BBUNSUP($1, "Unsupported: Bind with instance list"); }
| yBIND bind_target_instance ':' bind_target_instance_list bind_instantiation
{ $$ = NULL; BBUNSUP($1, "Unsupported: Bind with instance list"); }
;
bind_target_instance_list: // ==IEEE: bind_target_instance_list
@ -2451,8 +2519,8 @@ statement_item<nodep>: // IEEE: statement_item
// // IEEE: blocking_assignment
// // 1800-2009 restricts LHS of assignment to new to not have a range
// // This is ignored to avoid conflicts
//UNSUP fexprLvalue '=' class_new ';' { UNSUP }
//UNSUP fexprLvalue '=' dynamic_array_new ';' { UNSUP }
| fexprLvalue '=' class_new ';' { $$ = new AstAssign($2, $1, $3); }
| fexprLvalue '=' dynamic_array_new ';' { $$ = new AstAssign($2, $1, $3); }
//
// // IEEE: nonblocking_assignment
| fexprLvalue yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
@ -2522,9 +2590,9 @@ statement_item<nodep>: // IEEE: statement_item
// // Because we've joined class_constructor_declaration into generic functions
// // Way over-permissive;
// // IEEE: [ ySUPER '.' yNEW [ '(' list_of_arguments ')' ] ';' ]
//UNSUP fexpr '.' class_new ';' { }
| fexpr '.' class_new ';' { $$ = NULL; BBUNSUP($1, "Unsupported: dotted new"); }
//
| statementVerilatorPragmas { $$ = $1; }
| statementVerilatorPragmas { $$ = $1; }
//
// // IEEE: disable_statement
| yDISABLE idAny/*hierarchical_identifier-task_or_block*/ ';' { $$ = new AstDisable($1,*$2); }
@ -2626,6 +2694,19 @@ finc_or_dec_expression<nodep>: // ==IEEE: inc_or_dec_expression
| yP_MINUSMINUS fexprLvalue { $$ = new AstAssign($1,$2,new AstSub ($1,$2->cloneTree(true),new AstConst($1, AstConst::StringToParse(), "'b1"))); }
;
class_new<nodep>: // ==IEEE: class_new
// // Special precence so (...) doesn't match expr
yNEW__ETC { $$ = new AstNew($1); }
| yNEW__ETC expr { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: new with expression"); }
// // Grammer abiguity; we assume "new (x)" the () are a argument, not expr
| yNEW__PAREN '(' list_of_argumentsE ')' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: new with arguments"); }
;
dynamic_array_new<nodep>: // ==IEEE: dynamic_array_new
yNEW__ETC '[' expr ']' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: Dynamic array new"); }
| yNEW__ETC '[' expr ']' '(' expr ')' { $$ = new AstNew($1); BBUNSUP($1, "Unsupported: Dynamic array new"); }
;
//************************************************
// Case/If
@ -2831,17 +2912,27 @@ funcRef<nodep>: // IEEE: part of tf_call
task_subroutine_callNoMethod<nodep>: // function_subroutine_callNoMethod (as task)
// // IEEE: tf_call
taskRef { $$ = $1; }
//UNSUP funcRef yWITH__PAREN '(' expr ')' { /*UNSUP*/ }
| system_t_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
//UNSUP randomize_call { $$ = $1; }
// // IEEE: ['std::'] not needed, as normal std package resolution will find it
// // IEEE: randomize_call
// // We implement randomize as a normal funcRef, since randomize isn't a keyword
// // Note yNULL is already part of expressions, so they come for free
//UNSUP funcRef yWITH__CUR constraint_block { }
;
function_subroutine_callNoMethod<nodep>: // IEEE: function_subroutine_call (as function)
// // IEEE: tf_call
funcRef { $$ = $1; }
//UNSUP funcRef yWITH__PAREN '(' expr ')' { /*UNSUP*/ }
| system_f_call { $$ = $1; }
// // IEEE: method_call requires a "." so is in expr
//UNSUP randomize_call { $$ = $1; }
// // IEEE: ['std::'] not needed, as normal std package resolution will find it
// // IEEE: randomize_call
// // We implement randomize as a normal funcRef, since randomize isn't a keyword
// // Note yNULL is already part of expressions, so they come for free
//UNSUP funcRef yWITH__CUR constraint_block { }
;
system_t_call<nodep>: // IEEE: system_tf_call (as task)
@ -3039,6 +3130,10 @@ function_declaration<ftaskp>: // IEEE: function_declaration + function_body_decl
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7,$$,$7); }
| yFUNCTION lifetimeE funcIdNew funcIsolateE tfGuts yENDFUNCTION endLabelE
{ $$ = $3; $3->attrIsolateAssign($4); $$->addStmtsp($5);
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7,$$,$7); }
;
function_prototype<ftaskp>: // IEEE: function_prototype
@ -3046,6 +3141,11 @@ function_prototype<ftaskp>: // IEEE: function_prototype
| yFUNCTION funcId { $$=$2; $$->prototype(true); SYMP->popScope($$); }
;
class_constructor_prototype<ftaskp>: // ==IEEE: class_constructor_prototype
yFUNCTION funcIdNew '(' tf_port_listE ')' ';' { $$ = $2; $$->addStmtsp($4); $$->prototype(true); SYMP->popScope($$); }
| yFUNCTION funcIdNew ';' { $$ = $2; $$->prototype(true); SYMP->popScope($$); }
;
funcIsolateE<cint>:
/* empty */ { $$ = 0; }
| yVL_ISOLATE_ASSIGNMENTS { $$ = 1; }
@ -3097,11 +3197,27 @@ funcId<ftaskp>: // IEEE: function_data_type_or_implicit + part of function_bod
SYMP->pushNewUnder($$, NULL); }
;
funcIdNew<ftaskp>: // IEEE: from class_constructor_declaration
yNEW__ETC
{ $$ = new AstFunc($<fl>1, "new", NULL, NULL);
BBUNSUP($<fl>1, "Unsupported: new constructor");
SYMP->pushNewUnder($$, NULL); }
| yNEW__PAREN
{ $$ = new AstFunc($<fl>1, "new", NULL, NULL);
BBUNSUP($<fl>1, "Unsupported: new constructor");
SYMP->pushNewUnder($$, NULL); }
| class_scopeWithoutId yNEW__PAREN
{ $$ = new AstFunc($<fl>2, "new", NULL, NULL);
BBUNSUP($<fl>2, "Unsupported: scoped new constructor");
SYMP->pushNewUnder($$, NULL); }
;
tfIdScoped<strp>: // IEEE: part of function_body_declaration/task_body_declaration
// // IEEE: [ interface_identifier '.' | class_scope ] function_identifier
id { $<fl>$=$<fl>1; $<strp>$ = $1; }
//UNSUP id/*interface_identifier*/ '.' id { UNSUP }
//UNSUP class_scope_id { UNSUP }
| id/*interface_identifier*/ '.' id { $<fl>$=$<fl>3; $<strp>$ = $3; BBUNSUP($2, "Unsupported: Out of block function declaration"); }
| class_scopeIdFollows id { $<fl>$=$<fl>2; $<scp>$=$<scp>1; $<strp>$=$<strp>2;
BBUNSUP($<fl>1, "Unsupported: Out of class block function declaration"); }
;
tfGuts<nodep>:
@ -3368,8 +3484,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
// // Indistinguishable from function_subroutine_call:method_call
//
| '$' { $$ = new AstUnbounded($<fl>1); }
| yNULL { $$ = new AstConst($1, AstConst::LogicFalse());
BBUNSUP($<fl>1, "Unsupported: null expression"); }
| yNULL { $$ = new AstConst($1, AstConst::LogicFalse()); }
// // IEEE: yTHIS
// // See exprScope
//
@ -3442,15 +3557,17 @@ exprScope<nodep>: // scope and variable for use to inside an expression
// // IEEE: [ implicit_class_handle . | class_scope | package_scope ] hierarchical_identifier select
// // Or method_call_body without parenthesis
// // See also varRefClassBit, which is the non-expr version of most of this
//UNSUP yTHIS { UNSUP }
idArrayed { $$ = $1; }
yTHIS { $$ = new AstConst($1, AstConst::LogicFalse());
BBUNSUP($1, "Unsupported: this"); }
| idArrayed { $$ = $1; }
| package_scopeIdFollows idArrayed { $$ = AstDot::newIfPkg($2->fileline(), $1, $2); }
//UNSUP class_scopeIdFollows idArrayed { UNSUP }
| class_scopeIdFollows idArrayed { $$ = $2; BBUNSUP($<fl>1, "Unsupported: scoped class reference"); }
| ~l~expr '.' idArrayed { $$ = new AstDot($<fl>2,$1,$3); }
// // expr below must be a "yTHIS"
//UNSUP ~l~expr '.' ySUPER { UNSUP }
| ~l~expr '.' ySUPER { $$ = $1; BBUNSUP($3, "Unsupported: super"); }
// // Part of implicit_class_handle
//UNSUP ySUPER { UNSUP }
| ySUPER { $$ = new AstConst($1, AstConst::LogicFalse());
BBUNSUP($1, "Unsupported: super"); }
;
fexprScope<nodep>: // exprScope, For use as first part of statement (disambiguates <=)
@ -3823,6 +3940,11 @@ idAny<strp>: // Any kind of identifier
| yaID__ETC { $$ = $1; $<fl>$=$<fl>1; }
;
idRefDType<refdtypep>: // IEEE: class_identifier or other type identifier
// Used where reference is needed
yaID__aTYPE { $$ = new AstRefDType($<fl>1, *$1); }
;
idSVKwd<strp>: // Warn about non-forward compatible Verilog 2001 code
// // yBIT, yBYTE won't work here as causes conflicts
yDO { static string s = "do" ; $$ = &s; ERRSVKWD($1,*$$); $<fl>$=$<fl>1; }
@ -3850,12 +3972,12 @@ variable_lvalueConcList<nodep>: // IEEE: part of variable_lvalue: '{' variable_l
idClassSel<nodep>: // Misc Ref to dotted, and/or arrayed, and/or bit-ranged variable
idDotted { $$ = $1; }
// // IEEE: [ implicit_class_handle . | package_scope ] hierarchical_variable_identifier select
//UNSUP yTHIS '.' idDotted { UNSUP }
//UNSUP ySUPER '.' idDotted { UNSUP }
//UNSUP yTHIS '.' ySUPER '.' idDotted { UNSUP }
| yTHIS '.' idDotted { $$ = $3; BBUNSUP($1, "Unsupported: this"); }
| ySUPER '.' idDotted { $$ = $3; BBUNSUP($1, "Unsupported: super"); }
| yTHIS '.' ySUPER '.' idDotted { $$ = $5; BBUNSUP($1, "Unsupported: this.super"); }
// // Expanded: package_scope idDotted
//UNSUP class_scopeIdFollows idDotted { UNSUP }
//UNSUP package_scopeIdFollows idDotted { UNSUP }
| class_scopeIdFollows idDotted { $$ = $2; BBUNSUP($2, "Unsupported: package scoped id"); }
| package_scopeIdFollows idDotted { $$ = $2; BBUNSUP($2, "Unsupported: class scoped id"); }
;
idDotted<nodep>:
@ -3919,7 +4041,7 @@ strAsText<nodep>:
endLabelE<strp>:
/* empty */ { $$ = NULL; $<fl>$=NULL; }
| ':' idAny { $$ = $2; $<fl>$=$<fl>2; }
//UNSUP ':' yNEW__ETC { $$ = $2; $<fl>$=$<fl>2; }
| ':' yNEW__ETC { static string n = "new"; $$ = &n; $<fl>$=$<fl>2; }
;
//************************************************
@ -4037,6 +4159,65 @@ property_spec<nodep>: // IEEE: property_spec
//**********************************************************************
// Class
class_declaration<nodep>: // ==IEEE: part of class_declaration
// // IEEE-2012: using this also for interface_class_declaration
// // The classExtendsE rule relys on classFront having the
// // new class scope correct via classFront
classFront parameter_port_listE classExtendsE classImplementsE ';'
class_itemListE yENDCLASS endLabelE
{ $$ = $1; $1->addMembersp($2);
$1->addMembersp($4); $1->addMembersp($6);
SYMP->popScope($$);
GRAMMARP->endLabel($<fl>7, $1, $8); }
;
classFront<classp>: // IEEE: part of class_declaration
classVirtualE yCLASS lifetimeE idAny/*class_identifier*/
{ $$ = new AstClass($2, *$4);
SYMP->pushNew($<classp>$);
BBUNSUP($2, "Unsupported: classes"); }
// // IEEE: part of interface_class_declaration
| yINTERFACE yCLASS lifetimeE idAny/*class_identifier*/
{ $$ = new AstClass($2, *$4);
SYMP->pushNew($<classp>$);
BBUNSUP($2, "Unsupported: interface classes"); }
;
classVirtualE:
/* empty */ { }
| yVIRTUAL__CLASS { BBUNSUP($1, "Unsupported: virtual classes"); }
;
classExtendsE<nodep>: // IEEE: part of class_declaration
// // The classExtendsE rule relys on classFront having the
// // new class scope correct via classFront
/* empty */ { $$ = NULL; }
| yEXTENDS classExtendsList { $$ = $2; }
;
classExtendsList<nodep>: // IEEE: part of class_declaration
classExtendsOne { $$ = $1; }
| classExtendsList ',' classExtendsOne { $$ = AstNode::addNextNull($1, $3); }
;
classExtendsOne<nodep>: // IEEE: part of class_declaration
class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
// // IEEE: Might not be legal to have more than one set of parameters in an extends
| class_typeWithoutId '(' list_of_argumentsE ')' { $$ = NULL; BBUNSUP($1, "Unsupported: extends"); }
;
classImplementsE<nodep>: // IEEE: part of class_declaration
// // All 1800-2012
/* empty */ { $$ = NULL; }
| yIMPLEMENTS classImplementsList { $$ = $2; }
;
classImplementsList<nodep>: // IEEE: part of class_declaration
// // All 1800-2012
class_typeWithoutId { $$ = NULL; BBUNSUP($1, "Unsupported: implements class"); }
| classImplementsList ',' class_typeWithoutId { $$ = AstNode::addNextNull($1, $3); }
;
//=========
// Package scoping - to traverse the symbol table properly, the final identifer
// must be included in the rules below.
@ -4049,13 +4230,48 @@ ps_id_etc: // package_scope + general id
ps_type<dtypep>: // IEEE: ps_parameter_identifier | ps_type_identifier
// Even though we looked up the type and have a AstNode* to it,
// we can't fully resolve it because it may have been just a forward definition.
package_scopeIdFollowsE yaID__aTYPE { $$ = new AstRefDType($<fl>2, *$2); VN_CAST($$, RefDType)->packagep($1); }
package_scopeIdFollowsE idRefDType { $$ = $2; $2->packagep($1); }
// // Simplify typing - from ps_covergroup_identifier
//UNSUP package_scopeIdFollowsE yaID__aCOVERGROUP { $<fl>$=$<fl>1; $$=$1+$2; }
;
//=== Below rules assume special scoping per above
class_typeWithoutId<nodep>: // as with class_typeWithoutId but allow yaID__aTYPE
// // and we thus don't need to resolve it in specified package
package_scopeIdFollowsE class_typeOneList { $$ = $2; $2->packagep($1); }
;
class_scopeWithoutId<nodep>: // class_type standalone without following id
// // and we thus don't need to resolve it in specified package
class_scopeIdFollows { $$ = $1; }
;
class_scopeIdFollows<nodep>: // IEEE: class_scope + type
// // IEEE: "class_type yP_COLONCOLON"
// // IMPORTANT: The lexer will parse the following ID to be in the found package
// // But class_type:'::' conflicts with class_scope:'::' so expand here
package_scopeIdFollowsE class_typeOneListColonIdFollows
{ $$ = NULL; BBUNSUP(CRELINE(), "Unsupported: scoped class reference"); }
;
class_typeOneListColonIdFollows: // IEEE: class_type :: but allow yaID__aTYPE
class_typeOneList yP_COLONCOLON { BBUNSUP($2, "Unsupported: Hierarchical class references"); }
;
class_typeOneList<refdtypep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
// // If you follow the rules down, class_type is really a list via ps_class_identifier
// // Must propagate scp up for next id
class_typeOne { $$ = $1; }
| class_typeOneListColonIdFollows class_typeOne { $$ = $2; /*UNSUP*/ }
;
class_typeOne<refdtypep>: // IEEE: class_type: "id [ parameter_value_assignment ]" but allow yaID__aTYPE
// // If you follow the rules down, class_type is really a list via ps_class_identifier
// // Not listed in IEEE, but see bug627 any parameter type maybe a class
idRefDType parameter_value_assignmentE
{ $$ = $1; if ($2) BBUNSUP($2->fileline(), "Unsupported: Parameterized classes"); }
;
package_scopeIdFollowsE<packagep>: // IEEE: [package_scope]
// // IMPORTANT: The lexer will parse the following ID to be in the found package
// // class_qualifier := [ yLOCAL '::' ] [ implicit_class_handle '.' class_scope ]
@ -4074,6 +4290,81 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
;
//^^^=========
class_itemListE<nodep>:
/* empty */ { $$ = NULL; }
| class_itemList { $$ = $1; }
;
class_itemList<nodep>:
class_item { $$ = $1; }
| class_itemList class_item { $$ = AstNode::addNextNull($1, $2); }
;
class_item<nodep>: // ==IEEE: class_item
class_property { $$ = $1; }
| class_method { $$ = $1; }
//UNSUP class_constraint { $$ = $1; }
//
| class_declaration { $$ = NULL; BBUNSUP($1, "Unsupported: class within class"); }
| timeunits_declaration { $$ = $1; }
//UNSUP covergroup_declaration { $$ = $1; }
| local_parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009
| parameter_declaration ';' { $$ = $1; BBUNSUP($2, "Unsupported: class parameters"); } // 1800-2009
| ';' { $$ = NULL; }
//
| error ';' { $$ = NULL; }
;
class_method<nodep>: // ==IEEE: class_method
memberQualResetListE task_declaration { $$ = $2; }
| memberQualResetListE function_declaration { $$ = $2; }
| yPURE yVIRTUAL__ETC memberQualResetListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: pure virtual class method"); }
| yEXTERN memberQualResetListE method_prototype ';'
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class method prototype"); }
// // IEEE: "method_qualifierE class_constructor_declaration"
// // part of function_declaration
| yEXTERN memberQualResetListE class_constructor_prototype
{ $$ = NULL; BBUNSUP($1, "Unsupported: extern class"); }
;
// IEEE: class_constructor_prototype
// See function_declaration
class_item_qualifier<nodep>: // IEEE: class_item_qualifier minus ySTATIC
// // IMPORTANT: yPROTECTED | yLOCAL is in a lex rule
yPROTECTED { $$ = NULL; } // Ignoring protected until implemented
| yLOCAL__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'local' class item"); }
| ySTATIC__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: 'static' class item"); }
;
memberQualResetListE<nodep>: // Called from class_property for all qualifiers before yVAR
// // Also before method declarations, to prevent grammar conflict
// // Thus both types of qualifiers (method/property) are here
/*empty*/ { $$ = NULL; }
| memberQualList { $$ = $1; }
;
memberQualList<nodep>:
memberQualOne { $$ = $1; }
| memberQualList memberQualOne { $$ = AstNode::addNextNull($1, $2); }
;
memberQualOne<nodep>: // IEEE: property_qualifier + method_qualifier
// // Part of method_qualifier and property_qualifier
class_item_qualifier { $$ = $1; }
// // Part of method_qualifier only
| yVIRTUAL__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: virtual class member qualifier"); }
// // Part of property_qualifier only
| random_qualifier { $$ = NULL; }
// // Part of lifetime, but here as ySTATIC can be in different positions
| yAUTOMATIC { $$ = NULL; BBUNSUP($1, "Unsupported: automatic class member qualifier"); }
// // Part of data_declaration, but not in data_declarationVarFrontClass
| yCONST__ETC { $$ = NULL; BBUNSUP($1, "Unsupported: const class member qualifier"); }
;
//**********************************************************************
// Constraints

View File

@ -1,4 +1,4 @@
%Error: t/t_flag_wpedantic_bad.v:7: syntax error, unexpected global, expecting IDENTIFIER or do or final
%Error: t/t_flag_wpedantic_bad.v:7: syntax error, unexpected global, expecting IDENTIFIER or '=' or do or final
reg global;
^
%Error: Exiting due to