sv_parser_parser/source_text/
system_verilog_source_text.rs

1use crate::*;
2
3// -----------------------------------------------------------------------------
4
5#[tracable_parser]
6#[packrat_parser]
7pub(crate) fn source_text(s: Span) -> IResult<Span, SourceText> {
8    let (s, a) = many0(white_space)(s)?;
9    let (s, b) = opt(timeunits_declaration)(s)?;
10    let (s, (c, _)) = many_till(description, eof)(s)?;
11    Ok((s, SourceText { nodes: (a, b, c) }))
12}
13
14#[tracable_parser]
15#[packrat_parser]
16pub(crate) fn source_text_incomplete(s: Span) -> IResult<Span, SourceText> {
17    let (s, a) = many0(white_space)(s)?;
18    let (s, b) = opt(timeunits_declaration)(s)?;
19    let (s, c) = many0(description)(s)?;
20    Ok((s, SourceText { nodes: (a, b, c) }))
21}
22
23#[tracable_parser]
24#[packrat_parser]
25pub(crate) fn description(s: Span) -> IResult<Span, Description> {
26    alt((
27        map(resetall_compiler_directive, |x| {
28            Description::ResetallCompilerDirective(Box::new(x))
29        }),
30        map(module_declaration, |x| {
31            Description::ModuleDeclaration(Box::new(x))
32        }),
33        map(udp_declaration, |x| {
34            Description::UdpDeclaration(Box::new(x))
35        }),
36        map(interface_declaration, |x| {
37            Description::InterfaceDeclaration(Box::new(x))
38        }),
39        map(interface_class_declaration, |x| {
40            Description::InterfaceClassDeclaration(Box::new(x))
41        }),
42        map(program_declaration, |x| {
43            Description::ProgramDeclaration(Box::new(x))
44        }),
45        map(package_declaration, |x| {
46            Description::PackageDeclaration(Box::new(x))
47        }),
48        description_package_item,
49        description_bind_directive,
50        map(config_declaration, |x| {
51            Description::ConfigDeclaration(Box::new(x))
52        }),
53    ))(s)
54}
55
56#[recursive_parser]
57#[tracable_parser]
58#[packrat_parser]
59pub(crate) fn description_package_item(s: Span) -> IResult<Span, Description> {
60    let (s, a) = many0(attribute_instance)(s)?;
61    let (s, b) = package_item(s)?;
62    Ok((
63        s,
64        Description::PackageItem(Box::new(DescriptionPackageItem { nodes: (a, b) })),
65    ))
66}
67
68#[tracable_parser]
69#[packrat_parser]
70pub(crate) fn description_bind_directive(s: Span) -> IResult<Span, Description> {
71    let (s, a) = many0(attribute_instance)(s)?;
72    let (s, b) = bind_directive(s)?;
73    Ok((
74        s,
75        Description::BindDirective(Box::new(DescriptionBindDirective { nodes: (a, b) })),
76    ))
77}
78
79#[tracable_parser]
80#[packrat_parser]
81pub(crate) fn module_nonansi_header(s: Span) -> IResult<Span, ModuleNonansiHeader> {
82    let (s, (a, b)) = many_till(attribute_instance, module_keyword)(s)?;
83    let (s, c) = opt(lifetime)(s)?;
84    let (s, d) = module_identifier(s)?;
85    let (s, e) = many0(package_import_declaration)(s)?;
86    let (s, f) = opt(parameter_port_list)(s)?;
87    let (s, g) = list_of_ports(s)?;
88    let (s, h) = symbol(";")(s)?;
89    Ok((
90        s,
91        ModuleNonansiHeader {
92            nodes: (a, b, c, d, e, f, g, h),
93        },
94    ))
95}
96
97#[tracable_parser]
98#[packrat_parser]
99pub(crate) fn module_ansi_header(s: Span) -> IResult<Span, ModuleAnsiHeader> {
100    let (s, (a, b)) = many_till(attribute_instance, module_keyword)(s)?;
101    let (s, c) = opt(lifetime)(s)?;
102    let (s, d) = module_identifier(s)?;
103    let (s, e) = many0(package_import_declaration)(s)?;
104    let (s, f) = opt(parameter_port_list)(s)?;
105    let (s, g) = opt(list_of_port_declarations)(s)?;
106    let (s, h) = symbol(";")(s)?;
107    Ok((
108        s,
109        ModuleAnsiHeader {
110            nodes: (a, b, c, d, e, f, g, h),
111        },
112    ))
113}
114
115#[tracable_parser]
116#[packrat_parser]
117pub(crate) fn module_declaration(s: Span) -> IResult<Span, ModuleDeclaration> {
118    alt((
119        module_declaration_ansi,
120        module_declaration_nonansi,
121        module_declaration_wildcard,
122        module_declaration_extern_ansi,
123        module_declaration_extern_nonansi,
124    ))(s)
125}
126
127#[tracable_parser]
128#[packrat_parser]
129pub(crate) fn module_declaration_nonansi(s: Span) -> IResult<Span, ModuleDeclaration> {
130    let (s, a) = module_nonansi_header(s)?;
131    let (s, b) = opt(timeunits_declaration)(s)?;
132    let (s, (c, d)) = many_till(module_item, keyword("endmodule"))(s)?;
133    let (s, e) = opt(pair(symbol(":"), module_identifier))(s)?;
134    Ok((
135        s,
136        ModuleDeclaration::Nonansi(Box::new(ModuleDeclarationNonansi {
137            nodes: (a, b, c, d, e),
138        })),
139    ))
140}
141
142#[tracable_parser]
143#[packrat_parser]
144pub(crate) fn module_declaration_ansi(s: Span) -> IResult<Span, ModuleDeclaration> {
145    let (s, a) = module_ansi_header(s)?;
146    let (s, b) = opt(timeunits_declaration)(s)?;
147    let (s, (c, d)) = many_till(non_port_module_item, keyword("endmodule"))(s)?;
148    let (s, e) = opt(pair(symbol(":"), module_identifier))(s)?;
149    Ok((
150        s,
151        ModuleDeclaration::Ansi(Box::new(ModuleDeclarationAnsi {
152            nodes: (a, b, c, d, e),
153        })),
154    ))
155}
156
157#[tracable_parser]
158#[packrat_parser]
159pub(crate) fn module_declaration_wildcard(s: Span) -> IResult<Span, ModuleDeclaration> {
160    let (s, (a, b)) = many_till(attribute_instance, module_keyword)(s)?;
161    let (s, c) = opt(lifetime)(s)?;
162    let (s, d) = module_identifier(s)?;
163    let (s, e) = paren(symbol(".*"))(s)?;
164    let (s, f) = symbol(";")(s)?;
165    let (s, g) = opt(timeunits_declaration)(s)?;
166    let (s, (h, i)) = many_till(module_item, keyword("endmodule"))(s)?;
167    let (s, j) = opt(pair(symbol(":"), module_identifier))(s)?;
168    Ok((
169        s,
170        ModuleDeclaration::Wildcard(Box::new(ModuleDeclarationWildcard {
171            nodes: (a, b, c, d, e, f, g, h, i, j),
172        })),
173    ))
174}
175
176#[tracable_parser]
177#[packrat_parser]
178pub(crate) fn module_declaration_extern_nonansi(s: Span) -> IResult<Span, ModuleDeclaration> {
179    let (s, a) = keyword("extern")(s)?;
180    let (s, b) = module_nonansi_header(s)?;
181    Ok((
182        s,
183        ModuleDeclaration::ExternNonansi(Box::new(ModuleDeclarationExternNonansi {
184            nodes: (a, b),
185        })),
186    ))
187}
188
189#[tracable_parser]
190#[packrat_parser]
191pub(crate) fn module_declaration_extern_ansi(s: Span) -> IResult<Span, ModuleDeclaration> {
192    let (s, a) = keyword("extern")(s)?;
193    let (s, b) = module_ansi_header(s)?;
194    Ok((
195        s,
196        ModuleDeclaration::ExternAnsi(Box::new(ModuleDeclarationExternAnsi { nodes: (a, b) })),
197    ))
198}
199
200#[tracable_parser]
201#[packrat_parser]
202pub(crate) fn module_keyword(s: Span) -> IResult<Span, ModuleKeyword> {
203    alt((
204        map(keyword("module"), |x| ModuleKeyword::Module(Box::new(x))),
205        map(keyword("macromodule"), |x| {
206            ModuleKeyword::Macromodule(Box::new(x))
207        }),
208    ))(s)
209}
210
211#[tracable_parser]
212#[packrat_parser]
213pub(crate) fn interface_declaration(s: Span) -> IResult<Span, InterfaceDeclaration> {
214    alt((
215        interface_declaration_ansi,
216        interface_declaration_nonansi,
217        interface_declaration_wildcard,
218        interface_declaration_extern_ansi,
219        interface_declaration_extern_nonansi,
220    ))(s)
221}
222
223#[tracable_parser]
224#[packrat_parser]
225pub(crate) fn interface_declaration_nonansi(s: Span) -> IResult<Span, InterfaceDeclaration> {
226    let (s, a) = interface_nonansi_header(s)?;
227    let (s, b) = opt(timeunits_declaration)(s)?;
228    let (s, (c, d)) = many_till(interface_item, keyword("endinterface"))(s)?;
229    let (s, e) = opt(pair(symbol(":"), interface_identifier))(s)?;
230    Ok((
231        s,
232        InterfaceDeclaration::Nonansi(Box::new(InterfaceDeclarationNonansi {
233            nodes: (a, b, c, d, e),
234        })),
235    ))
236}
237
238#[tracable_parser]
239#[packrat_parser]
240pub(crate) fn interface_declaration_ansi(s: Span) -> IResult<Span, InterfaceDeclaration> {
241    let (s, a) = interface_ansi_header(s)?;
242    let (s, b) = opt(timeunits_declaration)(s)?;
243    let (s, (c, d)) = many_till(non_port_interface_item, keyword("endinterface"))(s)?;
244    let (s, e) = opt(pair(symbol(":"), interface_identifier))(s)?;
245    Ok((
246        s,
247        InterfaceDeclaration::Ansi(Box::new(InterfaceDeclarationAnsi {
248            nodes: (a, b, c, d, e),
249        })),
250    ))
251}
252
253#[tracable_parser]
254#[packrat_parser]
255pub(crate) fn interface_declaration_wildcard(s: Span) -> IResult<Span, InterfaceDeclaration> {
256    let (s, (a, b)) = many_till(attribute_instance, keyword("interface"))(s)?;
257    let (s, c) = opt(lifetime)(s)?;
258    let (s, d) = interface_identifier(s)?;
259    let (s, e) = paren(symbol(".*"))(s)?;
260    let (s, f) = symbol(";")(s)?;
261    let (s, g) = opt(timeunits_declaration)(s)?;
262    let (s, (h, i)) = many_till(interface_item, keyword("endinterface"))(s)?;
263    let (s, j) = opt(pair(symbol(":"), interface_identifier))(s)?;
264    Ok((
265        s,
266        InterfaceDeclaration::Wildcard(Box::new(InterfaceDeclarationWildcard {
267            nodes: (a, b, c, d, e, f, g, h, i, j),
268        })),
269    ))
270}
271
272#[tracable_parser]
273#[packrat_parser]
274pub(crate) fn interface_declaration_extern_nonansi(s: Span) -> IResult<Span, InterfaceDeclaration> {
275    let (s, a) = keyword("extern")(s)?;
276    let (s, b) = interface_nonansi_header(s)?;
277    Ok((
278        s,
279        InterfaceDeclaration::ExternNonansi(Box::new(InterfaceDeclarationExternNonansi {
280            nodes: (a, b),
281        })),
282    ))
283}
284
285#[tracable_parser]
286#[packrat_parser]
287pub(crate) fn interface_declaration_extern_ansi(s: Span) -> IResult<Span, InterfaceDeclaration> {
288    let (s, a) = keyword("extern")(s)?;
289    let (s, b) = interface_ansi_header(s)?;
290    Ok((
291        s,
292        InterfaceDeclaration::ExternAnsi(Box::new(InterfaceDeclarationExternAnsi {
293            nodes: (a, b),
294        })),
295    ))
296}
297
298#[tracable_parser]
299#[packrat_parser]
300pub(crate) fn interface_nonansi_header(s: Span) -> IResult<Span, InterfaceNonansiHeader> {
301    let (s, (a, b)) = many_till(attribute_instance, keyword("interface"))(s)?;
302    let (s, c) = opt(lifetime)(s)?;
303    let (s, d) = interface_identifier(s)?;
304    let (s, e) = many0(package_import_declaration)(s)?;
305    let (s, f) = opt(parameter_port_list)(s)?;
306    let (s, g) = list_of_ports(s)?;
307    let (s, h) = symbol(";")(s)?;
308    Ok((
309        s,
310        InterfaceNonansiHeader {
311            nodes: (a, b, c, d, e, f, g, h),
312        },
313    ))
314}
315
316#[tracable_parser]
317#[packrat_parser]
318pub(crate) fn interface_ansi_header(s: Span) -> IResult<Span, InterfaceAnsiHeader> {
319    let (s, (a, b)) = many_till(attribute_instance, keyword("interface"))(s)?;
320    let (s, c) = opt(lifetime)(s)?;
321    let (s, d) = interface_identifier(s)?;
322    let (s, e) = many0(package_import_declaration)(s)?;
323    let (s, f) = opt(parameter_port_list)(s)?;
324    let (s, g) = opt(list_of_port_declarations)(s)?;
325    let (s, h) = symbol(";")(s)?;
326    Ok((
327        s,
328        InterfaceAnsiHeader {
329            nodes: (a, b, c, d, e, f, g, h),
330        },
331    ))
332}
333
334#[tracable_parser]
335#[packrat_parser]
336pub(crate) fn program_declaration(s: Span) -> IResult<Span, ProgramDeclaration> {
337    alt((
338        program_declaration_ansi,
339        program_declaration_nonansi,
340        program_declaration_wildcard,
341        program_declaration_extern_ansi,
342        program_declaration_extern_nonansi,
343    ))(s)
344}
345
346#[tracable_parser]
347#[packrat_parser]
348pub(crate) fn program_declaration_nonansi(s: Span) -> IResult<Span, ProgramDeclaration> {
349    let (s, a) = program_nonansi_header(s)?;
350    let (s, b) = opt(timeunits_declaration)(s)?;
351    let (s, (c, d)) = many_till(program_item, keyword("endprogram"))(s)?;
352    let (s, e) = opt(pair(symbol(":"), program_identifier))(s)?;
353    Ok((
354        s,
355        ProgramDeclaration::Nonansi(Box::new(ProgramDeclarationNonansi {
356            nodes: (a, b, c, d, e),
357        })),
358    ))
359}
360
361#[tracable_parser]
362#[packrat_parser]
363pub(crate) fn program_declaration_ansi(s: Span) -> IResult<Span, ProgramDeclaration> {
364    let (s, a) = program_ansi_header(s)?;
365    let (s, b) = opt(timeunits_declaration)(s)?;
366    let (s, (c, d)) = many_till(non_port_program_item, keyword("endprogram"))(s)?;
367    let (s, e) = opt(pair(symbol(":"), program_identifier))(s)?;
368    Ok((
369        s,
370        ProgramDeclaration::Ansi(Box::new(ProgramDeclarationAnsi {
371            nodes: (a, b, c, d, e),
372        })),
373    ))
374}
375
376#[tracable_parser]
377#[packrat_parser]
378pub(crate) fn program_declaration_wildcard(s: Span) -> IResult<Span, ProgramDeclaration> {
379    let (s, (a, b)) = many_till(attribute_instance, keyword("program"))(s)?;
380    let (s, c) = program_identifier(s)?;
381    let (s, d) = paren(symbol(".*"))(s)?;
382    let (s, e) = symbol(";")(s)?;
383    let (s, f) = opt(timeunits_declaration)(s)?;
384    let (s, (g, h)) = many_till(program_item, keyword("endprogram"))(s)?;
385    let (s, i) = opt(pair(symbol(":"), program_identifier))(s)?;
386    Ok((
387        s,
388        ProgramDeclaration::Wildcard(Box::new(ProgramDeclarationWildcard {
389            nodes: (a, b, c, d, e, f, g, h, i),
390        })),
391    ))
392}
393
394#[tracable_parser]
395#[packrat_parser]
396pub(crate) fn program_declaration_extern_nonansi(s: Span) -> IResult<Span, ProgramDeclaration> {
397    let (s, a) = keyword("extern")(s)?;
398    let (s, b) = program_nonansi_header(s)?;
399    Ok((
400        s,
401        ProgramDeclaration::ExternNonansi(Box::new(ProgramDeclarationExternNonansi {
402            nodes: (a, b),
403        })),
404    ))
405}
406
407#[tracable_parser]
408#[packrat_parser]
409pub(crate) fn program_declaration_extern_ansi(s: Span) -> IResult<Span, ProgramDeclaration> {
410    let (s, a) = keyword("extern")(s)?;
411    let (s, b) = program_ansi_header(s)?;
412    Ok((
413        s,
414        ProgramDeclaration::ExternAnsi(Box::new(ProgramDeclarationExternAnsi { nodes: (a, b) })),
415    ))
416}
417
418#[tracable_parser]
419#[packrat_parser]
420pub(crate) fn program_nonansi_header(s: Span) -> IResult<Span, ProgramNonansiHeader> {
421    let (s, (a, b)) = many_till(attribute_instance, keyword("prgogram"))(s)?;
422    let (s, c) = opt(lifetime)(s)?;
423    let (s, d) = program_identifier(s)?;
424    let (s, e) = many0(package_import_declaration)(s)?;
425    let (s, f) = opt(parameter_port_list)(s)?;
426    let (s, g) = list_of_ports(s)?;
427    let (s, h) = symbol(";")(s)?;
428    Ok((
429        s,
430        ProgramNonansiHeader {
431            nodes: (a, b, c, d, e, f, g, h),
432        },
433    ))
434}
435
436#[tracable_parser]
437#[packrat_parser]
438pub(crate) fn program_ansi_header(s: Span) -> IResult<Span, ProgramAnsiHeader> {
439    let (s, (a, b)) = many_till(attribute_instance, keyword("program"))(s)?;
440    let (s, c) = opt(lifetime)(s)?;
441    let (s, d) = program_identifier(s)?;
442    let (s, e) = many0(package_import_declaration)(s)?;
443    let (s, f) = opt(parameter_port_list)(s)?;
444    let (s, g) = opt(list_of_port_declarations)(s)?;
445    let (s, h) = symbol(";")(s)?;
446    Ok((
447        s,
448        ProgramAnsiHeader {
449            nodes: (a, b, c, d, e, f, g, h),
450        },
451    ))
452}
453
454#[tracable_parser]
455#[packrat_parser]
456pub(crate) fn checker_declaration(s: Span) -> IResult<Span, CheckerDeclaration> {
457    let (s, a) = keyword("checker")(s)?;
458    let (s, b) = checker_identifier(s)?;
459    let (s, c) = opt(paren(opt(checker_port_list)))(s)?;
460    let (s, d) = symbol(";")(s)?;
461    let (s, (e, f)) = many_till(
462        pair(many0(attribute_instance), checker_or_generate_item),
463        keyword("endchecker"),
464    )(s)?;
465    let (s, g) = opt(pair(symbol(":"), checker_identifier))(s)?;
466    Ok((
467        s,
468        CheckerDeclaration {
469            nodes: (a, b, c, d, e, f, g),
470        },
471    ))
472}
473
474#[tracable_parser]
475#[packrat_parser]
476pub(crate) fn class_declaration(s: Span) -> IResult<Span, ClassDeclaration> {
477    let (s, a) = opt(map(keyword("virtual"), |x| Virtual { nodes: (x,) }))(s)?;
478    let (s, b) = keyword("class")(s)?;
479    let (s, c) = opt(lifetime)(s)?;
480    let (s, d) = class_identifier(s)?;
481    let (s, e) = opt(parameter_port_list)(s)?;
482    let (s, f) = opt(triple(
483        keyword("extends"),
484        class_type,
485        opt(paren(list_of_arguments)),
486    ))(s)?;
487    let (s, g) = opt(pair(
488        keyword("implements"),
489        list(symbol(","), interface_class_type),
490    ))(s)?;
491    let (s, h) = symbol(";")(s)?;
492    let (s, (i, j)) = many_till(class_item, keyword("endclass"))(s)?;
493    let (s, k) = opt(pair(symbol(":"), class_identifier))(s)?;
494    Ok((
495        s,
496        ClassDeclaration {
497            nodes: (a, b, c, d, e, f, g, h, i, j, k),
498        },
499    ))
500}
501
502#[tracable_parser]
503#[packrat_parser]
504pub(crate) fn interface_class_type(s: Span) -> IResult<Span, InterfaceClassType> {
505    let (s, a) = ps_class_identifier(s)?;
506    let (s, b) = opt(parameter_value_assignment)(s)?;
507    Ok((s, InterfaceClassType { nodes: (a, b) }))
508}
509
510#[tracable_parser]
511#[packrat_parser]
512pub(crate) fn interface_class_declaration(s: Span) -> IResult<Span, InterfaceClassDeclaration> {
513    let (s, a) = keyword("interface")(s)?;
514    let (s, b) = keyword("class")(s)?;
515    let (s, c) = class_identifier(s)?;
516    let (s, d) = opt(parameter_port_list)(s)?;
517    let (s, e) = opt(pair(
518        keyword("extends"),
519        list(symbol(","), interface_class_type),
520    ))(s)?;
521    let (s, f) = symbol(";")(s)?;
522    let (s, (g, h)) = many_till(interface_class_item, keyword("endclass"))(s)?;
523    let (s, i) = opt(pair(symbol(":"), class_identifier))(s)?;
524    Ok((
525        s,
526        InterfaceClassDeclaration {
527            nodes: (a, b, c, d, e, f, g, h, i),
528        },
529    ))
530}
531
532#[tracable_parser]
533#[packrat_parser]
534pub(crate) fn interface_class_item(s: Span) -> IResult<Span, InterfaceClassItem> {
535    alt((
536        map(type_declaration, |x| {
537            InterfaceClassItem::TypeDeclaration(Box::new(x))
538        }),
539        interface_class_item_method,
540        map(pair(local_parameter_declaration, symbol(";")), |x| {
541            InterfaceClassItem::LocalParameterDeclaration(Box::new(x))
542        }),
543        map(pair(parameter_declaration, symbol(";")), |x| {
544            InterfaceClassItem::ParameterDeclaration(Box::new(x))
545        }),
546        map(symbol(";"), |x| InterfaceClassItem::Null(Box::new(x))),
547    ))(s)
548}
549
550#[tracable_parser]
551#[packrat_parser]
552pub(crate) fn interface_class_item_method(s: Span) -> IResult<Span, InterfaceClassItem> {
553    let (s, a) = many0(attribute_instance)(s)?;
554    let (s, b) = interface_class_method(s)?;
555    Ok((
556        s,
557        InterfaceClassItem::Method(Box::new(InterfaceClassItemMethod { nodes: (a, b) })),
558    ))
559}
560
561#[tracable_parser]
562#[packrat_parser]
563pub(crate) fn interface_class_method(s: Span) -> IResult<Span, InterfaceClassMethod> {
564    let (s, a) = keyword("pure")(s)?;
565    let (s, b) = keyword("virtual")(s)?;
566    let (s, c) = method_prototype(s)?;
567    let (s, d) = symbol(";")(s)?;
568    Ok((
569        s,
570        InterfaceClassMethod {
571            nodes: (a, b, c, d),
572        },
573    ))
574}
575
576#[tracable_parser]
577#[packrat_parser]
578pub(crate) fn package_declaration(s: Span) -> IResult<Span, PackageDeclaration> {
579    let (s, (a, b)) = many_till(attribute_instance, keyword("package"))(s)?;
580    let (s, c) = opt(lifetime)(s)?;
581    let (s, d) = package_identifier(s)?;
582    let (s, e) = symbol(";")(s)?;
583    let (s, f) = opt(timeunits_declaration)(s)?;
584    let (s, (g, h)) = many_till(
585        pair(many0(attribute_instance), package_item),
586        keyword("endpackage"),
587    )(s)?;
588    let (s, i) = opt(pair(symbol(":"), package_identifier))(s)?;
589    Ok((
590        s,
591        PackageDeclaration {
592            nodes: (a, b, c, d, e, f, g, h, i),
593        },
594    ))
595}
596
597#[tracable_parser]
598#[packrat_parser]
599pub(crate) fn timeunits_declaration(s: Span) -> IResult<Span, TimeunitsDeclaration> {
600    alt((
601        timeunits_declaration_timeunit_timeprecision,
602        timeunits_declaration_timeunit,
603        timeunits_declaration_timeprecision_timeunit,
604        timeunits_declaration_timeprecision,
605    ))(s)
606}
607
608#[tracable_parser]
609#[packrat_parser]
610pub(crate) fn timeunits_declaration_timeunit(s: Span) -> IResult<Span, TimeunitsDeclaration> {
611    let (s, a) = keyword("timeunit")(s)?;
612    let (s, b) = time_literal(s)?;
613    let (s, c) = opt(pair(symbol("/"), time_literal))(s)?;
614    let (s, d) = symbol(";")(s)?;
615    Ok((
616        s,
617        TimeunitsDeclaration::Timeunit(Box::new(TimeunitsDeclarationTimeunit {
618            nodes: (a, b, c, d),
619        })),
620    ))
621}
622
623#[tracable_parser]
624#[packrat_parser]
625pub(crate) fn timeunits_declaration_timeprecision(s: Span) -> IResult<Span, TimeunitsDeclaration> {
626    let (s, a) = keyword("timeprecision")(s)?;
627    let (s, b) = time_literal(s)?;
628    let (s, c) = symbol(";")(s)?;
629    Ok((
630        s,
631        TimeunitsDeclaration::Timeprecision(Box::new(TimeunitsDeclarationTimeprecision {
632            nodes: (a, b, c),
633        })),
634    ))
635}
636
637#[tracable_parser]
638#[packrat_parser]
639pub(crate) fn timeunits_declaration_timeunit_timeprecision(
640    s: Span,
641) -> IResult<Span, TimeunitsDeclaration> {
642    let (s, a) = keyword("timeunit")(s)?;
643    let (s, b) = time_literal(s)?;
644    let (s, c) = symbol(";")(s)?;
645    let (s, d) = keyword("timeprecision")(s)?;
646    let (s, e) = time_literal(s)?;
647    let (s, f) = symbol(";")(s)?;
648    Ok((
649        s,
650        TimeunitsDeclaration::TimeunitTimeprecision(Box::new(
651            TimeunitsDeclarationTimeunitTimeprecision {
652                nodes: (a, b, c, d, e, f),
653            },
654        )),
655    ))
656}
657
658#[tracable_parser]
659#[packrat_parser]
660pub(crate) fn timeunits_declaration_timeprecision_timeunit(
661    s: Span,
662) -> IResult<Span, TimeunitsDeclaration> {
663    let (s, a) = keyword("timeprecision")(s)?;
664    let (s, b) = time_literal(s)?;
665    let (s, c) = symbol(";")(s)?;
666    let (s, d) = keyword("timeunit")(s)?;
667    let (s, e) = time_literal(s)?;
668    let (s, f) = symbol(";")(s)?;
669    Ok((
670        s,
671        TimeunitsDeclaration::TimeprecisionTimeunit(Box::new(
672            TimeunitsDeclarationTimeprecisionTimeunit {
673                nodes: (a, b, c, d, e, f),
674            },
675        )),
676    ))
677}