Skip to content

Commit 323589c

Browse files
authored
Merge pull request #123 from pointerliu/fix-gen-inside
Fix parser failure for `inside` expression in module-level if generate construct
2 parents 9a329a5 + 247790c commit 323589c

3 files changed

Lines changed: 37 additions & 0 deletions

File tree

sv-parser-parser/src/expressions/expressions.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,15 @@ pub(crate) fn expression_or_cond_pattern_ternary(
7878
#[packrat_parser]
7979
pub(crate) fn constant_expression(s: Span) -> IResult<Span, ConstantExpression> {
8080
alt((
81+
map(terminated(constant_primary, peek(one_of(",();}:"))), |x| {
82+
ConstantExpression::ConstantPrimary(Box::new(x))
83+
}),
8184
constant_expression_ternary,
8285
constant_expression_binary,
8386
constant_expression_unary,
87+
map(constant_inside_expression, |x| {
88+
ConstantExpression::Inside(Box::new(x))
89+
}),
8490
map(constant_primary, |x| {
8591
ConstantExpression::ConstantPrimary(Box::new(x))
8692
}),
@@ -133,6 +139,16 @@ pub(crate) fn constant_expression_ternary(s: Span) -> IResult<Span, ConstantExpr
133139
))
134140
}
135141

142+
#[recursive_parser]
143+
#[tracable_parser]
144+
#[packrat_parser]
145+
pub(crate) fn constant_inside_expression(s: Span) -> IResult<Span, ConstantInsideExpression> {
146+
let (s, a) = constant_expression(s)?;
147+
let (s, b) = keyword("inside")(s)?;
148+
let (s, c) = brace(open_range_list)(s)?;
149+
Ok((s, ConstantInsideExpression { nodes: (a, b, c) }))
150+
}
151+
136152
#[tracable_parser]
137153
#[packrat_parser]
138154
pub(crate) fn constant_mintypmax_expression(s: Span) -> IResult<Span, ConstantMintypmaxExpression> {

sv-parser-parser/src/tests.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5071,6 +5071,21 @@ mod spec {
50715071
assign r=3'bz11 inside {3'b1?1, 3'b011}; // r = 1'bx"##,
50725072
Ok((_, _))
50735073
);
5074+
// Bug trigger: inside expression in module-level if statement (without generate keyword)
5075+
// Fails at "inside" keyword - parser cannot handle "if (x inside {a, b}) begin" at module level
5076+
test!(
5077+
many1(module_item),
5078+
r##"module a;
5079+
typedef enum logic {
5080+
SwAccessRW = 0,
5081+
SwAccessRO = 1
5082+
} sw_access_e;
5083+
parameter sw_access_e SwAccess = SwAccessRW;
5084+
wire x;
5085+
if (SwAccess inside {SwAccessRW, SwAccessRO});
5086+
endmodule"##,
5087+
Ok((_, _))
5088+
);
50745089
test!(
50755090
many1(module_item),
50765091
r##"initial begin

sv-parser-syntaxtree/src/expressions/expressions.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub enum ConstantExpression {
3636
Unary(Box<ConstantExpressionUnary>),
3737
Binary(Box<ConstantExpressionBinary>),
3838
Ternary(Box<ConstantExpressionTernary>),
39+
Inside(Box<ConstantInsideExpression>),
3940
}
4041

4142
#[derive(Clone, Debug, PartialEq, Node)]
@@ -65,6 +66,11 @@ pub struct ConstantExpressionTernary {
6566
),
6667
}
6768

69+
#[derive(Clone, Debug, PartialEq, Node)]
70+
pub struct ConstantInsideExpression {
71+
pub nodes: (ConstantExpression, Keyword, Brace<OpenRangeList>),
72+
}
73+
6874
#[derive(Clone, Debug, PartialEq, Node)]
6975
pub enum ConstantMintypmaxExpression {
7076
Unary(Box<ConstantExpression>),

0 commit comments

Comments
 (0)