From 7b6efd9dadd1a69cdfcdc030107c3824e7f30911 Mon Sep 17 00:00:00 2001 From: dalance Date: Fri, 16 Aug 2019 15:07:47 +0900 Subject: [PATCH] Add compiler_directives --- README.md | 6 +- .../src/general/compiler_directives.rs | 437 +++++ sv-parser-parser/src/general/mod.rs | 2 + sv-parser-parser/src/keywords.rs | 1446 +++++++++++++++++ sv-parser-parser/src/lib.rs | 8 +- .../src/source_text/library_source_text.rs | 5 +- .../source_text/system_verilog_source_text.rs | 7 +- sv-parser-parser/src/tests.rs | 362 +++-- sv-parser-parser/src/utils.rs | 332 +--- .../src/general/compiler_directives.rs | 176 ++ sv-parser-syntaxtree/src/general/mod.rs | 2 + .../src/source_text/library_source_text.rs | 2 +- .../source_text/system_verilog_source_text.rs | 6 +- sv-parser-syntaxtree/src/special_node.rs | 1 + 14 files changed, 2396 insertions(+), 396 deletions(-) create mode 100644 sv-parser-parser/src/general/compiler_directives.rs create mode 100644 sv-parser-parser/src/keywords.rs create mode 100644 sv-parser-syntaxtree/src/general/compiler_directives.rs diff --git a/README.md b/README.md index dae1224..0b84ef3 100644 --- a/README.md +++ b/README.md @@ -82,15 +82,15 @@ Parser library for System Verilog. | Clause | Exist | Pass | Clause | Exist | Pass | Clause | Exist | Pass | Clause | Exist | Pass | | ------ | ----- | ---- | ------ | ----- | ---- | ------ | ----- | ---- | ------ | ----- | ---- | | 3 | x | x | 13 | x | x | 23 | x | x | 33 | x | x | -| 4 | x | x | 14 | x | x | 24 | x | x | 34 | x | | +| 4 | x | x | 14 | x | x | 24 | x | x | 34 | x | x | | 5 | x | x | 15 | x | x | 25 | x | x | 35 | x | x | | 6 | x | x | 16 | x | x | 26 | x | x | 36 | x | x | | 7 | x | x | 17 | x | x | 27 | x | x | | | | | 8 | x | x | 18 | x | x | 28 | x | x | | | | | 9 | x | x | 19 | x | | 29 | x | x | | | | -| 10 | x | x | 20 | x | | 30 | x | x | | | | +| 10 | x | x | 20 | x | x | 30 | x | x | | | | | 11 | x | x | 21 | x | x | 31 | x | x | | | | -| 12 | x | x | 22 | | | 32 | x | x | | | | +| 12 | x | x | 22 | x | x | 32 | x | x | | | | ## Missing entry of specification diff --git a/sv-parser-parser/src/general/compiler_directives.rs b/sv-parser-parser/src/general/compiler_directives.rs new file mode 100644 index 0000000..b9e5e44 --- /dev/null +++ b/sv-parser-parser/src/general/compiler_directives.rs @@ -0,0 +1,437 @@ +use crate::*; + +// ----------------------------------------------------------------------------- + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn compiler_directive(s: Span) -> IResult { + alt(( + map(resetall_compiler_directive, |x| { + CompilerDirective::ResetallCompilerDirective(Box::new(x)) + }), + map(text_macro_definition, |x| { + CompilerDirective::TextMacroDefinition(Box::new(x)) + }), + map(undefine_compiler_directive, |x| { + CompilerDirective::UndefineCompilerDirective(Box::new(x)) + }), + map(undefineall_compiler_directive, |x| { + CompilerDirective::UndefineallCompilerDirective(Box::new(x)) + }), + map(timescale_compiler_directive, |x| { + CompilerDirective::TimescaleCompilerDirective(Box::new(x)) + }), + map(default_nettype_compiler_directive, |x| { + CompilerDirective::DefaultNettypeCompilerDirective(Box::new(x)) + }), + map(unconnected_drive_compiler_directive, |x| { + CompilerDirective::UnconnectedDriveCompilerDirective(Box::new(x)) + }), + map(nounconnected_drive_compiler_directive, |x| { + CompilerDirective::NounconnectedDriveCompilerDirective(Box::new(x)) + }), + map(celldefine_compiler_directive, |x| { + CompilerDirective::CelldefineDriveCompilerDirective(Box::new(x)) + }), + map(endcelldefine_compiler_directive, |x| { + CompilerDirective::EndcelldefineDriveCompilerDirective(Box::new(x)) + }), + map(pragma, |x| CompilerDirective::Pragma(Box::new(x))), + map(line_compiler_directive, |x| { + CompilerDirective::LineCompilerDirective(Box::new(x)) + }), + map(keywords_directive, |x| { + CompilerDirective::KeywordsDirective(Box::new(x)) + }), + map(endkeywords_directive, |x| { + CompilerDirective::EndkeywordsDirective(Box::new(x)) + }), + ))(s) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn resetall_compiler_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("resetall")(s)?; + Ok((s, ResetallCompilerDirective { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn text_macro_definition(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("define")(s)?; + let (s, c) = text_macro_name(s)?; + let (s, d) = opt(macro_text)(s)?; + Ok(( + s, + TextMacroDefinition { + nodes: (a, b, c, d), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn text_macro_name(s: Span) -> IResult { + let (s, a) = text_macro_identifier(s)?; + let (s, b) = opt(paren(list_of_formal_arguments))(s)?; + Ok((s, TextMacroName { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn list_of_formal_arguments(s: Span) -> IResult { + let (s, a) = list(symbol(","), formal_argument)(s)?; + Ok((s, ListOfFormalArguments { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn formal_argument(s: Span) -> IResult { + let (s, a) = simple_identifier(s)?; + let (s, b) = opt(pair(symbol("="), default_text))(s)?; + Ok((s, FormalArgument { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn text_macro_identifier(s: Span) -> IResult { + let (s, a) = identifier(s)?; + Ok((s, TextMacroIdentifier { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn macro_text(s: Span) -> IResult { + let (s, a) = many1(alt((tag("\\\n"), tag("\\"), is_not("\\\n"))))(s)?; + + let mut ret = None; + for x in a { + ret = if let Some(ret) = ret { + Some(concat(ret, x).unwrap()) + } else { + Some(x) + } + } + let a = ret.unwrap(); + Ok(( + s, + MacroText { + nodes: (into_locate(a),), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn default_text(s: Span) -> IResult { + let (s, a) = is_not(",)")(s)?; + Ok(( + s, + DefaultText { + nodes: (into_locate(a),), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn undefine_compiler_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("undef")(s)?; + let (s, c) = text_macro_identifier(s)?; + Ok((s, UndefineCompilerDirective { nodes: (a, b, c) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn undefineall_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("undefineall")(s)?; + Ok((s, UndefineallCompilerDirective { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn timescale_compiler_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("timescale")(s)?; + let (s, c) = time_literal(s)?; + let (s, d) = symbol("/")(s)?; + let (s, e) = time_literal(s)?; + Ok(( + s, + TimescaleCompilerDirective { + nodes: (a, b, c, d, e), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn default_nettype_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("default_nettype")(s)?; + let (s, c) = default_nettype_value(s)?; + Ok((s, DefaultNettypeCompilerDirective { nodes: (a, b, c) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn default_nettype_value(s: Span) -> IResult { + let (s, a) = alt(( + keyword("none"), + keyword("tri0"), + keyword("tri1"), + keyword("trior"), + keyword("trireg"), + keyword("triwand"), + keyword("tri"), + keyword("uwire"), + keyword("wand"), + keyword("wire"), + keyword("wor"), + ))(s)?; + Ok((s, DefaultNettypeValue { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn unconnected_drive_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("unconnected_drive")(s)?; + let (s, c) = alt((keyword("pull0"), keyword("pull1")))(s)?; + Ok((s, UnconnectedDriveCompilerDirective { nodes: (a, b, c) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn nounconnected_drive_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("nounconnected_drive")(s)?; + Ok((s, NounconnectedDriveCompilerDirective { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn celldefine_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("celldefine")(s)?; + Ok((s, CelldefineDriveCompilerDirective { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn endcelldefine_compiler_directive( + s: Span, +) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("endcelldefine")(s)?; + Ok((s, EndcelldefineDriveCompilerDirective { nodes: (a, b) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("pragma")(s)?; + let (s, c) = pragma_name(s)?; + let (s, d) = opt(list(symbol(","), pragma_expression))(s)?; + Ok(( + s, + Pragma { + nodes: (a, b, c, d), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_name(s: Span) -> IResult { + let (s, a) = simple_identifier(s)?; + Ok((s, PragmaName { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_expression(s: Span) -> IResult { + alt(( + pragma_expression_assignment, + map(pragma_keyword, |x| { + PragmaExpression::PragmaKeyword(Box::new(x)) + }), + map(pragma_value, |x| PragmaExpression::PragmaValue(Box::new(x))), + ))(s) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_expression_assignment(s: Span) -> IResult { + let (s, a) = pragma_keyword(s)?; + let (s, b) = symbol("=")(s)?; + let (s, c) = pragma_value(s)?; + Ok(( + s, + PragmaExpression::Assignment(Box::new(PragmaExpressionAssignment { nodes: (a, b, c) })), + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_value(s: Span) -> IResult { + alt(( + pragma_value_paren, + map(number, |x| PragmaValue::Number(Box::new(x))), + map(string_literal, |x| PragmaValue::StringLiteral(Box::new(x))), + map(identifier_pragma, |x| PragmaValue::Identifier(Box::new(x))), + ))(s) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_value_paren(s: Span) -> IResult { + let (s, a) = paren(list(symbol(","), pragma_expression))(s)?; + Ok(( + s, + PragmaValue::Paren(Box::new(PragmaValueParen { nodes: (a,) })), + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn pragma_keyword(s: Span) -> IResult { + let (s, a) = simple_identifier_pragma(s)?; + Ok((s, PragmaKeyword { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn identifier_pragma(s: Span) -> IResult { + alt(( + map(escaped_identifier, |x| { + Identifier::EscapedIdentifier(Box::new(x)) + }), + map(simple_identifier_pragma, |x| { + Identifier::SimpleIdentifier(Box::new(x)) + }), + ))(s) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn simple_identifier_pragma(s: Span) -> IResult { + let (s, a) = ws(simple_identifier_pragma_impl)(s)?; + Ok((s, SimpleIdentifier { nodes: a })) +} + +#[tracable_parser] +pub(crate) fn simple_identifier_pragma_impl(s: Span) -> IResult { + let (s, a) = is_a(AZ_)(s)?; + let (s, b) = opt(is_a(AZ09_DOLLAR))(s)?; + let a = if let Some(b) = b { + concat(a, b).unwrap() + } else { + a + }; + Ok((s, into_locate(a))) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn line_compiler_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("line")(s)?; + let (s, c) = number(s)?; + let (s, d) = string_literal(s)?; + let (s, e) = level(s)?; + Ok(( + s, + LineCompilerDirective { + nodes: (a, b, c, d, e), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn level(s: Span) -> IResult { + let (s, a) = alt((symbol("0"), symbol("1"), symbol("2")))(s)?; + Ok((s, Level { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn keywords_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("begin_keywords")(s)?; + let (s, c) = symbol("\"")(s)?; + let (s, d) = version_specifier(s)?; + let (s, e) = symbol("\"")(s)?; + Ok(( + s, + KeywordsDirective { + nodes: (a, b, c, d, e), + }, + )) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn version_specifier(s: Span) -> IResult { + let (s, a) = alt(( + map(keyword("1800-2017"), |x| { + begin_keywords("1800-2017"); + x + }), + map(keyword("1800-2012"), |x| { + begin_keywords("1800-2012"); + x + }), + map(keyword("1800-2009"), |x| { + begin_keywords("1800-2009"); + x + }), + map(keyword("1800-2005"), |x| { + begin_keywords("1800-2005"); + x + }), + map(keyword("1364-2005"), |x| { + begin_keywords("1364-2005"); + x + }), + map(keyword("1364-2001"), |x| { + begin_keywords("1364-2001"); + x + }), + map(keyword("1364-2001-noconfig"), |x| { + begin_keywords("1364-2001-noconfig"); + x + }), + map(keyword("1364-1995"), |x| { + begin_keywords("1364-1995"); + x + }), + ))(s)?; + Ok((s, VersionSpecifier { nodes: (a,) })) +} + +#[tracable_parser] +#[packrat_parser] +pub(crate) fn endkeywords_directive(s: Span) -> IResult { + let (s, a) = symbol("`")(s)?; + let (s, b) = keyword("end_keywords")(s)?; + end_keywords(); + Ok((s, EndkeywordsDirective { nodes: (a, b) })) +} diff --git a/sv-parser-parser/src/general/mod.rs b/sv-parser-parser/src/general/mod.rs index 27f9c15..886f599 100644 --- a/sv-parser-parser/src/general/mod.rs +++ b/sv-parser-parser/src/general/mod.rs @@ -1,6 +1,8 @@ pub mod attributes; pub mod comments; +pub mod compiler_directives; pub mod identifiers; pub(crate) use attributes::*; pub(crate) use comments::*; +pub(crate) use compiler_directives::*; pub(crate) use identifiers::*; diff --git a/sv-parser-parser/src/keywords.rs b/sv-parser-parser/src/keywords.rs new file mode 100644 index 0000000..7f9f03d --- /dev/null +++ b/sv-parser-parser/src/keywords.rs @@ -0,0 +1,1446 @@ +pub(crate) const KEYWORDS_1364_1995: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", +]; + +pub(crate) const KEYWORDS_1364_2001: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "cell", + "config", + "design", + "endconfig", + "endgenerate", + "generate", + "genvar", + "incdir", + "include", + "instance", + "liblist", + "library", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", + "use", +]; + +pub(crate) const KEYWORDS_1364_2001_NOCONFIG: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "endgenerate", + "generate", + "genvar", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", +]; + +pub(crate) const KEYWORDS_1364_2005: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "cell", + "config", + "design", + "endconfig", + "endgenerate", + "generate", + "genvar", + "incdir", + "include", + "instance", + "liblist", + "library", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", + "use", + "uwire", +]; + +pub(crate) const KEYWORDS_1800_2005: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "cell", + "config", + "design", + "endconfig", + "endgenerate", + "generate", + "genvar", + "incdir", + "include", + "instance", + "liblist", + "library", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", + "use", + "uwire", + "alias", + "always_comb", + "always_ff", + "always_latch", + "assert", + "assume", + "before", + "bind", + "bins", + "binsof", + "bit", + "break", + "byte", + "chandle", + "class", + "clocking", + "const", + "constraint", + "context", + "continue", + "cover", + "covergroup", + "coverpoint", + "cross", + "dist", + "do", + "endclass", + "endclocking", + "endgroup", + "endinterface", + "endpackage", + "endprogram", + "endproperty", + "endsequence", + "enum", + "expect", + "export", + "extends", + "extern", + "final", + "first_match", + "foreach", + "forkjoin", + "iff", + "ignore_bins", + "illegal_bins", + "import", + "inside", + "int", + "interface", + "intersect", + "join_any", + "join_none", + "local", + "logic", + "longint", + "matches", + "modport", + "new", + "null", + "package", + "packed", + "priority", + "program", + "property", + "protected", + "pure", + "rand", + "randc", + "randcase", + "randsequence", + "ref", + "return", + "sequence", + "shortint", + "shortreal", + "solve", + "static", + "string", + "struct", + "super", + "tagged", + "this", + "throughout", + "timeprecision", + "timeunit", + "type", + "typedef", + "union", + "unique", + "var", + "virtual", + "void", + "wait_order", + "wildcard", + "with", + "within", +]; + +pub(crate) const KEYWORDS_1800_2009: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "cell", + "config", + "design", + "endconfig", + "endgenerate", + "generate", + "genvar", + "incdir", + "include", + "instance", + "liblist", + "library", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", + "use", + "uwire", + "alias", + "always_comb", + "always_ff", + "always_latch", + "assert", + "assume", + "before", + "bind", + "bins", + "binsof", + "bit", + "break", + "byte", + "chandle", + "class", + "clocking", + "const", + "constraint", + "context", + "continue", + "cover", + "covergroup", + "coverpoint", + "cross", + "dist", + "do", + "endclass", + "endclocking", + "endgroup", + "endinterface", + "endpackage", + "endprogram", + "endproperty", + "endsequence", + "enum", + "expect", + "export", + "extends", + "extern", + "final", + "first_match", + "foreach", + "forkjoin", + "iff", + "ignore_bins", + "illegal_bins", + "import", + "inside", + "int", + "interface", + "intersect", + "join_any", + "join_none", + "local", + "logic", + "longint", + "matches", + "modport", + "new", + "null", + "package", + "packed", + "priority", + "program", + "property", + "protected", + "pure", + "rand", + "randc", + "randcase", + "randsequence", + "ref", + "return", + "sequence", + "shortint", + "shortreal", + "solve", + "static", + "string", + "struct", + "super", + "tagged", + "this", + "throughout", + "timeprecision", + "timeunit", + "type", + "typedef", + "union", + "unique", + "var", + "virtual", + "void", + "wait_order", + "wildcard", + "with", + "within", + "accept_on", + "checker", + "endchecker", + "eventually", + "global", + "implies", + "let", + "nexttime", + "reject_on", + "restrict", + "s_always", + "s_eventually", + "s_nexttime", + "s_until", + "s_until_with", + "strong", + "sync_accept_on", + "sync_reject_on", + "unique0", + "until", + "until_with", + "untyped", + "weak", +]; + +pub(crate) const KEYWORDS_1800_2012: &[&str] = &[ + "always", + "and", + "assign", + "begin", + "buf", + "bufif0", + "bufif1", + "case", + "casex", + "casez", + "cmos", + "deassign", + "default", + "defparam", + "disable", + "edge", + "else", + "end", + "endcase", + "endfunction", + "endmodule", + "endprimitive", + "endspecify", + "endtable", + "endtask", + "event", + "for", + "force", + "forever", + "fork", + "function", + "highz0", + "highz1", + "if", + "ifnone", + "initial", + "inout", + "input", + "integer", + "join", + "large", + "macromodule", + "medium", + "module", + "nand", + "negedge", + "nmos", + "nor", + "not", + "notif0", + "notif1", + "or", + "output", + "parameter", + "pmos", + "posedge", + "primitive", + "pull0", + "pull1", + "pulldown", + "pullup", + "rcmos", + "real", + "realtime", + "reg", + "release", + "repeat", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "scalared", + "small", + "specify", + "specparam", + "strong0", + "strong1", + "supply0", + "supply1", + "table", + "task", + "time", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "vectored", + "wait", + "wand", + "weak0", + "weak1", + "while", + "wire", + "wor", + "xnor", + "xor", + "automatic", + "cell", + "config", + "design", + "endconfig", + "endgenerate", + "generate", + "genvar", + "incdir", + "include", + "instance", + "liblist", + "library", + "localparam", + "noshowcancelled", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "showcancelled", + "signed", + "unsigned", + "use", + "uwire", + "alias", + "always_comb", + "always_ff", + "always_latch", + "assert", + "assume", + "before", + "bind", + "bins", + "binsof", + "bit", + "break", + "byte", + "chandle", + "class", + "clocking", + "const", + "constraint", + "context", + "continue", + "cover", + "covergroup", + "coverpoint", + "cross", + "dist", + "do", + "endclass", + "endclocking", + "endgroup", + "endinterface", + "endpackage", + "endprogram", + "endproperty", + "endsequence", + "enum", + "expect", + "export", + "extends", + "extern", + "final", + "first_match", + "foreach", + "forkjoin", + "iff", + "ignore_bins", + "illegal_bins", + "import", + "inside", + "int", + "interface", + "intersect", + "join_any", + "join_none", + "local", + "logic", + "longint", + "matches", + "modport", + "new", + "null", + "package", + "packed", + "priority", + "program", + "property", + "protected", + "pure", + "rand", + "randc", + "randcase", + "randsequence", + "ref", + "return", + "sequence", + "shortint", + "shortreal", + "solve", + "static", + "string", + "struct", + "super", + "tagged", + "this", + "throughout", + "timeprecision", + "timeunit", + "type", + "typedef", + "union", + "unique", + "var", + "virtual", + "void", + "wait_order", + "wildcard", + "with", + "within", + "accept_on", + "checker", + "endchecker", + "eventually", + "global", + "implies", + "let", + "nexttime", + "reject_on", + "restrict", + "s_always", + "s_eventually", + "s_nexttime", + "s_until", + "s_until_with", + "strong", + "sync_accept_on", + "sync_reject_on", + "unique0", + "until", + "until_with", + "untyped", + "weak", + "implements", + "interconnect", + "nettype", + "soft", +]; + +pub(crate) const KEYWORDS_1800_2017: &[&str] = &[ + "accept_on", + "alias", + "always", + "always_comb", + "always_ff", + "always_latch", + "and", + "assert", + "assign", + "assume", + "automatic", + "before", + "begin", + "bind", + "bins", + "binsof", + "bit", + "break", + "buf", + "bufif0", + "bufif1", + "byte", + "case", + "casex", + "casez", + "cell", + "chandle", + "checker", + "class", + "clocking", + "cmos", + "config", + "const", + "constraint", + "context", + "continue", + "cover", + "covergroup", + "coverpoint", + "cross", + "deassign", + "default", + "defparam", + "design", + "disable", + "dist", + "do", + "edge", + "else", + "end", + "endcase", + "endchecker", + "endclass", + "endclocking", + "endconfig", + "endfunction", + "endgenerate", + "endgroup", + "endinterface", + "endmodule", + "endpackage", + "endprimitive", + "endprogram", + "endproperty", + "endspecify", + "endsequence", + "endtable", + "endtask", + "enum", + "event", + "eventually", + "expect", + "export", + "extends", + "extern", + "final", + "first_match", + "for", + "force", + "foreach", + "forever", + "fork", + "forkjoin", + "function", + "generate", + "genvar", + "global", + "highz0", + "highz1", + "if", + "iff", + "ifnone", + "ignore_bins", + "illegal_bins", + "implements", + "implies", + "import", + "incdir", + "include", + "initial", + "inout", + "input", + "inside", + "instance", + "int", + "integer", + "interconnect", + "interface", + "intersect", + "join", + "join_any", + "join_none", + "large", + "let", + "liblist", + "library", + "local", + "localparam", + "logic", + "longint", + "macromodule", + "matches", + "medium", + "modport", + "module", + "nand", + "negedge", + "nettype", + "new", + "nexttime", + "nmos", + "nor", + "noshowcancelled", + "not", + "notif0", + "notif1", + "null", + "or", + "output", + "package", + "packed", + "parameter", + "pmos", + "posedge", + "primitive", + "priority", + "program", + "property", + "protected", + "pull0", + "pull1", + "pulldown", + "pullup", + "pulsestyle_ondetect", + "pulsestyle_onevent", + "pure", + "rand", + "randc", + "randcase", + "randsequence", + "rcmos", + "real", + "realtime", + "ref", + "reg", + "reject_on", + "release", + "repeat", + "restrict", + "return", + "rnmos", + "rpmos", + "rtran", + "rtranif0", + "rtranif1", + "s_always", + "s_eventually", + "s_nexttime", + "s_until", + "s_until_with", + "scalared", + "sequence", + "shortint", + "shortreal", + "showcancelled", + "signed", + "small", + "soft", + "solve", + "specify", + "specparam", + "static", + "string", + "strong", + "strong0", + "strong1", + "struct", + "super", + "supply0", + "supply1", + "sync_accept_on", + "sync_reject_on", + "table", + "tagged", + "task", + "this", + "throughout", + "time", + "timeprecision", + "timeunit", + "tran", + "tranif0", + "tranif1", + "tri", + "tri0", + "tri1", + "triand", + "trior", + "trireg", + "type", + "typedef", + "union", + "unique", + "unique0", + "unsigned", + "until", + "until_with", + "untyped", + "use", + "uwire", + "var", + "vectored", + "virtual", + "void", + "wait", + "wait_order", + "wand", + "weak", + "weak0", + "weak1", + "while", + "wildcard", + "wire", + "with", + "within", + "wor", + "xnor", + "xor", +]; diff --git a/sv-parser-parser/src/lib.rs b/sv-parser-parser/src/lib.rs index 5e135a6..f041680 100644 --- a/sv-parser-parser/src/lib.rs +++ b/sv-parser-parser/src/lib.rs @@ -1,5 +1,7 @@ +pub mod keywords; #[macro_use] pub mod utils; +pub(crate) use keywords::*; pub(crate) use utils::*; mod tests; @@ -72,11 +74,6 @@ impl HasTracableInfo for SpanInfo { } } -//impl HasExtraState for SpanInfo { -// fn get_extra_state(&self) -> RecursiveInfo { -// self.recursive_info -// } -//} impl HasExtraState<()> for SpanInfo { fn get_extra_state(&self) -> () { () @@ -85,7 +82,6 @@ impl HasExtraState<()> for SpanInfo { // ----------------------------------------------------------------------------- -//nom_packrat::storage!(AnyNode, RecursiveInfo); nom_packrat::storage!(AnyNode); pub fn parse_sv(s: &str) -> Result { diff --git a/sv-parser-parser/src/source_text/library_source_text.rs b/sv-parser-parser/src/source_text/library_source_text.rs index 75e0352..d2e9181 100644 --- a/sv-parser-parser/src/source_text/library_source_text.rs +++ b/sv-parser-parser/src/source_text/library_source_text.rs @@ -5,8 +5,9 @@ use crate::*; #[tracable_parser] #[packrat_parser] pub(crate) fn library_text(s: Span) -> IResult { - let (s, a) = many0(library_description)(s)?; - Ok((s, LibraryText { nodes: (a,) })) + let (s, a) = many0(white_space)(s)?; + let (s, b) = many0(library_description)(s)?; + Ok((s, LibraryText { nodes: (a, b) })) } #[tracable_parser] diff --git a/sv-parser-parser/src/source_text/system_verilog_source_text.rs b/sv-parser-parser/src/source_text/system_verilog_source_text.rs index 7a7af18..2d65b43 100644 --- a/sv-parser-parser/src/source_text/system_verilog_source_text.rs +++ b/sv-parser-parser/src/source_text/system_verilog_source_text.rs @@ -5,9 +5,10 @@ use crate::*; #[tracable_parser] #[packrat_parser] pub(crate) fn source_text(s: Span) -> IResult { - let (s, a) = opt(timeunits_declaration)(s)?; - let (s, b) = many0(description)(s)?; - Ok((s, SourceText { nodes: (a, b) })) + let (s, a) = many0(white_space)(s)?; + let (s, b) = opt(timeunits_declaration)(s)?; + let (s, c) = many0(description)(s)?; + Ok((s, SourceText { nodes: (a, b, c) })) } #[tracable_parser] diff --git a/sv-parser-parser/src/tests.rs b/sv-parser-parser/src/tests.rs index 9d91633..d6b9b92 100644 --- a/sv-parser-parser/src/tests.rs +++ b/sv-parser-parser/src/tests.rs @@ -9,7 +9,7 @@ macro_rules! test { #[cfg(feature = "trace")] let info = info.set_tracable_info( info.get_tracable_info() - .fold("white_space") + //.fold("white_space") .fold("number") .fold("binary_operator") .fold("unary_operator"), @@ -290,6 +290,18 @@ mod unit { fn test_expression() { test!(expression, "(!a ? 0 : !b : 1 : c ? 0 : 1)", Ok((_, _))); } + + #[test] + fn test_text_macro_definition() { + test!(text_macro_definition, r##"`define a b c"##, Ok((_, _))); + test!( + text_macro_definition, + r##"`define a b \ + c"##, + Ok((_, _)) + ); + test!(text_macro_definition, r##"`define a"##, Ok((_, _))); + } } mod spec { @@ -11056,87 +11068,87 @@ mod spec { #[test] fn clause20() { - //test!( - // many1(module_item), - // r##"`timescale 10 ns / 1 ns - // module test; - // logic set; - // parameter p = 1.55; - // initial begin - // $monitor($time,,"set=", set); - // #p set = 0; - // #p set = 1; - // end - // endmodule"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"`timescale 10 ns / 1 ns - // module test; - // logic set; - // parameter p = 1.55; - // initial begin - // $monitor($realtime,,"set=", set); - // #p set = 0; - // #p set = 1; - // end - // endmodule"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"`timescale 1 ms / 1 us - // module a_dat; - // initial - // $printtimescale(b_dat.c1); - // endmodule + test!( + source_text, + r##"`timescale 10 ns / 1 ns + module test; + logic set; + parameter p = 1.55; + initial begin + $monitor($time,,"set=", set); + #p set = 0; + #p set = 1; + end + endmodule"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`timescale 10 ns / 1 ns + module test; + logic set; + parameter p = 1.55; + initial begin + $monitor($realtime,,"set=", set); + #p set = 0; + #p set = 1; + end + endmodule"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`timescale 1 ms / 1 us + module a_dat; + initial + $printtimescale(b_dat.c1); + endmodule - // `timescale 10 fs / 1 fs - // module b_dat; - // c_dat c1 (); - // endmodule + `timescale 10 fs / 1 fs + module b_dat; + c_dat c1 (); + endmodule - // `timescale 1 ns / 1 ns - // module c_dat; - // endmodule"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"`timescale 1 ms / 1 ns - // module cntrl; - // initial - // i $timeformat(-9, 5, " ns", 10); - // endmodule + `timescale 1 ns / 1 ns + module c_dat; + endmodule"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`timescale 1 ms / 1 ns + module cntrl; + initial + $timeformat(-9, 5, " ns", 10); + endmodule - // `timescale 1 fs / 1 fs - // module a1_dat; - // logic in1; - // integer file; - // buf #10000000 (o1,in1); - // initial begin - // file = $fopen("a1.dat"); - // #00000000 $fmonitor(file,"%m: %t in1=%d o1=%h", $realtime,in1,o1); - // #10000000 in1 = 0; - // #10000000 in1 = 1; - // end - // endmodule + `timescale 1 fs / 1 fs + module a1_dat; + logic in1; + integer file; + buf #10000000 (o1,in1); + initial begin + file = $fopen("a1.dat"); + #00000000 $fmonitor(file,"%m: %t in1=%d o1=%h", $realtime,in1,o1); + #10000000 in1 = 0; + #10000000 in1 = 1; + end + endmodule - // `timescale 1 ps / 1 ps - // module a2_dat; - // logic in2; - // integer file2; - // buf #10000 (o2,in2); - // initial begin - // file2=$fopen("a2.dat"); - // #00000 $fmonitor(file2,"%m: %t in2=%d o2=%h",$realtime,in2,o2); - // #10000 in2 = 0; - // #10000 in2 = 1; - // end - // endmodule"##, - // Ok((_, _)) - //); + `timescale 1 ps / 1 ps + module a2_dat; + logic in2; + integer file2; + buf #10000 (o2,in2); + initial begin + file2=$fopen("a2.dat"); + #00000 $fmonitor(file2,"%m: %t in2=%d o2=%h",$realtime,in2,o2); + #10000 in2 = 0; + #10000 in2 = 1; + end + endmodule"##, + Ok((_, _)) + ); test!( many1(module_item), r##"module driver (net_r); @@ -11747,6 +11759,93 @@ mod spec { ); } + #[test] + fn clause22() { + test!( + source_text, + r##"`define D(x,y) initial $display("start", x , y, "end");"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`define MACRO1(a=5,b="B",c) $display(a,,b,,c); + `define MACRO2(a=5, b, c="C") $display(a,,b,,c); + `define MACRO3(a=5, b=0, c="C") $display(a,,b,,c);"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`define wordsize 8 + `define var_nand(dly) nand #dly"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`define max(a,b)((a) > (b) ? (a) : (b))"##, + Ok((_, _)) + ); + test!(source_text, r##"`define TOP(a,b) a + b"##, Ok((_, _))); + test!( + source_text, + r##"`define msg(x,y) `"x: `\`"y`\`"`""##, + Ok((_, _)) + ); + test!(source_text, r##"`define append(f) f``_master"##, Ok((_, _))); + test!( + source_text, + r##"`define home(filename) `"/home/mydir/filename`""##, + Ok((_, _)) + ); + test!(source_text, r##"`timescale 1 ns / 1 ps"##, Ok((_, _))); + test!(source_text, r##"`timescale 10 us / 100 ns"##, Ok((_, _))); + test!( + source_text, + r##"`timescale 10 ns / 1 ns + module test; + logic set; + parameter d = 1.55; + + initial begin + #d set = 0; + #d set = 1; + end + endmodule"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`line 3 "orig.v" 2 + // This line is line 3 of orig.v after exiting include file"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`begin_keywords "1364-2001" // use IEEE Std 1364-2001 Verilog keywords + module m2; + reg [63:0] logic; // OK: "logic" is not a keyword in 1364-2001 + endmodule + `end_keywords"##, + Ok((_, _)) + ); + test!( + source_text, + r##"`begin_keywords "1800-2005" // use IEEE Std 1800-2005 SystemVerilog keywords + module m2; + reg [63:0] logic; // ERROR: "logic" is a keyword in 1800-2005 + endmodule + `end_keywords"##, + Err(_) + ); + test!( + source_text, + r##"`begin_keywords "1800-2005" // use IEEE Std 1800-2005 SystemVerilog keywords + interface if1; + endinterface + `end_keywords"##, + Ok((_, _)) + ); + } + #[test] fn clause23() { test!( @@ -15475,56 +15574,56 @@ mod spec { #[test] fn clause34() { - //test!( - // source_text, - // r##"module secret (a, b); - // input a; - // output b; + test!( + source_text, + r##"module secret (a, b); + input a; + output b; - // `pragma protect encoding=(enctype="raw") - // `pragma protect data_method="x-caesar", data_keyname="rot13", begin - // `pragma protect - // runtime_license=(library="lic.so",feature="runSecret",entry="chk", match=42) - // logic b; - // initial - // begin - // b = 0; - // end + `pragma protect encoding=(enctype="raw") + `pragma protect data_method="x-caesar", data_keyname="rot13", begin + `pragma protect + runtime_license=(library="lic.so",feature="runSecret",entry="chk", match=42) + logic b; + initial + begin + b = 0; + end - // always - // begin - // #5 b = a; - // end - // `pragma protect end - // endmodule // secret"##, - // Ok((_, _)) - //); - //test!( - // source_text, - // r##"module secret (a, b); - // input a; - // output b; - // `pragma protect encoding=(enctype="raw") - // `pragma protect data_method="x-caesar", data_keyname="rot13", - // begin_protected - // `pragma protect encoding=(enctype="raw", bytes=190), data_block - // `centzn cebgrpg ehagvzr_yvprafr=(yvoenel="yvp.fb",srngher="ehaFrperg", - // ragel="pux",zngpu=42) - // ert o; - // vavgvny - // ortva - // o = 0; - // raq + always + begin + #5 b = a; + end + `pragma protect end + endmodule // secret"##, + Ok((_, _)) + ); + test!( + source_text, + r##"module secret (a, b); + input a; + output b; + `pragma protect encoding=(enctype="raw") + `pragma protect data_method="x-caesar", data_keyname="rot13", + begin_protected + `pragma protect encoding=(enctype="raw", bytes=190), data_block + //`centzn cebgrpg ehagvzr_yvprafr=(yvoenel="yvp.fb",srngher="ehaFrperg", + //ragel="pux",zngpu=42) + // ert o; + // vavgvny + // ortva + // o = 0; + // raq - // nyjnlf - // ortva - // #5 o = n; - // raq - // `pragma protect end_protected - // `pragma reset protect - // endmodule // secret"##, - // Ok((_, _)) - //); + // nyjnlf + // ortva + // #5 o = n; + // raq + `pragma protect end_protected + `pragma reset protect + endmodule // secret"##, + Ok((_, _)) + ); } #[test] @@ -15603,4 +15702,15 @@ mod spec { } #[test] -fn debug() {} +fn debug() { + test!( + source_text, + r##"`pragma protect encoding=(enctype="raw") + `pragma protect data_method="x-caesar", data_keyname="rot13", begin + `pragma protect + runtime_license=(library="lic.so",feature="runSecret",entry="chk", match=42) + `pragma protect end + "##, + Ok((_, _)) + ); +} diff --git a/sv-parser-parser/src/utils.rs b/sv-parser-parser/src/utils.rs index e36ea5d..51cf0ea 100644 --- a/sv-parser-parser/src/utils.rs +++ b/sv-parser-parser/src/utils.rs @@ -2,259 +2,6 @@ use crate::*; // ----------------------------------------------------------------------------- -const KEYWORDS: &[&str] = &[ - "accept_on", - "alias", - "always", - "always_comb", - "always_ff", - "always_latch", - "and", - "assert", - "assign", - "assume", - "automatic", - "before", - "begin", - "bind", - "bins", - "binsof", - "bit", - "break", - "buf", - "bufif0", - "bufif1", - "byte", - "case", - "casex", - "casez", - "cell", - "chandle", - "checker", - "class", - "clocking", - "cmos", - "config", - "const", - "constraint", - "context", - "continue", - "cover", - "covergroup", - "coverpoint", - "cross", - "deassign", - "default", - "defparam", - "design", - "disable", - "dist", - "do", - "edge", - "else", - "end", - "endcase", - "endchecker", - "endclass", - "endclocking", - "endconfig", - "endfunction", - "endgenerate", - "endgroup", - "endinterface", - "endmodule", - "endpackage", - "endprimitive", - "endprogram", - "endproperty", - "endspecify", - "endsequence", - "endtable", - "endtask", - "enum", - "event", - "eventually", - "expect", - "export", - "extends", - "extern", - "final", - "first_match", - "for", - "force", - "foreach", - "forever", - "fork", - "forkjoin", - "function", - "generate", - "genvar", - "global", - "highz0", - "highz1", - "if", - "iff", - "ifnone", - "ignore_bins", - "illegal_bins", - "implements", - "implies", - "import", - "incdir", - "include", - "initial", - "inout", - "input", - "inside", - "instance", - "int", - "integer", - "interconnect", - "interface", - "intersect", - "join", - "join_any", - "join_none", - "large", - "let", - "liblist", - "library", - "local", - "localparam", - "logic", - "longint", - "macromodule", - "matches", - "medium", - "modport", - "module", - "nand", - "negedge", - "nettype", - "new", - "nexttime", - "nmos", - "nor", - "noshowcancelled", - "not", - "notif0", - "notif1", - "null", - "or", - "output", - "package", - "packed", - "parameter", - "pmos", - "posedge", - "primitive", - "priority", - "program", - "property", - "protected", - "pull0", - "pull1", - "pulldown", - "pullup", - "pulsestyle_ondetect", - "pulsestyle_onevent", - "pure", - "rand", - "randc", - "randcase", - "randsequence", - "rcmos", - "real", - "realtime", - "ref", - "reg", - "reject_on", - "release", - "repeat", - "restrict", - "return", - "rnmos", - "rpmos", - "rtran", - "rtranif0", - "rtranif1", - "s_always", - "s_eventually", - "s_nexttime", - "s_until", - "s_until_with", - "scalared", - "sequence", - "shortint", - "shortreal", - "showcancelled", - "signed", - "small", - "soft", - "solve", - "specify", - "specparam", - "static", - "string", - "strong", - "strong0", - "strong1", - "struct", - "super", - "supply0", - "supply1", - "sync_accept_on", - "sync_reject_on", - "table", - "tagged", - "task", - "this", - "throughout", - "time", - "timeprecision", - "timeunit", - "tran", - "tranif0", - "tranif1", - "tri", - "tri0", - "tri1", - "triand", - "trior", - "trireg", - "type", - "typedef", - "union", - "unique", - "unique0", - "unsigned", - "until", - "until_with", - "untyped", - "use", - "uwire", - "var", - "vectored", - "virtual", - "void", - "wait", - "wait_order", - "wand", - "weak", - "weak0", - "weak1", - "while", - "wildcard", - "wire", - "with", - "within", - "wor", - "xnor", - "xor", -]; - -// ----------------------------------------------------------------------------- - pub(crate) fn ws<'a, O, F>(f: F) -> impl Fn(Span<'a>) -> IResult, (O, Vec)> where F: Fn(Span<'a>) -> IResult, O>, @@ -514,11 +261,77 @@ pub(crate) fn white_space(s: Span) -> IResult { WhiteSpace::Space(Box::new(into_locate(x))) }), map(comment, |x| WhiteSpace::Comment(Box::new(x))), + map(compiler_directive, |x| { + WhiteSpace::CompilerDirective(Box::new(x)) + }), ))(s) } // ----------------------------------------------------------------------------- +#[derive(Clone, Copy)] +pub(crate) enum VersionSpecifier { + Ieee1364_1995, + Ieee1364_2001, + Ieee1364_2001Noconfig, + Ieee1364_2005, + Ieee1800_2005, + Ieee1800_2009, + Ieee1800_2012, + Ieee1800_2017, +} + +thread_local!( + static CURRENT_VERSION: core::cell::RefCell> = { + core::cell::RefCell::new(Vec::new()) + } +); + +pub(crate) fn begin_keywords(version: &str) { + CURRENT_VERSION.with(|current_version| match version { + "1364-1995" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1364_1995), + "1364-2001" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1364_2001), + "1364-2001-noconfig" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1364_2001Noconfig), + "1364-2005" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1364_2005), + "1800-2005" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1800_2005), + "1800-2009" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1800_2009), + "1800-2012" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1800_2012), + "1800-2017" => current_version + .borrow_mut() + .push(VersionSpecifier::Ieee1800_2017), + _ => (), + }); +} + +pub(crate) fn end_keywords() { + CURRENT_VERSION.with(|current_version| { + current_version.borrow_mut().pop(); + }); +} + +pub(crate) fn current_version() -> Option { + CURRENT_VERSION.with(|current_version| match current_version.borrow().last() { + Some(x) => Some(*x), + None => None, + }) +} + +// ----------------------------------------------------------------------------- + pub(crate) fn concat<'a>(a: Span<'a>, b: Span<'a>) -> Option> { let c = str_concat::concat(a.fragment, b.fragment); if let Ok(c) = c { @@ -534,7 +347,18 @@ pub(crate) fn concat<'a>(a: Span<'a>, b: Span<'a>) -> Option> { } pub(crate) fn is_keyword(s: &Span) -> bool { - for k in KEYWORDS { + let keywords = match current_version() { + Some(VersionSpecifier::Ieee1364_1995) => KEYWORDS_1364_1995, + Some(VersionSpecifier::Ieee1364_2001) => KEYWORDS_1364_2001, + Some(VersionSpecifier::Ieee1364_2001Noconfig) => KEYWORDS_1364_2001_NOCONFIG, + Some(VersionSpecifier::Ieee1364_2005) => KEYWORDS_1364_2005, + Some(VersionSpecifier::Ieee1800_2005) => KEYWORDS_1800_2005, + Some(VersionSpecifier::Ieee1800_2009) => KEYWORDS_1800_2009, + Some(VersionSpecifier::Ieee1800_2012) => KEYWORDS_1800_2012, + Some(VersionSpecifier::Ieee1800_2017) => KEYWORDS_1800_2017, + None => KEYWORDS_1800_2017, + }; + for k in keywords { if &s.fragment == k { return true; } diff --git a/sv-parser-syntaxtree/src/general/compiler_directives.rs b/sv-parser-syntaxtree/src/general/compiler_directives.rs new file mode 100644 index 0000000..729382a --- /dev/null +++ b/sv-parser-syntaxtree/src/general/compiler_directives.rs @@ -0,0 +1,176 @@ +use crate::*; + +// ----------------------------------------------------------------------------- + +#[derive(Clone, Debug, Node)] +pub enum CompilerDirective { + ResetallCompilerDirective(Box), + TextMacroDefinition(Box), + UndefineCompilerDirective(Box), + UndefineallCompilerDirective(Box), + TimescaleCompilerDirective(Box), + DefaultNettypeCompilerDirective(Box), + UnconnectedDriveCompilerDirective(Box), + NounconnectedDriveCompilerDirective(Box), + CelldefineDriveCompilerDirective(Box), + EndcelldefineDriveCompilerDirective(Box), + Pragma(Box), + LineCompilerDirective(Box), + KeywordsDirective(Box), + EndkeywordsDirective(Box), +} + +#[derive(Clone, Debug, Node)] +pub struct ResetallCompilerDirective { + pub nodes: (Symbol, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct TextMacroDefinition { + pub nodes: (Symbol, Keyword, TextMacroName, Option), +} + +#[derive(Clone, Debug, Node)] +pub struct TextMacroName { + pub nodes: (TextMacroIdentifier, Option>), +} + +#[derive(Clone, Debug, Node)] +pub struct ListOfFormalArguments { + pub nodes: (List,), +} + +#[derive(Clone, Debug, Node)] +pub struct FormalArgument { + pub nodes: (SimpleIdentifier, Option<(Symbol, DefaultText)>), +} + +#[derive(Clone, Debug, Node)] +pub struct TextMacroIdentifier { + pub nodes: (Identifier,), +} + +#[derive(Clone, Debug, Node)] +pub struct MacroText { + pub nodes: (Locate,), +} + +#[derive(Clone, Debug, Node)] +pub struct DefaultText { + pub nodes: (Locate,), +} + +#[derive(Clone, Debug, Node)] +pub struct UndefineCompilerDirective { + pub nodes: (Symbol, Keyword, TextMacroIdentifier), +} + +#[derive(Clone, Debug, Node)] +pub struct UndefineallCompilerDirective { + pub nodes: (Symbol, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct TimescaleCompilerDirective { + pub nodes: (Symbol, Keyword, TimeLiteral, Symbol, TimeLiteral), +} + +#[derive(Clone, Debug, Node)] +pub struct DefaultNettypeCompilerDirective { + pub nodes: (Symbol, Keyword, DefaultNettypeValue), +} + +#[derive(Clone, Debug, Node)] +pub struct DefaultNettypeValue { + pub nodes: (Keyword,), +} + +#[derive(Clone, Debug, Node)] +pub struct UnconnectedDriveCompilerDirective { + pub nodes: (Symbol, Keyword, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct NounconnectedDriveCompilerDirective { + pub nodes: (Symbol, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct CelldefineDriveCompilerDirective { + pub nodes: (Symbol, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct EndcelldefineDriveCompilerDirective { + pub nodes: (Symbol, Keyword), +} + +#[derive(Clone, Debug, Node)] +pub struct Pragma { + pub nodes: ( + Symbol, + Keyword, + PragmaName, + Option>, + ), +} + +#[derive(Clone, Debug, Node)] +pub struct PragmaName { + pub nodes: (SimpleIdentifier,), +} + +#[derive(Clone, Debug, Node)] +pub enum PragmaExpression { + PragmaKeyword(Box), + Assignment(Box), + PragmaValue(Box), +} + +#[derive(Clone, Debug, Node)] +pub struct PragmaExpressionAssignment { + pub nodes: (PragmaKeyword, Symbol, PragmaValue), +} + +#[derive(Clone, Debug, Node)] +pub enum PragmaValue { + Paren(Box), + Number(Box), + StringLiteral(Box), + Identifier(Box), +} + +#[derive(Clone, Debug, Node)] +pub struct PragmaValueParen { + pub nodes: (Paren>,), +} + +#[derive(Clone, Debug, Node)] +pub struct PragmaKeyword { + pub nodes: (SimpleIdentifier,), +} + +#[derive(Clone, Debug, Node)] +pub struct LineCompilerDirective { + pub nodes: (Symbol, Keyword, Number, StringLiteral, Level), +} + +#[derive(Clone, Debug, Node)] +pub struct Level { + pub nodes: (Symbol,), +} + +#[derive(Clone, Debug, Node)] +pub struct KeywordsDirective { + pub nodes: (Symbol, Keyword, Symbol, VersionSpecifier, Symbol), +} + +#[derive(Clone, Debug, Node)] +pub struct VersionSpecifier { + pub nodes: (Keyword,), +} + +#[derive(Clone, Debug, Node)] +pub struct EndkeywordsDirective { + pub nodes: (Symbol, Keyword), +} diff --git a/sv-parser-syntaxtree/src/general/mod.rs b/sv-parser-syntaxtree/src/general/mod.rs index 7cad8f7..caf77be 100644 --- a/sv-parser-syntaxtree/src/general/mod.rs +++ b/sv-parser-syntaxtree/src/general/mod.rs @@ -1,6 +1,8 @@ pub mod attributes; pub mod comments; +pub mod compiler_directives; pub mod identifiers; pub use attributes::*; pub use comments::*; +pub use compiler_directives::*; pub use identifiers::*; diff --git a/sv-parser-syntaxtree/src/source_text/library_source_text.rs b/sv-parser-syntaxtree/src/source_text/library_source_text.rs index 8af878b..3ffead0 100644 --- a/sv-parser-syntaxtree/src/source_text/library_source_text.rs +++ b/sv-parser-syntaxtree/src/source_text/library_source_text.rs @@ -4,7 +4,7 @@ use crate::*; #[derive(Clone, Debug, Node)] pub struct LibraryText { - pub nodes: (Vec,), + pub nodes: (Vec, Vec), } #[derive(Clone, Debug, Node)] diff --git a/sv-parser-syntaxtree/src/source_text/system_verilog_source_text.rs b/sv-parser-syntaxtree/src/source_text/system_verilog_source_text.rs index 8e1e6c7..35c5368 100644 --- a/sv-parser-syntaxtree/src/source_text/system_verilog_source_text.rs +++ b/sv-parser-syntaxtree/src/source_text/system_verilog_source_text.rs @@ -4,7 +4,11 @@ use crate::*; #[derive(Clone, Debug, Node)] pub struct SourceText { - pub nodes: (Option, Vec), + pub nodes: ( + Vec, + Option, + Vec, + ), } #[derive(Clone, Debug, Node)] diff --git a/sv-parser-syntaxtree/src/special_node.rs b/sv-parser-syntaxtree/src/special_node.rs index 8d7fbd6..1854324 100644 --- a/sv-parser-syntaxtree/src/special_node.rs +++ b/sv-parser-syntaxtree/src/special_node.rs @@ -16,6 +16,7 @@ pub struct Keyword { pub enum WhiteSpace { Space(Box), Comment(Box), + CompilerDirective(Box), } #[derive(Clone, Debug)]