This commit is contained in:
dalance 2019-11-06 17:44:19 +09:00
parent 71644e960f
commit a2c265f5b7
9 changed files with 122 additions and 88 deletions

View File

@ -8,6 +8,9 @@
* [Fixed] hierarchical this bug * [Fixed] hierarchical this bug
* [Fixed] hierarchical delay value bug * [Fixed] hierarchical delay value bug
* [Fixed] const class new bug * [Fixed] const class new bug
* [Fixed] missing all_consuming of pp_parser
* [Fixed] typo 'triwand'
* [Fixed] arguments of text_macro_usage
## [v0.3.6](https://github.com/dalance/sv-parser/compare/v0.3.5...v0.3.6) - 2019-11-05 ## [v0.3.6](https://github.com/dalance/sv-parser/compare/v0.3.5...v0.3.6) - 2019-11-05

View File

@ -22,6 +22,8 @@ pub enum ErrorKind {
DefineArgNotFound(String), DefineArgNotFound(String),
#[fail(display = "Define not found: {}", _0)] #[fail(display = "Define not found: {}", _0)]
DefineNotFound(String), DefineNotFound(String),
#[fail(display = "Define must have argument")]
DefineNoArgs,
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -183,10 +183,10 @@ pub(crate) fn constant_param_expression(s: Span) -> IResult<Span, ConstantParamE
#[packrat_parser] #[packrat_parser]
pub(crate) fn param_expression(s: Span) -> IResult<Span, ParamExpression> { pub(crate) fn param_expression(s: Span) -> IResult<Span, ParamExpression> {
alt(( alt((
map(data_type, |x| ParamExpression::DataType(Box::new(x))), map(terminated(mintypmax_expression, peek(none_of("#"))), |x| {
map(mintypmax_expression, |x| {
ParamExpression::MintypmaxExpression(Box::new(x)) ParamExpression::MintypmaxExpression(Box::new(x))
}), }),
map(data_type, |x| ParamExpression::DataType(Box::new(x))),
map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))), map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))),
))(s) ))(s)
} }

View File

@ -6,6 +6,8 @@ use crate::*;
#[packrat_parser] #[packrat_parser]
pub(crate) fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> { pub(crate) fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> {
alt(( alt((
// BNF-WA
map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))),
map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))), map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))),
map(constant_assignment_pattern_expression, |x| { map(constant_assignment_pattern_expression, |x| {
ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x)) ConstantPrimary::ConstantAssignmentPatternExpression(Box::new(x))

View File

@ -154,7 +154,9 @@ pub(crate) fn angle_bracket_literal_impl(s: Span) -> IResult<Span, Locate> {
pub(crate) fn text_macro_definition(s: Span) -> IResult<Span, TextMacroDefinition> { pub(crate) fn text_macro_definition(s: Span) -> IResult<Span, TextMacroDefinition> {
let (s, a) = symbol("`")(s)?; let (s, a) = symbol("`")(s)?;
let (s, b) = keyword("define")(s)?; let (s, b) = keyword("define")(s)?;
begin_keywords("directive");
let (s, c) = text_macro_name(s)?; let (s, c) = text_macro_name(s)?;
end_keywords();
let (s, d) = opt(macro_text)(s)?; let (s, d) = opt(macro_text)(s)?;
Ok(( Ok((
s, s,
@ -255,7 +257,7 @@ pub(crate) fn text_macro_usage(s: Span) -> IResult<Span, TextMacroUsage> {
#[tracable_parser] #[tracable_parser]
#[packrat_parser] #[packrat_parser]
pub(crate) fn list_of_actual_arguments(s: Span) -> IResult<Span, ListOfActualArguments> { pub(crate) fn list_of_actual_arguments(s: Span) -> IResult<Span, ListOfActualArguments> {
let (s, a) = list(symbol(","), actual_argument)(s)?; let (s, a) = list(symbol(","), opt(actual_argument))(s)?;
Ok((s, ListOfActualArguments { nodes: (a,) })) Ok((s, ListOfActualArguments { nodes: (a,) }))
} }
@ -555,7 +557,7 @@ pub(crate) fn default_nettype_value(s: Span) -> IResult<Span, DefaultNettypeValu
keyword("tri1"), keyword("tri1"),
keyword("trior"), keyword("trior"),
keyword("trireg"), keyword("trireg"),
keyword("triwand"), keyword("triand"),
keyword("tri"), keyword("tri"),
keyword("uwire"), keyword("uwire"),
keyword("wand"), keyword("wand"),

View File

@ -388,6 +388,11 @@ mod unit {
r##"module a; initial begin #a.b; end endmodule"##, r##"module a; initial begin #a.b; end endmodule"##,
Ok((_, _)) Ok((_, _))
); );
test!(
source_text,
r##"module a; b #( .a(a+1)) a (); endmodule"##,
Ok((_, _))
);
} }
} }
@ -1780,21 +1785,21 @@ mod spec {
channel = {channel, channel_type'(genPkt())};"##, channel = {channel, channel_type'(genPkt())};"##,
Ok((_, _)) Ok((_, _))
); );
// TODO // BNF-WA
// $ can't be parsed because it is not constant_primary // $ can't be parsed because it is not constant_primary
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// Packet p; Packet p;
// int size; int size;
// size = channel[0] + 4; size = channel[0] + 4;
// p = Packet'( channel[0 : size - 1] ); // convert stream to Packet p = Packet'( channel[0 : size - 1] ); // convert stream to Packet
// channel = channel[ size : $ ]; // update the stream so it now channel = channel[ size : $ ]; // update the stream so it now
// // lacks that packet // lacks that packet
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
test!( test!(
source_text, source_text,
r##"virtual class C#(parameter type T = logic, parameter SIZE = 1); r##"virtual class C#(parameter type T = logic, parameter SIZE = 1);
@ -2380,37 +2385,37 @@ mod spec {
end"##, end"##,
Ok((_, _)) Ok((_, _))
); );
// TODO // BNF-WA
// $ can't be parsed because it is not constant_primary // $ can't be parsed because it is not constant_primary
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// int q[$] = { 2, 4, 8 }; int q[$] = { 2, 4, 8 };
// int e, pos; int e, pos;
// // assignment // method call yielding the // assignment // method call yielding the
// // // same value in variable q // // same value in variable q
// // ----------------------------- // ------------------------- // ----------------------------- // -------------------------
// q = { q, 6 }; // q.push_back(6) q = { q, 6 }; // q.push_back(6)
// q = { e, q }; // q.push_front(e) q = { e, q }; // q.push_front(e)
// q = q[1:$]; // void'(q.pop_front()) or q.delete(0) q = q[1:$]; // void'(q.pop_front()) or q.delete(0)
// q = q[0:$-1]; // void'(q.pop_back()) or q = q[0:$-1]; // void'(q.pop_back()) or
// // q.delete(q.size-1) // q.delete(q.size-1)
// q = { q[0:pos-1], e, q[pos:$] }; // q.insert(pos, e) q = { q[0:pos-1], e, q[pos:$] }; // q.insert(pos, e)
// q = { q[0:pos], e, q[pos+1:$] }; // q.insert(pos+1, e) q = { q[0:pos], e, q[pos+1:$] }; // q.insert(pos+1, e)
// q = {}; // q.delete() q = {}; // q.delete()
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
// TODO // BNF-WA
// $ can't be parsed because it is not constant_primary // $ can't be parsed because it is not constant_primary
//test!( test!(
// many1(module_item), many1(module_item),
// r##"initial begin r##"initial begin
// q = q[2:$]; // a new queue lacking the first two items q = q[2:$]; // a new queue lacking the first two items
// q = q[1:$-1]; // a new queue lacking the first and last items q = q[1:$-1]; // a new queue lacking the first and last items
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
test!( test!(
many1(module_item), many1(module_item),
r##"initial begin r##"initial begin
@ -5009,41 +5014,41 @@ mod spec {
end"##, end"##,
Ok((_, _)) Ok((_, _))
); );
// TODO // BNF-WA
// $ can't be parsed because it is not constant_primary // $ can't be parsed because it is not constant_primary
//test!( test!(
// many1(module_item), many1(module_item),
// r##"byte stream[$]; // byte stream r##"byte stream[$]; // byte stream
// class Packet; class Packet;
// rand int header; rand int header;
// rand int len; rand int len;
// rand byte payload[]; rand byte payload[];
// int crc; int crc;
// constraint G { len > 1; payload.size == len ; } constraint G { len > 1; payload.size == len ; }
// function void post_randomize; crc = payload.sum; endfunction function void post_randomize; crc = payload.sum; endfunction
// endclass endclass
// initial begin initial begin
// send: begin // Create random packet and transmit send: begin // Create random packet and transmit
// byte q[$]; byte q[$];
// Packet p = new; Packet p = new;
// void'(p.randomize()); void'(p.randomize());
// q = {<< byte{p.header, p.len, p.payload, p.crc}}; // pack q = {<< byte{p.header, p.len, p.payload, p.crc}}; // pack
// stream = {stream, q}; // append to stream stream = {stream, q}; // append to stream
// end end
// receive: begin // Receive packet, unpack, and remove receive: begin // Receive packet, unpack, and remove
// byte q[$]; byte q[$];
// Packet p = new; Packet p = new;
// {<< byte{ p.header, p.len, p.payload with [0 +: p.len], p.crc }} = stream; {<< byte{ p.header, p.len, p.payload with [0 +: p.len], p.crc }} = stream;
// stream = stream[ $bits(p) / 8 : $ ]; // remove packet stream = stream[ $bits(p) / 8 : $ ]; // remove packet
// end end
// end"##, end"##,
// Ok((_, _)) Ok((_, _))
//); );
test!( test!(
many1(module_item), many1(module_item),
r##"initial begin r##"initial begin
@ -15848,7 +15853,7 @@ mod spec {
fn debug() { fn debug() {
test!( test!(
source_text, source_text,
r##"module a; initial begin #a.b; end endmodule"##, r##"module a; b #( .a(a+1)) a (); endmodule"##,
Ok((_, _)) Ok((_, _))
); );
nom_tracable::cumulative_histogram(); nom_tracable::cumulative_histogram();

View File

@ -1,5 +1,6 @@
use crate::range::Range; use crate::range::Range;
use failure::ResultExt; use failure::ResultExt;
use nom::combinator::all_consuming;
use nom_greedyerror::error_position; use nom_greedyerror::error_position;
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
use std::convert::TryInto; use std::convert::TryInto;
@ -110,7 +111,7 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
} }
let span = Span::new_extra(&s, SpanInfo::default()); let span = Span::new_extra(&s, SpanInfo::default());
let (_, pp_text) = pp_parser(span).map_err(|x| match x { let (_, pp_text) = all_consuming(pp_parser)(span).map_err(|x| match x {
nom::Err::Incomplete(_) => ErrorKind::Parse(None), nom::Err::Incomplete(_) => ErrorKind::Parse(None),
nom::Err::Error(e) => { nom::Err::Error(e) => {
if let Some(pos) = error_position(&e) { if let Some(pos) = error_position(&e) {
@ -406,27 +407,45 @@ fn resolve_text_macro_usage<T: AsRef<Path>, U: AsRef<Path>>(
let id = identifier((&name.nodes.0).into(), &s).unwrap(); let id = identifier((&name.nodes.0).into(), &s).unwrap();
let mut actual_args = Vec::new(); let mut actual_args = Vec::new();
let no_args = args.is_none();
if let Some(args) = args { if let Some(args) = args {
let (_, ref args, _) = args.nodes; let (_, ref args, _) = args.nodes;
let (ref args,) = args.nodes; let (ref args,) = args.nodes;
for arg in args.contents() { for arg in args.contents() {
let (ref arg,) = arg.nodes; if let Some(arg) = arg {
let arg = arg.str(&s); let (ref arg,) = arg.nodes;
actual_args.push(arg); let arg = arg.str(&s);
actual_args.push(Some(arg));
} else {
actual_args.push(None);
}
} }
} }
let define = defines.get(&id); let define = defines.get(&id);
if let Some(Some(define)) = define { if let Some(Some(define)) = define {
let mut arg_map = HashMap::new(); let mut arg_map = HashMap::new();
if !define.arguments.is_empty() && no_args {
return Err(ErrorKind::DefineNoArgs.into());
}
for (i, (arg, default)) in define.arguments.iter().enumerate() { for (i, (arg, default)) in define.arguments.iter().enumerate() {
let value = if let Some(actual_arg) = actual_args.get(i) { let value = match actual_args.get(i) {
*actual_arg Some(Some(actual_arg)) => *actual_arg,
} else { Some(None) => {
if let Some(default) = default { if let Some(default) = default {
default default
} else { } else {
return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into()); ""
}
}
None => {
if let Some(default) = default {
default
} else {
return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into());
}
} }
}; };
arg_map.insert(String::from(arg), value); arg_map.insert(String::from(arg), value);

View File

@ -19,6 +19,7 @@ pub enum ConstantPrimary {
ConstantAssignmentPatternExpression(Box<ConstantAssignmentPatternExpression>), ConstantAssignmentPatternExpression(Box<ConstantAssignmentPatternExpression>),
TypeReference(Box<TypeReference>), TypeReference(Box<TypeReference>),
Null(Box<Keyword>), Null(Box<Keyword>),
Dollar(Box<Keyword>),
} }
#[derive(Clone, Debug, PartialEq, Node)] #[derive(Clone, Debug, PartialEq, Node)]

View File

@ -102,7 +102,7 @@ pub struct TextMacroUsage {
#[derive(Clone, Debug, PartialEq, Node)] #[derive(Clone, Debug, PartialEq, Node)]
pub struct ListOfActualArguments { pub struct ListOfActualArguments {
pub nodes: (List<Symbol, ActualArgument>,), pub nodes: (List<Symbol, Option<ActualArgument>>,),
} }
#[derive(Clone, Debug, PartialEq, Node)] #[derive(Clone, Debug, PartialEq, Node)]