Fix bugs
This commit is contained in:
parent
71644e960f
commit
a2c265f5b7
@ -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
|
||||
|
||||
|
@ -22,6 +22,8 @@ pub enum ErrorKind {
|
||||
DefineArgNotFound(String),
|
||||
#[fail(display = "Define not found: {}", _0)]
|
||||
DefineNotFound(String),
|
||||
#[fail(display = "Define must have argument")]
|
||||
DefineNoArgs,
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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"),
|
||||
|
@ -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();
|
||||
|
@ -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,28 +407,46 @@ 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() {
|
||||
if let Some(arg) = arg {
|
||||
let (ref arg,) = arg.nodes;
|
||||
let arg = arg.str(&s);
|
||||
actual_args.push(arg);
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ pub enum ConstantPrimary {
|
||||
ConstantAssignmentPatternExpression(Box<ConstantAssignmentPatternExpression>),
|
||||
TypeReference(Box<TypeReference>),
|
||||
Null(Box<Keyword>),
|
||||
Dollar(Box<Keyword>),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Node)]
|
||||
|
@ -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)]
|
||||
|
Loading…
x
Reference in New Issue
Block a user