step_p21/parser/exchange/
data.rs1use crate::{
2 ast::*,
3 parser::{combinator::*, exchange::*, token::*},
4};
5use nom::{Parser, branch::alt};
6
7pub fn data_section(input: &str) -> ParseResult<'_, DataSection> {
10 tuple_((
11 tag_("DATA"),
12 opt_(tuple_((char_('('), parameter_list, char_(')')))),
13 char_(';'),
14 entity_instance_list,
15 tag_("ENDSEC;"),
16 ))
17 .map(|(_start, meta, _semicolon, entities, _end)| DataSection {
18 meta: meta
19 .map(|(_open, params, _close)| params)
20 .unwrap_or_default(),
21 entities,
22 })
23 .parse(input)
24}
25
26pub fn entity_instance_list(
28 input: &str,
29) -> ParseResult<'_, Vec<EntityInstance>> {
30 many0_(entity_instance).parse(input)
31}
32
33pub fn entity_instance(input: &str) -> ParseResult<'_, EntityInstance> {
35 alt((simple_entity_instance, complex_entity_instance)).parse(input)
36}
37
38pub fn simple_entity_instance(input: &str) -> ParseResult<'_, EntityInstance> {
40 tuple_((entity_instance_name, char_('='), simple_record, char_(';')))
41 .map(|(id, _eq, record, _semicolon)| EntityInstance::Simple {
42 id,
43 record,
44 })
45 .parse(input)
46}
47
48pub fn complex_entity_instance(input: &str) -> ParseResult<'_, EntityInstance> {
50 tuple_((
51 entity_instance_name,
52 char_('='),
53 subsuper_record,
54 char_(';'),
55 ))
56 .map(|(id, _eq, subsuper, _semicolon)| EntityInstance::Complex {
57 id,
58 subsuper,
59 })
60 .parse(input)
61}
62
63pub fn simple_record(input: &str) -> ParseResult<'_, Record> {
65 tuple_((keyword, char_('('), opt_(parameter_list), char_(')')))
66 .map(|(name, _open, parameter, _close)| Record {
67 name,
68 parameter: parameter.unwrap_or_default().into_iter().collect(),
69 })
70 .parse(input)
71}
72
73pub fn simple_record_list(input: &str) -> ParseResult<'_, Vec<Record>> {
75 many0_(simple_record).parse(input)
76}
77
78pub fn subsuper_record(input: &str) -> ParseResult<'_, SubSuperRecord> {
80 tuple_((char_('('), simple_record_list, char_(')')))
81 .map(|(_open, records, _close)| SubSuperRecord(records))
82 .parse(input)
83}
84
85#[cfg(test)]
86mod tests {
87 use nom::Finish;
88
89 #[test]
90 fn simple_recode1() {
91 let (res, record) = super::simple_record("A(1, 2.0)").finish().unwrap();
92 dbg!(record);
93 assert_eq!(res, "");
94 }
95
96 #[test]
97 fn simple_recode2() {
98 let (res, record) = super::simple_record(
99 "LENGTH_MEASURE_WITH_UNIT( LENGTH_MEASURE( 1.00000000000000 ), #359 )",
100 )
101 .finish()
102 .unwrap();
103 dbg!(record);
104 assert_eq!(res, "");
105 }
106}