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 delay value 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

View File

@ -22,6 +22,8 @@ pub enum ErrorKind {
DefineArgNotFound(String),
#[fail(display = "Define not found: {}", _0)]
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]
pub(crate) fn param_expression(s: Span) -> IResult<Span, ParamExpression> {
alt((
map(data_type, |x| ParamExpression::DataType(Box::new(x))),
map(mintypmax_expression, |x| {
map(terminated(mintypmax_expression, peek(none_of("#"))), |x| {
ParamExpression::MintypmaxExpression(Box::new(x))
}),
map(data_type, |x| ParamExpression::DataType(Box::new(x))),
map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))),
))(s)
}

View File

@ -6,6 +6,8 @@ use crate::*;
#[packrat_parser]
pub(crate) fn constant_primary(s: Span) -> IResult<Span, ConstantPrimary> {
alt((
// BNF-WA
map(keyword("$"), |x| ConstantPrimary::Dollar(Box::new(x))),
map(keyword("null"), |x| ConstantPrimary::Null(Box::new(x))),
map(constant_assignment_pattern_expression, |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> {
let (s, a) = symbol("`")(s)?;
let (s, b) = keyword("define")(s)?;
begin_keywords("directive");
let (s, c) = text_macro_name(s)?;
end_keywords();
let (s, d) = opt(macro_text)(s)?;
Ok((
s,
@ -255,7 +257,7 @@ pub(crate) fn text_macro_usage(s: Span) -> IResult<Span, TextMacroUsage> {
#[tracable_parser]
#[packrat_parser]
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,) }))
}
@ -555,7 +557,7 @@ pub(crate) fn default_nettype_value(s: Span) -> IResult<Span, DefaultNettypeValu
keyword("tri1"),
keyword("trior"),
keyword("trireg"),
keyword("triwand"),
keyword("triand"),
keyword("tri"),
keyword("uwire"),
keyword("wand"),

View File

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

View File

@ -1,5 +1,6 @@
use crate::range::Range;
use failure::ResultExt;
use nom::combinator::all_consuming;
use nom_greedyerror::error_position;
use std::collections::{BTreeMap, HashMap};
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 (_, 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::Error(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 mut actual_args = Vec::new();
let no_args = args.is_none();
if let Some(args) = args {
let (_, ref args, _) = args.nodes;
let (ref args,) = args.nodes;
for arg in args.contents() {
let (ref arg,) = arg.nodes;
let arg = arg.str(&s);
actual_args.push(arg);
if let Some(arg) = arg {
let (ref arg,) = arg.nodes;
let arg = arg.str(&s);
actual_args.push(Some(arg));
} else {
actual_args.push(None);
}
}
}
let define = defines.get(&id);
if let Some(Some(define)) = define {
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() {
let value = if let Some(actual_arg) = actual_args.get(i) {
*actual_arg
} else {
if let Some(default) = default {
default
} else {
return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into());
let value = match actual_args.get(i) {
Some(Some(actual_arg)) => *actual_arg,
Some(None) => {
if let Some(default) = default {
default
} else {
""
}
}
None => {
if let Some(default) = default {
default
} else {
return Err(ErrorKind::DefineArgNotFound(String::from(arg)).into());
}
}
};
arg_map.insert(String::from(arg), value);

View File

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

View File

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