sv_parser_parser/declarations/
covergroup_declarations.rs

1use crate::*;
2
3// -----------------------------------------------------------------------------
4
5#[tracable_parser]
6#[packrat_parser]
7pub(crate) fn covergroup_declaration(s: Span) -> IResult<Span, CovergroupDeclaration> {
8    let (s, a) = keyword("covergroup")(s)?;
9    let (s, b) = covergroup_identifier(s)?;
10    let (s, c) = opt(paren(opt(tf_port_list)))(s)?;
11    let (s, d) = opt(coverage_event)(s)?;
12    let (s, e) = symbol(";")(s)?;
13    let (s, (f, g)) = many_till(coverage_spec_or_option, keyword("endgroup"))(s)?;
14    let (s, h) = opt(pair(symbol(":"), covergroup_identifier))(s)?;
15    Ok((
16        s,
17        CovergroupDeclaration {
18            nodes: (a, b, c, d, e, f, g, h),
19        },
20    ))
21}
22
23#[tracable_parser]
24#[packrat_parser]
25pub(crate) fn coverage_spec_or_option(s: Span) -> IResult<Span, CoverageSpecOrOption> {
26    alt((coverage_spec_or_option_spec, coverage_spec_or_option_option))(s)
27}
28
29#[tracable_parser]
30#[packrat_parser]
31pub(crate) fn coverage_spec_or_option_spec(s: Span) -> IResult<Span, CoverageSpecOrOption> {
32    let (s, a) = many0(attribute_instance)(s)?;
33    let (s, b) = coverage_spec(s)?;
34    Ok((
35        s,
36        CoverageSpecOrOption::Spec(Box::new(CoverageSpecOrOptionSpec { nodes: (a, b) })),
37    ))
38}
39
40#[tracable_parser]
41#[packrat_parser]
42pub(crate) fn coverage_spec_or_option_option(s: Span) -> IResult<Span, CoverageSpecOrOption> {
43    let (s, a) = many0(attribute_instance)(s)?;
44    let (s, b) = coverage_option(s)?;
45    let (s, c) = symbol(";")(s)?;
46    Ok((
47        s,
48        CoverageSpecOrOption::Option(Box::new(CoverageSpecOrOptionOption { nodes: (a, b, c) })),
49    ))
50}
51
52#[tracable_parser]
53#[packrat_parser]
54pub(crate) fn coverage_option(s: Span) -> IResult<Span, CoverageOption> {
55    alt((coverage_option_option, coverage_option_type_option))(s)
56}
57
58#[tracable_parser]
59#[packrat_parser]
60pub(crate) fn coverage_option_option(s: Span) -> IResult<Span, CoverageOption> {
61    let (s, a) = keyword("option")(s)?;
62    let (s, b) = symbol(".")(s)?;
63    let (s, c) = member_identifier(s)?;
64    let (s, d) = symbol("=")(s)?;
65    let (s, e) = expression(s)?;
66    Ok((
67        s,
68        CoverageOption::Option(Box::new(CoverageOptionOption {
69            nodes: (a, b, c, d, e),
70        })),
71    ))
72}
73
74#[tracable_parser]
75#[packrat_parser]
76pub(crate) fn coverage_option_type_option(s: Span) -> IResult<Span, CoverageOption> {
77    let (s, a) = keyword("type_option")(s)?;
78    let (s, b) = symbol(".")(s)?;
79    let (s, c) = member_identifier(s)?;
80    let (s, d) = symbol("=")(s)?;
81    let (s, e) = constant_expression(s)?;
82    Ok((
83        s,
84        CoverageOption::TypeOption(Box::new(CoverageOptionTypeOption {
85            nodes: (a, b, c, d, e),
86        })),
87    ))
88}
89
90#[tracable_parser]
91#[packrat_parser]
92pub(crate) fn coverage_spec(s: Span) -> IResult<Span, CoverageSpec> {
93    alt((
94        map(cover_point, |x| CoverageSpec::CoverPoint(Box::new(x))),
95        map(cover_cross, |x| CoverageSpec::CoverCross(Box::new(x))),
96    ))(s)
97}
98
99#[tracable_parser]
100#[packrat_parser]
101pub(crate) fn coverage_event(s: Span) -> IResult<Span, CoverageEvent> {
102    alt((
103        map(clocking_event, |x| {
104            CoverageEvent::ClockingEvent(Box::new(x))
105        }),
106        coverage_event_sample,
107        coverage_event_at,
108    ))(s)
109}
110
111#[tracable_parser]
112#[packrat_parser]
113pub(crate) fn coverage_event_sample(s: Span) -> IResult<Span, CoverageEvent> {
114    let (s, a) = keyword("with")(s)?;
115    let (s, b) = keyword("function")(s)?;
116    let (s, c) = keyword("sample")(s)?;
117    let (s, d) = paren(opt(tf_port_list))(s)?;
118    Ok((
119        s,
120        CoverageEvent::Sample(Box::new(CoverageEventSample {
121            nodes: (a, b, c, d),
122        })),
123    ))
124}
125
126#[tracable_parser]
127#[packrat_parser]
128pub(crate) fn coverage_event_at(s: Span) -> IResult<Span, CoverageEvent> {
129    let (s, a) = symbol("@@")(s)?;
130    let (s, b) = paren(block_event_expression)(s)?;
131    Ok((
132        s,
133        CoverageEvent::At(Box::new(CoverageEventAt { nodes: (a, b) })),
134    ))
135}
136
137#[tracable_parser]
138#[packrat_parser]
139pub(crate) fn block_event_expression(s: Span) -> IResult<Span, BlockEventExpression> {
140    alt((
141        block_event_expression_or,
142        block_event_expression_begin,
143        block_event_expression_end,
144    ))(s)
145}
146
147#[recursive_parser]
148#[tracable_parser]
149#[packrat_parser]
150pub(crate) fn block_event_expression_or(s: Span) -> IResult<Span, BlockEventExpression> {
151    let (s, a) = block_event_expression(s)?;
152    let (s, b) = keyword("or")(s)?;
153    let (s, c) = block_event_expression(s)?;
154    Ok((
155        s,
156        BlockEventExpression::Or(Box::new(BlockEventExpressionOr { nodes: (a, b, c) })),
157    ))
158}
159
160#[tracable_parser]
161#[packrat_parser]
162pub(crate) fn block_event_expression_begin(s: Span) -> IResult<Span, BlockEventExpression> {
163    let (s, a) = keyword("begin")(s)?;
164    let (s, b) = hierarchical_btf_identifier(s)?;
165    Ok((
166        s,
167        BlockEventExpression::Begin(Box::new(BlockEventExpressionBegin { nodes: (a, b) })),
168    ))
169}
170
171#[tracable_parser]
172#[packrat_parser]
173pub(crate) fn block_event_expression_end(s: Span) -> IResult<Span, BlockEventExpression> {
174    let (s, a) = keyword("end")(s)?;
175    let (s, b) = hierarchical_btf_identifier(s)?;
176    Ok((
177        s,
178        BlockEventExpression::End(Box::new(BlockEventExpressionEnd { nodes: (a, b) })),
179    ))
180}
181
182#[tracable_parser]
183#[packrat_parser]
184pub(crate) fn hierarchical_btf_identifier(s: Span) -> IResult<Span, HierarchicalBtfIdentifier> {
185    alt((
186        map(hierarchical_tf_identifier, |x| {
187            HierarchicalBtfIdentifier::HierarchicalTfIdentifier(Box::new(x))
188        }),
189        map(hierarchical_block_identifier, |x| {
190            HierarchicalBtfIdentifier::HierarchicalBlockIdentifier(Box::new(x))
191        }),
192        hierarchical_btf_identifier_method,
193    ))(s)
194}
195
196#[tracable_parser]
197#[packrat_parser]
198pub(crate) fn hierarchical_btf_identifier_method(
199    s: Span,
200) -> IResult<Span, HierarchicalBtfIdentifier> {
201    let (s, a) = opt(hierarchical_identifier_or_class_scope)(s)?;
202    let (s, b) = method_identifier(s)?;
203    Ok((
204        s,
205        HierarchicalBtfIdentifier::Method(Box::new(HierarchicalBtfIdentifierMethod {
206            nodes: (a, b),
207        })),
208    ))
209}
210
211#[tracable_parser]
212#[packrat_parser]
213pub(crate) fn hierarchical_identifier_or_class_scope(
214    s: Span,
215) -> IResult<Span, HierarchicalIdentifierOrClassScope> {
216    alt((
217        map(pair(hierarchical_identifier, symbol(".")), |x| {
218            HierarchicalIdentifierOrClassScope::HierarchicalIdentifier(Box::new(x))
219        }),
220        map(class_scope, |x| {
221            HierarchicalIdentifierOrClassScope::ClassScope(Box::new(x))
222        }),
223    ))(s)
224}
225
226#[tracable_parser]
227#[packrat_parser]
228pub(crate) fn cover_point(s: Span) -> IResult<Span, CoverPoint> {
229    let (s, a) = opt(triple(
230        opt(data_type_or_implicit_cover_point),
231        cover_point_identifier,
232        symbol(":"),
233    ))(s)?;
234    let (s, b) = keyword("coverpoint")(s)?;
235    let (s, c) = expression(s)?;
236    let (s, d) = opt(pair(keyword("iff"), paren(expression)))(s)?;
237    let (s, e) = bins_or_empty(s)?;
238    Ok((
239        s,
240        CoverPoint {
241            nodes: (a, b, c, d, e),
242        },
243    ))
244}
245
246#[tracable_parser]
247#[packrat_parser]
248pub(crate) fn data_type_or_implicit_cover_point(s: Span) -> IResult<Span, DataTypeOrImplicit> {
249    alt((
250        map(terminated(data_type, peek(cover_point_identifier)), |x| {
251            DataTypeOrImplicit::DataType(Box::new(x))
252        }),
253        map(
254            terminated(implicit_data_type, peek(cover_point_identifier)),
255            |x| DataTypeOrImplicit::ImplicitDataType(Box::new(x)),
256        ),
257    ))(s)
258}
259
260#[tracable_parser]
261#[packrat_parser]
262pub(crate) fn bins_or_empty(s: Span) -> IResult<Span, BinsOrEmpty> {
263    alt((
264        bins_or_empty_non_empty,
265        map(symbol(";"), |x| BinsOrEmpty::Empty(Box::new(x))),
266    ))(s)
267}
268
269#[tracable_parser]
270#[packrat_parser]
271pub(crate) fn bins_or_empty_non_empty(s: Span) -> IResult<Span, BinsOrEmpty> {
272    let (s, a) = brace(pair(
273        many0(attribute_instance),
274        many0(pair(bins_or_options, symbol(";"))),
275    ))(s)?;
276    Ok((
277        s,
278        BinsOrEmpty::NonEmpty(Box::new(BinsOrEmptyNonEmpty { nodes: (a,) })),
279    ))
280}
281
282#[tracable_parser]
283#[packrat_parser]
284pub(crate) fn bins_or_options(s: Span) -> IResult<Span, BinsOrOptions> {
285    alt((
286        map(coverage_option, |x| {
287            BinsOrOptions::CoverageOption(Box::new(x))
288        }),
289        bins_or_options_covergroup,
290        bins_or_options_cover_point,
291        bins_or_options_set_covergroup,
292        bins_or_options_trans_list,
293        bins_or_options_default_sequence,
294        bins_or_options_default,
295    ))(s)
296}
297
298#[tracable_parser]
299#[packrat_parser]
300pub(crate) fn bins_or_options_covergroup(s: Span) -> IResult<Span, BinsOrOptions> {
301    let (s, a) = opt(wildcard)(s)?;
302    let (s, b) = bins_keyword(s)?;
303    let (s, c) = bin_identifier(s)?;
304    let (s, d) = opt(bracket(opt(covergroup_expression)))(s)?;
305    let (s, e) = symbol("=")(s)?;
306    let (s, f) = brace(covergroup_range_list)(s)?;
307    let (s, g) = opt(pair(keyword("with"), paren(with_covergroup_expression)))(s)?;
308    let (s, h) = opt(pair(keyword("iff"), paren(expression)))(s)?;
309    Ok((
310        s,
311        BinsOrOptions::Covergroup(Box::new(BinsOrOptionsCovergroup {
312            nodes: (a, b, c, d, e, f, g, h),
313        })),
314    ))
315}
316
317#[tracable_parser]
318#[packrat_parser]
319pub(crate) fn wildcard(s: Span) -> IResult<Span, Wildcard> {
320    let (s, a) = keyword("wildcard")(s)?;
321    Ok((s, Wildcard { nodes: (a,) }))
322}
323
324#[tracable_parser]
325#[packrat_parser]
326pub(crate) fn bins_or_options_cover_point(s: Span) -> IResult<Span, BinsOrOptions> {
327    let (s, a) = opt(wildcard)(s)?;
328    let (s, b) = bins_keyword(s)?;
329    let (s, c) = bin_identifier(s)?;
330    let (s, d) = opt(bracket(opt(covergroup_expression)))(s)?;
331    let (s, e) = symbol("=")(s)?;
332    let (s, f) = cover_point_identifier(s)?;
333    let (s, g) = keyword("with")(s)?;
334    let (s, h) = paren(with_covergroup_expression)(s)?;
335    let (s, i) = opt(pair(keyword("iff"), paren(expression)))(s)?;
336    Ok((
337        s,
338        BinsOrOptions::CoverPoint(Box::new(BinsOrOptionsCoverPoint {
339            nodes: (a, b, c, d, e, f, g, h, i),
340        })),
341    ))
342}
343
344#[tracable_parser]
345#[packrat_parser]
346pub(crate) fn bins_or_options_set_covergroup(s: Span) -> IResult<Span, BinsOrOptions> {
347    let (s, a) = opt(wildcard)(s)?;
348    let (s, b) = bins_keyword(s)?;
349    let (s, c) = bin_identifier(s)?;
350    let (s, d) = opt(bracket(opt(covergroup_expression)))(s)?;
351    let (s, e) = symbol("=")(s)?;
352    let (s, f) = set_covergroup_expression(s)?;
353    let (s, g) = opt(pair(keyword("iff"), paren(expression)))(s)?;
354    Ok((
355        s,
356        BinsOrOptions::SetCovergroup(Box::new(BinsOrOptionsSetCovergroup {
357            nodes: (a, b, c, d, e, f, g),
358        })),
359    ))
360}
361
362#[tracable_parser]
363#[packrat_parser]
364pub(crate) fn bins_or_options_trans_list(s: Span) -> IResult<Span, BinsOrOptions> {
365    let (s, a) = opt(wildcard)(s)?;
366    let (s, b) = bins_keyword(s)?;
367    let (s, c) = bin_identifier(s)?;
368    let (s, d) = opt(pair(symbol("["), symbol("]")))(s)?;
369    let (s, e) = symbol("=")(s)?;
370    let (s, f) = trans_list(s)?;
371    let (s, g) = opt(pair(keyword("iff"), paren(expression)))(s)?;
372    Ok((
373        s,
374        BinsOrOptions::TransList(Box::new(BinsOrOptionsTransList {
375            nodes: (a, b, c, d, e, f, g),
376        })),
377    ))
378}
379
380#[tracable_parser]
381#[packrat_parser]
382pub(crate) fn bins_or_options_default(s: Span) -> IResult<Span, BinsOrOptions> {
383    let (s, a) = bins_keyword(s)?;
384    let (s, b) = bin_identifier(s)?;
385    let (s, c) = opt(bracket(opt(covergroup_expression)))(s)?;
386    let (s, d) = symbol("=")(s)?;
387    let (s, e) = keyword("default")(s)?;
388    let (s, f) = opt(pair(keyword("iff"), paren(expression)))(s)?;
389    Ok((
390        s,
391        BinsOrOptions::Default(Box::new(BinsOrOptionsDefault {
392            nodes: (a, b, c, d, e, f),
393        })),
394    ))
395}
396
397#[tracable_parser]
398#[packrat_parser]
399pub(crate) fn bins_or_options_default_sequence(s: Span) -> IResult<Span, BinsOrOptions> {
400    let (s, a) = bins_keyword(s)?;
401    let (s, b) = bin_identifier(s)?;
402    let (s, c) = symbol("=")(s)?;
403    let (s, d) = keyword("default")(s)?;
404    let (s, e) = keyword("sequence")(s)?;
405    let (s, f) = opt(pair(keyword("iff"), paren(expression)))(s)?;
406    Ok((
407        s,
408        BinsOrOptions::DefaultSequence(Box::new(BinsOrOptionsDefaultSequence {
409            nodes: (a, b, c, d, e, f),
410        })),
411    ))
412}
413
414#[tracable_parser]
415#[packrat_parser]
416pub(crate) fn bins_keyword(s: Span) -> IResult<Span, BinsKeyword> {
417    alt((
418        map(keyword("bins"), |x| BinsKeyword::Bins(Box::new(x))),
419        map(keyword("illegal_bins"), |x| {
420            BinsKeyword::IllegalBins(Box::new(x))
421        }),
422        map(keyword("ignore_bins"), |x| {
423            BinsKeyword::IgnoreBins(Box::new(x))
424        }),
425    ))(s)
426}
427
428#[tracable_parser]
429#[packrat_parser]
430pub(crate) fn trans_list(s: Span) -> IResult<Span, TransList> {
431    let (s, a) = list(symbol(","), paren(trans_set))(s)?;
432    Ok((s, TransList { nodes: (a,) }))
433}
434
435#[recursive_parser]
436#[tracable_parser]
437#[packrat_parser]
438pub(crate) fn trans_set(s: Span) -> IResult<Span, TransSet> {
439    let (s, a) = list(symbol("=>"), trans_range_list)(s)?;
440    Ok((s, TransSet { nodes: (a,) }))
441}
442
443#[tracable_parser]
444#[packrat_parser]
445pub(crate) fn trans_range_list(s: Span) -> IResult<Span, TransRangeList> {
446    alt((
447        trans_range_list_asterisk,
448        trans_range_list_arrow,
449        trans_range_list_equal,
450        map(trans_item, |x| TransRangeList::TransItem(Box::new(x))),
451    ))(s)
452}
453
454#[recursive_parser]
455#[tracable_parser]
456#[packrat_parser]
457pub(crate) fn trans_range_list_asterisk(s: Span) -> IResult<Span, TransRangeList> {
458    let (s, a) = trans_item(s)?;
459    let (s, b) = bracket(pair(symbol("*"), repeat_range))(s)?;
460    Ok((
461        s,
462        TransRangeList::Asterisk(Box::new(TransRangeListAsterisk { nodes: (a, b) })),
463    ))
464}
465
466#[recursive_parser]
467#[tracable_parser]
468#[packrat_parser]
469pub(crate) fn trans_range_list_arrow(s: Span) -> IResult<Span, TransRangeList> {
470    let (s, a) = trans_item(s)?;
471    let (s, b) = bracket(pair(symbol("->"), repeat_range))(s)?;
472    Ok((
473        s,
474        TransRangeList::Arrow(Box::new(TransRangeListArrow { nodes: (a, b) })),
475    ))
476}
477
478#[recursive_parser]
479#[tracable_parser]
480#[packrat_parser]
481pub(crate) fn trans_range_list_equal(s: Span) -> IResult<Span, TransRangeList> {
482    let (s, a) = trans_item(s)?;
483    let (s, b) = bracket(pair(symbol("="), repeat_range))(s)?;
484    Ok((
485        s,
486        TransRangeList::Equal(Box::new(TransRangeListEqual { nodes: (a, b) })),
487    ))
488}
489
490#[tracable_parser]
491#[packrat_parser]
492pub(crate) fn trans_item(s: Span) -> IResult<Span, TransItem> {
493    let (s, a) = covergroup_range_list(s)?;
494    Ok((s, TransItem { nodes: (a,) }))
495}
496
497#[tracable_parser]
498#[packrat_parser]
499pub(crate) fn repeat_range(s: Span) -> IResult<Span, RepeatRange> {
500    alt((
501        repeat_range_binary,
502        map(covergroup_expression, |x| {
503            RepeatRange::CovergroupExpression(Box::new(x))
504        }),
505    ))(s)
506}
507
508#[recursive_parser]
509#[tracable_parser]
510#[packrat_parser]
511pub(crate) fn repeat_range_binary(s: Span) -> IResult<Span, RepeatRange> {
512    let (s, a) = covergroup_expression(s)?;
513    let (s, b) = symbol(":")(s)?;
514    let (s, c) = covergroup_expression(s)?;
515    Ok((
516        s,
517        RepeatRange::Binary(Box::new(RepeatRangeBinary { nodes: (a, b, c) })),
518    ))
519}
520
521#[tracable_parser]
522#[packrat_parser]
523pub(crate) fn cover_cross(s: Span) -> IResult<Span, CoverCross> {
524    let (s, a) = opt(pair(cross_identifier, symbol(":")))(s)?;
525    let (s, b) = keyword("cross")(s)?;
526    let (s, c) = list_of_cross_items(s)?;
527    let (s, d) = opt(pair(keyword("iff"), paren(expression)))(s)?;
528    let (s, e) = cross_body(s)?;
529    Ok((
530        s,
531        CoverCross {
532            nodes: (a, b, c, d, e),
533        },
534    ))
535}
536
537#[tracable_parser]
538#[packrat_parser]
539pub(crate) fn list_of_cross_items(s: Span) -> IResult<Span, ListOfCrossItems> {
540    let (s, a) = cross_item(s)?;
541    let (s, b) = symbol(",")(s)?;
542    let (s, c) = list(symbol(","), cross_item)(s)?;
543    Ok((s, ListOfCrossItems { nodes: (a, b, c) }))
544}
545
546#[tracable_parser]
547#[packrat_parser]
548pub(crate) fn cross_item(s: Span) -> IResult<Span, CrossItem> {
549    alt((
550        map(cover_point_identifier, |x| {
551            CrossItem::CoverPointIdentifier(Box::new(x))
552        }),
553        map(variable_identifier, |x| {
554            CrossItem::VariableIdentifier(Box::new(x))
555        }),
556    ))(s)
557}
558
559#[tracable_parser]
560#[packrat_parser]
561pub(crate) fn cross_body(s: Span) -> IResult<Span, CrossBody> {
562    alt((
563        cross_body_non_empty,
564        map(symbol(";"), |x| CrossBody::Empty(Box::new(x))),
565    ))(s)
566}
567
568#[tracable_parser]
569#[packrat_parser]
570pub(crate) fn cross_body_non_empty(s: Span) -> IResult<Span, CrossBody> {
571    let (s, a) = brace(many0(cross_body_item))(s)?;
572    Ok((
573        s,
574        CrossBody::NonEmpty(Box::new(CrossBodyNonEmpty { nodes: (a,) })),
575    ))
576}
577
578#[tracable_parser]
579#[packrat_parser]
580pub(crate) fn cross_body_item(s: Span) -> IResult<Span, CrossBodyItem> {
581    alt((
582        map(function_declaration, |x| {
583            CrossBodyItem::FunctionDeclaration(Box::new(x))
584        }),
585        map(pair(bins_selection_or_option, symbol(";")), |x| {
586            CrossBodyItem::BinsSelectionOrOption(Box::new(x))
587        }),
588    ))(s)
589}
590
591#[tracable_parser]
592#[packrat_parser]
593pub(crate) fn bins_selection_or_option(s: Span) -> IResult<Span, BinsSelectionOrOption> {
594    alt((
595        bins_selection_or_option_coverage,
596        bins_selection_or_option_bins,
597    ))(s)
598}
599
600#[tracable_parser]
601#[packrat_parser]
602pub(crate) fn bins_selection_or_option_coverage(s: Span) -> IResult<Span, BinsSelectionOrOption> {
603    let (s, a) = many0(attribute_instance)(s)?;
604    let (s, b) = coverage_option(s)?;
605    Ok((
606        s,
607        BinsSelectionOrOption::Coverage(Box::new(BinsSelectionOrOptionCoverage { nodes: (a, b) })),
608    ))
609}
610
611#[tracable_parser]
612#[packrat_parser]
613pub(crate) fn bins_selection_or_option_bins(s: Span) -> IResult<Span, BinsSelectionOrOption> {
614    let (s, a) = many0(attribute_instance)(s)?;
615    let (s, b) = bins_selection(s)?;
616    Ok((
617        s,
618        BinsSelectionOrOption::Bins(Box::new(BinsSelectionOrOptionBins { nodes: (a, b) })),
619    ))
620}
621
622#[tracable_parser]
623#[packrat_parser]
624pub(crate) fn bins_selection(s: Span) -> IResult<Span, BinsSelection> {
625    let (s, a) = bins_keyword(s)?;
626    let (s, b) = bin_identifier(s)?;
627    let (s, c) = symbol("=")(s)?;
628    let (s, d) = select_expression(s)?;
629    let (s, e) = opt(pair(keyword("iff"), paren(expression)))(s)?;
630    Ok((
631        s,
632        BinsSelection {
633            nodes: (a, b, c, d, e),
634        },
635    ))
636}
637
638#[tracable_parser]
639#[packrat_parser]
640pub(crate) fn select_expression(s: Span) -> IResult<Span, SelectExpression> {
641    alt((
642        select_expression_and,
643        select_expression_or,
644        select_expression_with,
645        map(select_condition, |x| {
646            SelectExpression::SelectCondition(Box::new(x))
647        }),
648        select_expression_not,
649        select_expression_paren,
650        select_expression_cross_set,
651        map(cross_identifier, |x| {
652            SelectExpression::CrossIdentifier(Box::new(x))
653        }),
654    ))(s)
655}
656
657#[tracable_parser]
658#[packrat_parser]
659pub(crate) fn select_expression_not(s: Span) -> IResult<Span, SelectExpression> {
660    let (s, a) = symbol("!")(s)?;
661    let (s, b) = select_condition(s)?;
662    Ok((
663        s,
664        SelectExpression::Not(Box::new(SelectExpressionNot { nodes: (a, b) })),
665    ))
666}
667
668#[recursive_parser]
669#[tracable_parser]
670#[packrat_parser]
671pub(crate) fn select_expression_and(s: Span) -> IResult<Span, SelectExpression> {
672    let (s, a) = select_expression(s)?;
673    let (s, b) = symbol("&&")(s)?;
674    let (s, c) = select_expression(s)?;
675    Ok((
676        s,
677        SelectExpression::And(Box::new(SelectExpressionAnd { nodes: (a, b, c) })),
678    ))
679}
680
681#[recursive_parser]
682#[tracable_parser]
683#[packrat_parser]
684pub(crate) fn select_expression_or(s: Span) -> IResult<Span, SelectExpression> {
685    let (s, a) = select_expression(s)?;
686    let (s, b) = symbol("||")(s)?;
687    let (s, c) = select_expression(s)?;
688    Ok((
689        s,
690        SelectExpression::Or(Box::new(SelectExpressionOr { nodes: (a, b, c) })),
691    ))
692}
693
694#[tracable_parser]
695#[packrat_parser]
696pub(crate) fn select_expression_paren(s: Span) -> IResult<Span, SelectExpression> {
697    let (s, a) = paren(select_expression)(s)?;
698    Ok((
699        s,
700        SelectExpression::Paren(Box::new(SelectExpressionParen { nodes: (a,) })),
701    ))
702}
703
704#[recursive_parser]
705#[tracable_parser]
706#[packrat_parser]
707pub(crate) fn select_expression_with(s: Span) -> IResult<Span, SelectExpression> {
708    let (s, a) = select_expression(s)?;
709    let (s, b) = keyword("with")(s)?;
710    let (s, c) = paren(with_covergroup_expression)(s)?;
711    let (s, d) = opt(pair(keyword("matches"), integer_covergroup_expression))(s)?;
712    Ok((
713        s,
714        SelectExpression::With(Box::new(SelectExpressionWith {
715            nodes: (a, b, c, d),
716        })),
717    ))
718}
719
720#[recursive_parser]
721#[tracable_parser]
722#[packrat_parser]
723pub(crate) fn select_expression_cross_set(s: Span) -> IResult<Span, SelectExpression> {
724    let (s, a) = cross_set_expression(s)?;
725    let (s, b) = opt(pair(keyword("matches"), integer_covergroup_expression))(s)?;
726    Ok((
727        s,
728        SelectExpression::CrossSet(Box::new(SelectExpressionCrossSet { nodes: (a, b) })),
729    ))
730}
731
732#[tracable_parser]
733#[packrat_parser]
734pub(crate) fn select_condition(s: Span) -> IResult<Span, SelectCondition> {
735    let (s, a) = keyword("binsof")(s)?;
736    let (s, b) = paren(bins_expression)(s)?;
737    let (s, c) = opt(pair(keyword("intersect"), brace(covergroup_range_list)))(s)?;
738    Ok((s, SelectCondition { nodes: (a, b, c) }))
739}
740
741#[tracable_parser]
742#[packrat_parser]
743pub(crate) fn bins_expression(s: Span) -> IResult<Span, BinsExpression> {
744    alt((
745        bins_expression_cover_point,
746        map(variable_identifier, |x| {
747            BinsExpression::VariableIdentifier(Box::new(x))
748        }),
749    ))(s)
750}
751
752#[tracable_parser]
753#[packrat_parser]
754pub(crate) fn bins_expression_cover_point(s: Span) -> IResult<Span, BinsExpression> {
755    let (s, a) = cover_point_identifier(s)?;
756    let (s, b) = opt(pair(symbol("."), bin_identifier))(s)?;
757    Ok((
758        s,
759        BinsExpression::CoverPoint(Box::new(BinsExpressionCoverPoint { nodes: (a, b) })),
760    ))
761}
762
763#[recursive_parser]
764#[tracable_parser]
765#[packrat_parser]
766pub(crate) fn covergroup_range_list(s: Span) -> IResult<Span, CovergroupRangeList> {
767    let (s, a) = list(symbol(","), covergroup_value_range)(s)?;
768    Ok((s, CovergroupRangeList { nodes: (a,) }))
769}
770
771#[tracable_parser]
772#[packrat_parser]
773pub(crate) fn covergroup_value_range(s: Span) -> IResult<Span, CovergroupValueRange> {
774    alt((
775        map(covergroup_expression, |x| {
776            CovergroupValueRange::CovergroupExpression(Box::new(x))
777        }),
778        covergroup_value_range_binary,
779    ))(s)
780}
781
782#[tracable_parser]
783#[packrat_parser]
784pub(crate) fn covergroup_value_range_binary(s: Span) -> IResult<Span, CovergroupValueRange> {
785    let (s, a) = bracket(triple(
786        covergroup_expression,
787        symbol(":"),
788        covergroup_expression,
789    ))(s)?;
790    Ok((
791        s,
792        CovergroupValueRange::Binary(Box::new(CovergroupValueRangeBinary { nodes: (a,) })),
793    ))
794}
795
796#[tracable_parser]
797#[packrat_parser]
798pub(crate) fn with_covergroup_expression(s: Span) -> IResult<Span, WithCovergroupExpression> {
799    let (s, a) = covergroup_expression(s)?;
800    Ok((s, WithCovergroupExpression { nodes: (a,) }))
801}
802
803#[tracable_parser]
804#[packrat_parser]
805pub(crate) fn set_covergroup_expression(s: Span) -> IResult<Span, SetCovergroupExpression> {
806    let (s, a) = covergroup_expression(s)?;
807    Ok((s, SetCovergroupExpression { nodes: (a,) }))
808}
809
810#[tracable_parser]
811#[packrat_parser]
812pub(crate) fn integer_covergroup_expression(s: Span) -> IResult<Span, IntegerCovergroupExpression> {
813    let (s, a) = covergroup_expression(s)?;
814    Ok((s, IntegerCovergroupExpression { nodes: (a,) }))
815}
816
817#[tracable_parser]
818#[packrat_parser]
819pub(crate) fn cross_set_expression(s: Span) -> IResult<Span, CrossSetExpression> {
820    let (s, a) = covergroup_expression(s)?;
821    Ok((s, CrossSetExpression { nodes: (a,) }))
822}
823
824#[tracable_parser]
825#[packrat_parser]
826pub(crate) fn covergroup_expression(s: Span) -> IResult<Span, CovergroupExpression> {
827    let (s, a) = expression(s)?;
828    Ok((s, CovergroupExpression { nodes: (a,) }))
829}