Add preprocessor_text
This commit is contained in:
parent
c9456ee993
commit
6cd5d30e66
@ -5,10 +5,14 @@ use crate::*;
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
|
||||
alt((
|
||||
begin_directive();
|
||||
let ret = alt((
|
||||
map(resetall_compiler_directive, |x| {
|
||||
CompilerDirective::ResetallCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(include_compiler_directive, |x| {
|
||||
CompilerDirective::IncludeCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(text_macro_definition, |x| {
|
||||
CompilerDirective::TextMacroDefinition(Box::new(x))
|
||||
}),
|
||||
@ -18,6 +22,9 @@ pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
|
||||
map(undefineall_compiler_directive, |x| {
|
||||
CompilerDirective::UndefineallCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(conditional_compiler_directive, |x| {
|
||||
CompilerDirective::ConditionalCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(timescale_compiler_directive, |x| {
|
||||
CompilerDirective::TimescaleCompilerDirective(Box::new(x))
|
||||
}),
|
||||
@ -40,13 +47,21 @@ pub(crate) fn compiler_directive(s: Span) -> IResult<Span, CompilerDirective> {
|
||||
map(line_compiler_directive, |x| {
|
||||
CompilerDirective::LineCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(position_compiler_directive, |x| {
|
||||
CompilerDirective::PositionCompilerDirective(Box::new(x))
|
||||
}),
|
||||
map(keywords_directive, |x| {
|
||||
CompilerDirective::KeywordsDirective(Box::new(x))
|
||||
}),
|
||||
map(endkeywords_directive, |x| {
|
||||
CompilerDirective::EndkeywordsDirective(Box::new(x))
|
||||
}),
|
||||
))(s)
|
||||
map(text_macro_usage, |x| {
|
||||
CompilerDirective::TextMacroUsage(Box::new(x))
|
||||
}),
|
||||
))(s);
|
||||
end_directive();
|
||||
ret
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
@ -57,6 +72,66 @@ pub(crate) fn resetall_compiler_directive(s: Span) -> IResult<Span, ResetallComp
|
||||
Ok((s, ResetallCompilerDirective { nodes: (a, b) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn include_compiler_directive(s: Span) -> IResult<Span, IncludeCompilerDirective> {
|
||||
alt((
|
||||
include_compiler_directive_double_quote,
|
||||
include_compiler_directive_angle_bracket,
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn include_compiler_directive_double_quote(
|
||||
s: Span,
|
||||
) -> IResult<Span, IncludeCompilerDirective> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = keyword("include")(s)?;
|
||||
let (s, c) = string_literal(s)?;
|
||||
Ok((
|
||||
s,
|
||||
IncludeCompilerDirective::DoubleQuote(Box::new(IncludeCompilerDirectiveDoubleQuote {
|
||||
nodes: (a, b, c),
|
||||
})),
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn include_compiler_directive_angle_bracket(
|
||||
s: Span,
|
||||
) -> IResult<Span, IncludeCompilerDirective> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = keyword("include")(s)?;
|
||||
let (s, c) = angle_bracket_literal(s)?;
|
||||
Ok((
|
||||
s,
|
||||
IncludeCompilerDirective::AngleBracket(Box::new(IncludeCompilerDirectiveAngleBracket {
|
||||
nodes: (a, b, c),
|
||||
})),
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn angle_bracket_literal(s: Span) -> IResult<Span, AngleBracketLiteral> {
|
||||
let (s, a) = ws(angle_bracket_literal_impl)(s)?;
|
||||
Ok((s, AngleBracketLiteral { nodes: a }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
pub(crate) fn angle_bracket_literal_impl(s: Span) -> IResult<Span, Locate> {
|
||||
let (s, a) = tag("<")(s)?;
|
||||
let (s, b) = is_not(">")(s)?;
|
||||
let (s, c) = tag(">")(s)?;
|
||||
|
||||
let a = concat(a, b).unwrap();
|
||||
let a = concat(a, c).unwrap();
|
||||
|
||||
Ok((s, into_locate(a)))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn text_macro_definition(s: Span) -> IResult<Span, TextMacroDefinition> {
|
||||
@ -136,6 +211,29 @@ pub(crate) fn default_text(s: Span) -> IResult<Span, DefaultText> {
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn text_macro_usage(s: Span) -> IResult<Span, TextMacroUsage> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = text_macro_identifier(s)?;
|
||||
let (s, c) = opt(paren(list_of_actual_arguments))(s)?;
|
||||
Ok((s, TextMacroUsage { nodes: (a, b, c) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn list_of_actual_arguments(s: Span) -> IResult<Span, ListOfActualArguments> {
|
||||
let (s, a) = list(symbol(","), actual_argument)(s)?;
|
||||
Ok((s, ListOfActualArguments { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn actual_argument(s: Span) -> IResult<Span, ActualArgument> {
|
||||
let (s, a) = expression(s)?;
|
||||
Ok((s, ActualArgument { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn undefine_compiler_directive(s: Span) -> IResult<Span, UndefineCompilerDirective> {
|
||||
@ -155,6 +253,143 @@ pub(crate) fn undefineall_compiler_directive(
|
||||
Ok((s, UndefineallCompilerDirective { nodes: (a, b) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn conditional_compiler_directive(
|
||||
s: Span,
|
||||
) -> IResult<Span, ConditionalCompilerDirective> {
|
||||
alt((
|
||||
map(ifdef_directive, |x| {
|
||||
ConditionalCompilerDirective::IfdefDirective(Box::new(x))
|
||||
}),
|
||||
map(ifndef_directive, |x| {
|
||||
ConditionalCompilerDirective::IfndefDirective(Box::new(x))
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn ifdef_directive(s: Span) -> IResult<Span, IfdefDirective> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = keyword("ifdef")(s)?;
|
||||
let (s, c) = text_macro_identifier(s)?;
|
||||
let (s, d) = ifdef_group_of_lines(s)?;
|
||||
let (s, e) = many0(tuple((
|
||||
symbol("`"),
|
||||
keyword("elsif"),
|
||||
text_macro_identifier,
|
||||
elsif_group_of_lines,
|
||||
)))(s)?;
|
||||
let (s, f) = opt(tuple((symbol("`"), keyword("else"), else_group_of_lines)))(s)?;
|
||||
let (s, g) = symbol("`")(s)?;
|
||||
let (s, h) = keyword("endif")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
IfdefDirective {
|
||||
nodes: (a, b, c, d, e, f, g, h),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn ifndef_directive(s: Span) -> IResult<Span, IfndefDirective> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = keyword("ifndef")(s)?;
|
||||
let (s, c) = text_macro_identifier(s)?;
|
||||
let (s, d) = ifndef_group_of_lines(s)?;
|
||||
let (s, e) = many0(tuple((
|
||||
symbol("`"),
|
||||
keyword("elsif"),
|
||||
text_macro_identifier,
|
||||
elsif_group_of_lines,
|
||||
)))(s)?;
|
||||
let (s, f) = opt(tuple((symbol("`"), keyword("else"), else_group_of_lines)))(s)?;
|
||||
let (s, g) = symbol("`")(s)?;
|
||||
let (s, h) = keyword("endif")(s)?;
|
||||
Ok((
|
||||
s,
|
||||
IfndefDirective {
|
||||
nodes: (a, b, c, d, e, f, g, h),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn ifdef_group_of_lines(s: Span) -> IResult<Span, IfdefGroupOfLines> {
|
||||
let (s, a) = many1(preceded(
|
||||
peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))),
|
||||
source_description,
|
||||
))(s)?;
|
||||
Ok((s, IfdefGroupOfLines { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn ifndef_group_of_lines(s: Span) -> IResult<Span, IfndefGroupOfLines> {
|
||||
let (s, a) = many1(preceded(
|
||||
peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))),
|
||||
source_description,
|
||||
))(s)?;
|
||||
Ok((s, IfndefGroupOfLines { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn elsif_group_of_lines(s: Span) -> IResult<Span, ElsifGroupOfLines> {
|
||||
let (s, a) = many1(preceded(
|
||||
peek(not(alt((tag("`elsif"), tag("`else"), tag("`endif"))))),
|
||||
source_description,
|
||||
))(s)?;
|
||||
Ok((s, ElsifGroupOfLines { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn else_group_of_lines(s: Span) -> IResult<Span, ElseGroupOfLines> {
|
||||
let (s, a) = many1(preceded(peek(not(tag("`endif"))), source_description))(s)?;
|
||||
Ok((s, ElseGroupOfLines { nodes: (a,) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn source_description(s: Span) -> IResult<Span, SourceDescription> {
|
||||
alt((
|
||||
map(comment, |x| SourceDescription::Comment(Box::new(x))),
|
||||
source_description_not_directive,
|
||||
map(compiler_directive, |x| {
|
||||
SourceDescription::CompilerDirective(Box::new(x))
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn source_description_not_directive(s: Span) -> IResult<Span, SourceDescription> {
|
||||
let (s, a) = many1(alt((
|
||||
is_not("`/"),
|
||||
terminated(tag("/"), peek(not(alt((tag("/"), tag("*")))))),
|
||||
)))(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,
|
||||
SourceDescription::NotDirective(Box::new(SourceDescriptionNotDirective {
|
||||
nodes: (into_locate(a),),
|
||||
})),
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn timescale_compiler_directive(s: Span) -> IResult<Span, TimescaleCompilerDirective> {
|
||||
@ -364,6 +599,14 @@ pub(crate) fn line_compiler_directive(s: Span) -> IResult<Span, LineCompilerDire
|
||||
))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn position_compiler_directive(s: Span) -> IResult<Span, PositionCompilerDirective> {
|
||||
let (s, a) = symbol("`")(s)?;
|
||||
let (s, b) = alt((keyword("__FILE__"), keyword("__LINE__")))(s)?;
|
||||
Ok((s, PositionCompilerDirective { nodes: (a, b) }))
|
||||
}
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn level(s: Span) -> IResult<Span, Level> {
|
||||
|
@ -11,6 +11,7 @@ pub mod declarations;
|
||||
pub mod expressions;
|
||||
pub mod general;
|
||||
pub mod instantiations;
|
||||
pub mod preprocessor;
|
||||
pub mod primitive_instances;
|
||||
pub mod source_text;
|
||||
pub mod specify_section;
|
||||
@ -20,6 +21,7 @@ pub(crate) use declarations::*;
|
||||
pub(crate) use expressions::*;
|
||||
pub(crate) use general::*;
|
||||
pub(crate) use instantiations::*;
|
||||
pub(crate) use preprocessor::*;
|
||||
pub(crate) use primitive_instances::*;
|
||||
pub(crate) use source_text::*;
|
||||
pub(crate) use specify_section::*;
|
||||
@ -74,15 +76,15 @@ impl HasTracableInfo for SpanInfo {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasExtraState<()> for SpanInfo {
|
||||
fn get_extra_state(&self) -> () {
|
||||
()
|
||||
impl HasExtraState<bool> for SpanInfo {
|
||||
fn get_extra_state(&self) -> bool {
|
||||
in_directive()
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
nom_packrat::storage!(AnyNode, 1024);
|
||||
nom_packrat::storage!(AnyNode, bool, 1024);
|
||||
|
||||
pub fn sv_parser(s: Span) -> IResult<Span, SourceText> {
|
||||
source_text(s)
|
||||
@ -91,3 +93,7 @@ pub fn sv_parser(s: Span) -> IResult<Span, SourceText> {
|
||||
pub fn lib_parser(s: Span) -> IResult<Span, LibraryText> {
|
||||
library_text(s)
|
||||
}
|
||||
|
||||
pub fn pp_parser(s: Span) -> IResult<Span, PreprocessorText> {
|
||||
preprocessor_text(s)
|
||||
}
|
||||
|
2
sv-parser-parser/src/preprocessor/mod.rs
Normal file
2
sv-parser-parser/src/preprocessor/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod preprocessor;
|
||||
pub(crate) use preprocessor::*;
|
10
sv-parser-parser/src/preprocessor/preprocessor.rs
Normal file
10
sv-parser-parser/src/preprocessor/preprocessor.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use crate::*;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn preprocessor_text(s: Span) -> IResult<Span, PreprocessorText> {
|
||||
let (s, a) = many0(source_description)(s)?;
|
||||
Ok((s, PreprocessorText { nodes: (a,) }))
|
||||
}
|
@ -11797,6 +11797,76 @@ mod spec {
|
||||
r##"`define home(filename) `"/home/mydir/filename`""##,
|
||||
Ok((_, _))
|
||||
);
|
||||
test!(
|
||||
source_text,
|
||||
r##"module and_op (a, b, c);
|
||||
output a;
|
||||
input b, c;
|
||||
|
||||
`ifdef behavioral
|
||||
wire a = b & c;
|
||||
`else
|
||||
and a1 (a,b,c);
|
||||
`endif
|
||||
endmodule"##,
|
||||
Ok((_, _))
|
||||
);
|
||||
test!(
|
||||
source_text,
|
||||
r##"module test(out);
|
||||
output out;
|
||||
`define wow
|
||||
`define nest_one
|
||||
`define second_nest
|
||||
`define nest_two
|
||||
`ifdef wow
|
||||
initial $display("wow is defined");
|
||||
`ifdef nest_one
|
||||
initial $display("nest_one is defined");
|
||||
`ifdef nest_two
|
||||
initial $display("nest_two is defined");
|
||||
`else
|
||||
initial $display("nest_two is not defined");
|
||||
`endif
|
||||
`else
|
||||
initial $display("nest_one is not defined");
|
||||
`endif
|
||||
`else
|
||||
initial $display("wow is not defined");
|
||||
`ifdef second_nest
|
||||
initial $display("second_nest is defined");
|
||||
`else
|
||||
initial $display("second_nest is not defined");
|
||||
`endif
|
||||
`endif
|
||||
endmodule"##,
|
||||
Ok((_, _))
|
||||
);
|
||||
test!(
|
||||
source_text,
|
||||
r##"module test;
|
||||
`ifdef first_block
|
||||
`ifndef second_nest
|
||||
initial $display("first_block is defined");
|
||||
`else
|
||||
initial $display("first_block and second_nest defined");
|
||||
`endif
|
||||
`elsif second_block
|
||||
initial $display("second_block defined, first_block is not");
|
||||
`else
|
||||
`ifndef last_result
|
||||
initial $display("first_block, second_block,",
|
||||
" last_result not defined.");
|
||||
`elsif real_last
|
||||
initial $display("first_block, second_block not defined,",
|
||||
" last_result and real_last defined.");
|
||||
`else
|
||||
initial $display("Only last_result defined!");
|
||||
`endif
|
||||
`endif
|
||||
endmodule"##,
|
||||
Ok((_, _))
|
||||
);
|
||||
test!(source_text, r##"`timescale 1 ns / 1 ps"##, Ok((_, _)));
|
||||
test!(source_text, r##"`timescale 10 us / 100 ns"##, Ok((_, _)));
|
||||
test!(
|
||||
@ -15704,5 +15774,10 @@ mod spec {
|
||||
|
||||
#[test]
|
||||
fn debug() {
|
||||
test!(
|
||||
source_text,
|
||||
r##"module secret (a, b); `pragma protect encoding=(enctype="raw") `pragma protect data_method="x-caesar", data_keyname="rot13", begin endmodule"##,
|
||||
Ok((_, _))
|
||||
);
|
||||
nom_tracable::cumulative_histogram();
|
||||
}
|
||||
|
@ -256,6 +256,16 @@ where
|
||||
#[tracable_parser]
|
||||
#[packrat_parser]
|
||||
pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> {
|
||||
if in_directive() {
|
||||
alt((
|
||||
map(multispace1, |x: Span| {
|
||||
WhiteSpace::Space(Box::new(into_locate(x)))
|
||||
}),
|
||||
map(preceded(peek(char('/')), comment), |x| {
|
||||
WhiteSpace::Comment(Box::new(x))
|
||||
}),
|
||||
))(s)
|
||||
} else {
|
||||
alt((
|
||||
map(multispace1, |x: Span| {
|
||||
WhiteSpace::Space(Box::new(into_locate(x)))
|
||||
@ -267,6 +277,28 @@ pub(crate) fn white_space(s: Span) -> IResult<Span, WhiteSpace> {
|
||||
WhiteSpace::CompilerDirective(Box::new(x))
|
||||
}),
|
||||
))(s)
|
||||
}
|
||||
}
|
||||
|
||||
thread_local!(
|
||||
static IN_DIRECTIVE: core::cell::RefCell<Vec<()>> = {
|
||||
core::cell::RefCell::new(Vec::new())
|
||||
}
|
||||
);
|
||||
|
||||
pub(crate) fn in_directive() -> bool {
|
||||
IN_DIRECTIVE.with(|x| match x.borrow().last() {
|
||||
Some(_) => true,
|
||||
None => false,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn begin_directive() {
|
||||
IN_DIRECTIVE.with(|x| x.borrow_mut().push(()));
|
||||
}
|
||||
|
||||
pub(crate) fn end_directive() {
|
||||
IN_DIRECTIVE.with(|x| x.borrow_mut().pop());
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -1,96 +1,3 @@
|
||||
use nom::branch::*;
|
||||
use nom::bytes::complete::*;
|
||||
use nom::character::complete::*;
|
||||
use nom::combinator::*;
|
||||
use nom::multi::*;
|
||||
use nom::sequence::*;
|
||||
use nom::IResult;
|
||||
use str_concat::concat;
|
||||
|
||||
pub fn preprocessor_text(s: &str) -> IResult<&str, &str> {
|
||||
alt((multispace1, comment, string_literal, other))(s)
|
||||
}
|
||||
|
||||
fn comment(s: &str) -> IResult<&str, &str> {
|
||||
alt((one_line_comment, block_comment))(s)
|
||||
}
|
||||
|
||||
fn one_line_comment(s: &str) -> IResult<&str, &str> {
|
||||
let (s, a) = tag("//")(s)?;
|
||||
let (s, b) = is_not("\n")(s)?;
|
||||
let a = concat(a, b).unwrap();
|
||||
Ok((s, a))
|
||||
}
|
||||
|
||||
fn block_comment(s: &str) -> IResult<&str, &str> {
|
||||
let (s, a) = tag("/*")(s)?;
|
||||
let (s, b) = is_not("*/")(s)?;
|
||||
let (s, c) = tag("*/")(s)?;
|
||||
let a = concat(a, b).unwrap();
|
||||
let a = concat(a, c).unwrap();
|
||||
Ok((s, a))
|
||||
}
|
||||
|
||||
fn string_literal(s: &str) -> IResult<&str, &str> {
|
||||
let (s, a) = tag("\"")(s)?;
|
||||
let (s, b) = many0(alt((
|
||||
is_not("\\\""),
|
||||
map(pair(tag("\\"), take(1usize)), |(x, y)| {
|
||||
concat(x, y).unwrap()
|
||||
}),
|
||||
)))(s)?;
|
||||
let (s, c) = tag("\"")(s)?;
|
||||
|
||||
let mut ret = None;
|
||||
for x in b {
|
||||
ret = if let Some(ret) = ret {
|
||||
Some(concat(ret, x).unwrap())
|
||||
} else {
|
||||
Some(x)
|
||||
};
|
||||
}
|
||||
|
||||
let a = if let Some(b) = ret {
|
||||
let a = concat(a, b).unwrap();
|
||||
let a = concat(a, c).unwrap();
|
||||
a
|
||||
} else {
|
||||
let a = concat(a, c).unwrap();
|
||||
a
|
||||
};
|
||||
|
||||
Ok((s, a))
|
||||
}
|
||||
|
||||
fn other(s: &str) -> IResult<&str, &str> {
|
||||
let (s, a) = many1(alt((
|
||||
is_not("\"`/"),
|
||||
terminated(tag("/"), peek(not(alt((tag("/"), tag("*")))))),
|
||||
)))(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, a))
|
||||
}
|
||||
|
||||
fn ws<'a, F>(f: F) -> impl Fn(&'a str) -> IResult<&'a str, &'a str>
|
||||
where
|
||||
F: Fn(&'a str) -> IResult<&'a str, &'a str>,
|
||||
{
|
||||
move |s: &'a str| {
|
||||
let (s, x) = f(s)?;
|
||||
let (s, y) = multispace0(s)?;
|
||||
Ok((s, concat(x, y).unwrap()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
|
@ -5,9 +5,12 @@ use crate::*;
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub enum CompilerDirective {
|
||||
ResetallCompilerDirective(Box<ResetallCompilerDirective>),
|
||||
IncludeCompilerDirective(Box<IncludeCompilerDirective>),
|
||||
TextMacroDefinition(Box<TextMacroDefinition>),
|
||||
TextMacroUsage(Box<TextMacroUsage>),
|
||||
UndefineCompilerDirective(Box<UndefineCompilerDirective>),
|
||||
UndefineallCompilerDirective(Box<UndefineallCompilerDirective>),
|
||||
ConditionalCompilerDirective(Box<ConditionalCompilerDirective>),
|
||||
TimescaleCompilerDirective(Box<TimescaleCompilerDirective>),
|
||||
DefaultNettypeCompilerDirective(Box<DefaultNettypeCompilerDirective>),
|
||||
UnconnectedDriveCompilerDirective(Box<UnconnectedDriveCompilerDirective>),
|
||||
@ -16,6 +19,7 @@ pub enum CompilerDirective {
|
||||
EndcelldefineDriveCompilerDirective(Box<EndcelldefineDriveCompilerDirective>),
|
||||
Pragma(Box<Pragma>),
|
||||
LineCompilerDirective(Box<LineCompilerDirective>),
|
||||
PositionCompilerDirective(Box<PositionCompilerDirective>),
|
||||
KeywordsDirective(Box<KeywordsDirective>),
|
||||
EndkeywordsDirective(Box<EndkeywordsDirective>),
|
||||
}
|
||||
@ -25,6 +29,27 @@ pub struct ResetallCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub enum IncludeCompilerDirective {
|
||||
DoubleQuote(Box<IncludeCompilerDirectiveDoubleQuote>),
|
||||
AngleBracket(Box<IncludeCompilerDirectiveAngleBracket>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IncludeCompilerDirectiveDoubleQuote {
|
||||
pub nodes: (Symbol, Keyword, StringLiteral),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IncludeCompilerDirectiveAngleBracket {
|
||||
pub nodes: (Symbol, Keyword, AngleBracketLiteral),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct AngleBracketLiteral {
|
||||
pub nodes: (Locate, Vec<WhiteSpace>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct TextMacroDefinition {
|
||||
pub nodes: (Symbol, Keyword, TextMacroName, Option<MacroText>),
|
||||
@ -60,6 +85,25 @@ pub struct DefaultText {
|
||||
pub nodes: (Locate,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct TextMacroUsage {
|
||||
pub nodes: (
|
||||
Symbol,
|
||||
TextMacroIdentifier,
|
||||
Option<Paren<ListOfActualArguments>>,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct ListOfActualArguments {
|
||||
pub nodes: (List<Symbol, ActualArgument>,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct ActualArgument {
|
||||
pub nodes: (Expression,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct UndefineCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword, TextMacroIdentifier),
|
||||
@ -70,6 +114,72 @@ pub struct UndefineallCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub enum ConditionalCompilerDirective {
|
||||
IfdefDirective(Box<IfdefDirective>),
|
||||
IfndefDirective(Box<IfndefDirective>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IfdefDirective {
|
||||
pub nodes: (
|
||||
Symbol,
|
||||
Keyword,
|
||||
TextMacroIdentifier,
|
||||
IfdefGroupOfLines,
|
||||
Vec<(Symbol, Keyword, TextMacroIdentifier, ElsifGroupOfLines)>,
|
||||
Option<(Symbol, Keyword, ElseGroupOfLines)>,
|
||||
Symbol,
|
||||
Keyword,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IfndefDirective {
|
||||
pub nodes: (
|
||||
Symbol,
|
||||
Keyword,
|
||||
TextMacroIdentifier,
|
||||
IfndefGroupOfLines,
|
||||
Vec<(Symbol, Keyword, TextMacroIdentifier, ElsifGroupOfLines)>,
|
||||
Option<(Symbol, Keyword, ElseGroupOfLines)>,
|
||||
Symbol,
|
||||
Keyword,
|
||||
),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IfdefGroupOfLines {
|
||||
pub nodes: (Vec<SourceDescription>,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct IfndefGroupOfLines {
|
||||
pub nodes: (Vec<SourceDescription>,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct ElsifGroupOfLines {
|
||||
pub nodes: (Vec<SourceDescription>,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct ElseGroupOfLines {
|
||||
pub nodes: (Vec<SourceDescription>,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub enum SourceDescription {
|
||||
Comment(Box<Comment>),
|
||||
NotDirective(Box<SourceDescriptionNotDirective>),
|
||||
CompilerDirective(Box<CompilerDirective>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct SourceDescriptionNotDirective {
|
||||
pub nodes: (Locate,),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct TimescaleCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword, TimeLiteral, Symbol, TimeLiteral),
|
||||
@ -155,6 +265,11 @@ pub struct LineCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword, Number, StringLiteral, Level),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct PositionCompilerDirective {
|
||||
pub nodes: (Symbol, Keyword),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct Level {
|
||||
pub nodes: (Symbol,),
|
||||
|
@ -6,6 +6,7 @@ pub mod declarations;
|
||||
pub mod expressions;
|
||||
pub mod general;
|
||||
pub mod instantiations;
|
||||
pub mod preprocessor;
|
||||
pub mod primitive_instances;
|
||||
pub mod source_text;
|
||||
pub mod special_node;
|
||||
@ -17,6 +18,7 @@ pub use declarations::*;
|
||||
pub use expressions::*;
|
||||
pub use general::*;
|
||||
pub use instantiations::*;
|
||||
pub use preprocessor::*;
|
||||
pub use primitive_instances::*;
|
||||
pub use source_text::*;
|
||||
pub use special_node::*;
|
||||
|
2
sv-parser-syntaxtree/src/preprocessor/mod.rs
Normal file
2
sv-parser-syntaxtree/src/preprocessor/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod preprocessor;
|
||||
pub use preprocessor::*;
|
9
sv-parser-syntaxtree/src/preprocessor/preprocessor.rs
Normal file
9
sv-parser-syntaxtree/src/preprocessor/preprocessor.rs
Normal file
@ -0,0 +1,9 @@
|
||||
use crate::*;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#[derive(Clone, Debug, Node)]
|
||||
pub struct PreprocessorText {
|
||||
pub nodes: (Vec<SourceDescription>,),
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user