Add compiler_directives

This commit is contained in:
dalance 2019-08-16 15:07:47 +09:00
parent c33aea4725
commit 7b6efd9dad
14 changed files with 2396 additions and 396 deletions

View File

@ -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

View File

@ -0,0 +1,437 @@
use crate::*;
// -----------------------------------------------------------------------------
#[tracable_parser]
#[packrat_parser]
pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
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<Span, ResetallCompilerDirective> {
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<Span, TextMacroDefinition> {
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<Span, TextMacroName> {
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<Span, ListOfFormalArguments> {
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<Span, FormalArgument> {
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<Span, TextMacroIdentifier> {
let (s, a) = identifier(s)?;
Ok((s, TextMacroIdentifier { nodes: (a,) }))
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn macro_text(s: Span) -> IResult<Span, MacroText> {
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<Span, DefaultText> {
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<Span, UndefineCompilerDirective> {
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<Span, UndefineallCompilerDirective> {
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<Span, TimescaleCompilerDirective> {
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<Span, DefaultNettypeCompilerDirective> {
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<Span, DefaultNettypeValue> {
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<Span, UnconnectedDriveCompilerDirective> {
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<Span, NounconnectedDriveCompilerDirective> {
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<Span, CelldefineDriveCompilerDirective> {
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<Span, EndcelldefineDriveCompilerDirective> {
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<Span, Pragma> {
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<Span, PragmaName> {
let (s, a) = simple_identifier(s)?;
Ok((s, PragmaName { nodes: (a,) }))
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn pragma_expression(s: Span) -> IResult<Span, PragmaExpression> {
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<Span, PragmaExpression> {
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<Span, PragmaValue> {
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<Span, PragmaValue> {
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<Span, PragmaKeyword> {
let (s, a) = simple_identifier_pragma(s)?;
Ok((s, PragmaKeyword { nodes: (a,) }))
}
#[tracable_parser]
#[packrat_parser]
pub(crate) fn identifier_pragma(s: Span) -> IResult<Span, Identifier> {
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<Span, SimpleIdentifier> {
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<Span, Locate> {
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<Span, LineCompilerDirective> {
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<Span, Level> {
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<Span, KeywordsDirective> {
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<Span, VersionSpecifier> {
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<Span, EndkeywordsDirective> {
let (s, a) = symbol("`")(s)?;
let (s, b) = keyword("end_keywords")(s)?;
end_keywords();
Ok((s, EndkeywordsDirective { nodes: (a, b) }))
}

View File

@ -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::*;

File diff suppressed because it is too large Load Diff

View File

@ -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<RecursiveInfo> 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<SourceText, ()> {

View File

@ -5,8 +5,9 @@ use crate::*;
#[tracable_parser]
#[packrat_parser]
pub(crate) fn library_text(s: Span) -> IResult<Span, LibraryText> {
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]

View File

@ -5,9 +5,10 @@ use crate::*;
#[tracable_parser]
#[packrat_parser]
pub(crate) fn source_text(s: Span) -> IResult<Span, SourceText> {
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]

View File

@ -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,39 +15574,39 @@ 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
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;
@ -15520,11 +15619,11 @@ mod spec {
// ortva
// #5 o = n;
// raq
// `pragma protect end_protected
// `pragma reset protect
// endmodule // secret"##,
// Ok((_, _))
//);
`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((_, _))
);
}

View File

@ -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<Span<'a>, (O, Vec<WhiteSpace>)>
where
F: Fn(Span<'a>) -> IResult<Span<'a>, O>,
@ -514,11 +261,77 @@ pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> {
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<Vec<VersionSpecifier>> = {
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<VersionSpecifier> {
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<Span<'a>> {
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<Span<'a>> {
}
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;
}

View File

@ -0,0 +1,176 @@
use crate::*;
// -----------------------------------------------------------------------------
#[derive(Clone, Debug, Node)]
pub enum CompilerDirective {
ResetallCompilerDirective(Box<ResetallCompilerDirective>),
TextMacroDefinition(Box<TextMacroDefinition>),
UndefineCompilerDirective(Box<UndefineCompilerDirective>),
UndefineallCompilerDirective(Box<UndefineallCompilerDirective>),
TimescaleCompilerDirective(Box<TimescaleCompilerDirective>),
DefaultNettypeCompilerDirective(Box<DefaultNettypeCompilerDirective>),
UnconnectedDriveCompilerDirective(Box<UnconnectedDriveCompilerDirective>),
NounconnectedDriveCompilerDirective(Box<NounconnectedDriveCompilerDirective>),
CelldefineDriveCompilerDirective(Box<CelldefineDriveCompilerDirective>),
EndcelldefineDriveCompilerDirective(Box<EndcelldefineDriveCompilerDirective>),
Pragma(Box<Pragma>),
LineCompilerDirective(Box<LineCompilerDirective>),
KeywordsDirective(Box<KeywordsDirective>),
EndkeywordsDirective(Box<EndkeywordsDirective>),
}
#[derive(Clone, Debug, Node)]
pub struct ResetallCompilerDirective {
pub nodes: (Symbol, Keyword),
}
#[derive(Clone, Debug, Node)]
pub struct TextMacroDefinition {
pub nodes: (Symbol, Keyword, TextMacroName, Option<MacroText>),
}
#[derive(Clone, Debug, Node)]
pub struct TextMacroName {
pub nodes: (TextMacroIdentifier, Option<Paren<ListOfFormalArguments>>),
}
#[derive(Clone, Debug, Node)]
pub struct ListOfFormalArguments {
pub nodes: (List<Symbol, FormalArgument>,),
}
#[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<List<Symbol, PragmaExpression>>,
),
}
#[derive(Clone, Debug, Node)]
pub struct PragmaName {
pub nodes: (SimpleIdentifier,),
}
#[derive(Clone, Debug, Node)]
pub enum PragmaExpression {
PragmaKeyword(Box<PragmaKeyword>),
Assignment(Box<PragmaExpressionAssignment>),
PragmaValue(Box<PragmaValue>),
}
#[derive(Clone, Debug, Node)]
pub struct PragmaExpressionAssignment {
pub nodes: (PragmaKeyword, Symbol, PragmaValue),
}
#[derive(Clone, Debug, Node)]
pub enum PragmaValue {
Paren(Box<PragmaValueParen>),
Number(Box<Number>),
StringLiteral(Box<StringLiteral>),
Identifier(Box<Identifier>),
}
#[derive(Clone, Debug, Node)]
pub struct PragmaValueParen {
pub nodes: (Paren<List<Symbol, PragmaExpression>>,),
}
#[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),
}

View File

@ -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::*;

View File

@ -4,7 +4,7 @@ use crate::*;
#[derive(Clone, Debug, Node)]
pub struct LibraryText {
pub nodes: (Vec<LibraryDescription>,),
pub nodes: (Vec<WhiteSpace>, Vec<LibraryDescription>),
}
#[derive(Clone, Debug, Node)]

View File

@ -4,7 +4,11 @@ use crate::*;
#[derive(Clone, Debug, Node)]
pub struct SourceText {
pub nodes: (Option<TimeunitsDeclaration>, Vec<Description>),
pub nodes: (
Vec<WhiteSpace>,
Option<TimeunitsDeclaration>,
Vec<Description>,
),
}
#[derive(Clone, Debug, Node)]

View File

@ -16,6 +16,7 @@ pub struct Keyword {
pub enum WhiteSpace {
Space(Box<Locate>),
Comment(Box<Comment>),
CompilerDirective(Box<CompilerDirective>),
}
#[derive(Clone, Debug)]