Fix define with string literal

This commit is contained in:
dalance 2019-11-05 12:22:29 +09:00
parent 9c18f589ea
commit ca7279225d
7 changed files with 102 additions and 6 deletions

View File

@ -2,6 +2,8 @@
## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.3.3...Unreleased) - ReleaseDate
* [Fixed] define with string literal
## [v0.3.3](https://github.com/dalance/sv-parser/compare/v0.3.2...v0.3.3) - 2019-11-01
* [Fixed] define arument

View File

@ -478,6 +478,9 @@ pub(crate) fn else_group_of_lines(s: Span) -> IResult<Span, ElseGroupOfLines> {
pub(crate) fn source_description(s: Span) -> IResult<Span, SourceDescription> {
alt((
map(comment, |x| SourceDescription::Comment(Box::new(x))),
map(string_literal, |x| {
SourceDescription::StringLiteral(Box::new(x))
}),
source_description_not_directive,
map(compiler_directive, |x| {
SourceDescription::CompilerDirective(Box::new(x))
@ -489,7 +492,7 @@ pub(crate) fn source_description(s: Span) -> IResult<Span, SourceDescription> {
#[packrat_parser]
pub(crate) fn source_description_not_directive(s: Span) -> IResult<Span, SourceDescription> {
let (s, a) = many1(alt((
is_not("`/"),
is_not("`/\""),
terminated(tag("/"), peek(not(alt((tag("/"), tag("*")))))),
)))(s)?;

View File

@ -8,7 +8,9 @@ use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};
use sv_parser_error::{Error, ErrorKind};
use sv_parser_parser::{pp_parser, Span, SpanInfo};
use sv_parser_syntaxtree::{IncludeCompilerDirective, Locate, NodeEvent, RefNode, TextMacroUsage};
use sv_parser_syntaxtree::{
IncludeCompilerDirective, Locate, NodeEvent, RefNode, SourceDescription, TextMacroUsage,
};
#[derive(Debug)]
pub struct PreprocessedText {
@ -158,6 +160,13 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), path.as_ref(), range);
}
NodeEvent::Enter(RefNode::SourceDescription(SourceDescription::StringLiteral(x)))
if !skip =>
{
let locate: Locate = (&**x).try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len);
ret.push(locate.str(&s), path.as_ref(), range);
}
NodeEvent::Enter(RefNode::KeywordsDirective(x)) if !skip => {
let locate: Locate = x.try_into().unwrap();
let range = Range::new(locate.offset, locate.offset + locate.len);
@ -340,7 +349,9 @@ fn identifier(node: RefNode, s: &str) -> Option<String> {
}
fn split_text(s: &str) -> Vec<String> {
let mut is_string = false;
let mut is_ident = false;
let mut is_backquote_prev = false;
let mut is_ident_prev;
let mut x = String::from("");
let mut ret = vec![];
@ -348,12 +359,31 @@ fn split_text(s: &str) -> Vec<String> {
is_ident_prev = is_ident;
is_ident = c.is_ascii_alphanumeric() | (c == '_');
if is_ident != is_ident_prev {
if c == '"' && is_backquote_prev {
x.push(c);
ret.push(x);
x = String::from("");
} else if c == '"' && !is_string {
ret.push(x);
x = String::from("");
x.push(c);
is_string = true;
} else if c == '"' && is_string {
x.push(c);
ret.push(x);
x = String::from("");
is_string = false;
} else if !is_string {
if is_ident != is_ident_prev {
ret.push(x);
x = String::from("");
}
x.push(c);
} else {
x.push(c);
}
x.push(c);
is_backquote_prev = c == '`';
}
ret.push(x);
ret
@ -402,7 +432,13 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
if let Some(value) = arg_map.get(&text) {
replaced.push_str(*value);
} else {
replaced.push_str(&text.replace("``", "").replace("\\\n", ""));
replaced.push_str(
&text
.replace("``", "")
.replace("`\\`\"", "\\\"")
.replace("`\"", "\"")
.replace("\\\n", ""),
);
}
}
// separator is required
@ -538,6 +574,43 @@ module a ();
always @(posedge clk) begin if (!(!(a[i].b && c[i]))) begin $display ("xxx(()[]]{}}}", a[i].b, c[i])
; end end ;
endmodule
"##
);
}
#[test]
fn test5() {
let (ret, _) =
preprocess(get_testcase("test5.sv"), &HashMap::new(), &[] as &[String]).unwrap();
assert_eq!(
ret.text(),
r##"module a;
initial begin
$display("`HI, world");
$display( "`HI, world" );
$display( "Hello, x" );
end
endmodule
"##
);
}
#[test]
fn test6() {
let (ret, _) =
preprocess(get_testcase("test6.sv"), &HashMap::new(), &[] as &[String]).unwrap();
assert_eq!(
ret.text(),
r##"
module a;
initial begin
$display( "left side: \"right side\"" );
end
endmodule
"##
);

View File

@ -0,0 +1,10 @@
module a;
`define HI Hello
`define LO "`HI, world"
`define H(x) "Hello, x"
initial begin
$display("`HI, world");
$display(`LO);
$display(`H(world));
end
endmodule

View File

@ -0,0 +1,7 @@
`define msg(x,y) `"x: `\`"y`\`"`"
module a;
initial begin
$display(`msg(left side,right side));
end
endmodule

View File

@ -177,6 +177,7 @@ pub struct ElseGroupOfLines {
#[derive(Clone, Debug, PartialEq, Node)]
pub enum SourceDescription {
Comment(Box<Comment>),
StringLiteral(Box<StringLiteral>),
NotDirective(Box<SourceDescriptionNotDirective>),
CompilerDirective(Box<CompilerDirective>),
}

View File

@ -7,7 +7,7 @@ use std::fmt;
use std::path::{Path, PathBuf};
pub use sv_parser_error::{Error, ErrorKind};
use sv_parser_parser::{lib_parser, sv_parser, Span, SpanInfo};
use sv_parser_pp::preprocess::{preprocess, Define, Defines, PreprocessedText};
pub use sv_parser_pp::preprocess::{preprocess, Define, Defines, PreprocessedText};
pub use sv_parser_syntaxtree::*;
pub struct SyntaxTree {