1
2use crate::defs::{ SegmentDelimSyms::*, SegmentTypes,
3 ParserCtx, PDAStackCtx, ParsedSegment };
4
5
6fsm!( LittleParser<ParserCtx, PDAStackCtx> [
7 Idle on Start
8 => NewSentence on LeftBracket => PlainSegment,
9
10 NewSentence on RightBracket => InvalidSegment,
11 NewSentence on Letter(char)
12 => PlainSegment on LeftBracket
13 => PlainSegment on RightBracket peek_cmp Bracket
14 => PlainSegment on RightBracket => InvalidSegment,
15
16 PlainSegment on EndOfSentence peek_cmp SentenceStart => NewSentence,
17 PlainSegment on EndOfSentence peek_cmp SegmentStart => NewSentence,
18 _ on EndOfSentence => NewSentence,
19 _ on EndOfInput peek_cmp SentenceStart => Idle,
20 _ on EndOfInput => Idle,
21],
22[
23 Idle entry, NewSentence exit
24]);
25
26
27on_state_handler!( Idle entry for LittleParser {
28 data.index = 0;
29});
30on_state_handler!( NewSentence exit for LittleParser {
31 stack.push(PDAStackCtx { sym: SentenceStart, seg_start: data.index} );
32});
33
34transition_handler!( Idle on Start for LittleParser {
35});
36
37transition_handler!( NewSentence on Letter(char) for LittleParser {
38});
39
40transition_handler!( NewSentence on LeftBracket for LittleParser {
41 stack.push(PDAStackCtx { sym: Bracket, seg_start: data.index } );
42});
43
44transition_handler!( NewSentence on RightBracket for LittleParser {
45});
46
47transition_handler!( PlainSegment on LeftBracket for LittleParser {
48 let top = stack.last().unwrap();
49 if top.sym == SegmentStart || top.sym == SentenceStart {
50 data.segments.push(ParsedSegment {
51 tp: SegmentTypes::Plain,
52 seg: (top.seg_start, data.index),
53 rank: stack.len(),
54 });
55 }
56 stack.push(PDAStackCtx { sym: Bracket, seg_start: data.index} );
57});
58
59transition_handler!(PlainSegment on RightBracket peek_cmp Bracket for LittleParser {
60 let top = stack.pop().unwrap();
61 data.segments.push(ParsedSegment {
62 tp: SegmentTypes::Bracketed,
63 seg: (top.seg_start + 1, data.index),
64 rank: stack.len(),
65 });
66});
67
68transition_handler!(PlainSegment on RightBracket for LittleParser {
69 let top = stack.last().unwrap();
70 data.segments.push(ParsedSegment {
71 tp: SegmentTypes::Plain,
72 seg: (top.seg_start, data.index),
73 rank: stack.len(),
74 });
75 stack.push(PDAStackCtx { sym: SegmentStart, seg_start: data.index } );
76});
77
78transition_handler!(PlainSegment on EndOfSentence peek_cmp SentenceStart for LittleParser {
79 let top = stack.pop().unwrap();
80 data.segments.push(ParsedSegment {
81 tp: SegmentTypes::Sentence,
82 seg: (top.seg_start, data.index),
83 rank: stack.len(),
84 });
85});
86
87transition_handler!(PlainSegment on EndOfSentence peek_cmp SegmentStart for LittleParser {
88 let top = stack.pop().unwrap();
89 data.segments.push(ParsedSegment {
90 tp: SegmentTypes::Plain,
91 seg: (top.seg_start, data.index),
92 rank: stack.len(),
93 });
94});
95
96transition_handler!(_ on EndOfSentence for LittleParser {
97 Self::drain_unbalanced(data, stack);
98});
99
100transition_handler!( _ on EndOfInput peek_cmp SentenceStart for LittleParser {
101 data.segments.push(ParsedSegment {
102 tp: SegmentTypes::Tail,
103 seg: (stack.pop().unwrap().seg_start, data.index),
104 rank: stack.len(),
105 });
106});
107
108transition_handler!( _ on EndOfInput for LittleParser {
109 Self::drain_unbalanced(data, stack);
110});
111
112transition_handler!( NewSentence on EndOfSentence for LittleParser {
113});
114
115impl LittleParser {
116 pub fn start(&mut self) {
117 self.signal(&Start);
118 }
119 pub fn next(&mut self, signal: &LittleParserSignals) {
120 self.signal(signal);
121 self.data.index += 1;
122 }
123 pub fn stop(&mut self) {
124 self.signal(&EndOfInput);
125 }
126
127 fn drain_unbalanced(
128 data: &mut <Self as LittleParserTrait>::DataItem,
129 stack: &mut Vec<<Self as LittleParserTrait>::StackSymbolItem>,
130 ) {
131 while let Some(top) = stack.pop() {
132 let tp =
133 if Bracket == top { SegmentTypes::UnbalancedLeftBracket }
134 else if SegmentStart == top { SegmentTypes::UnbalancedRightSth}
135 else if SentenceStart == top { SegmentTypes::InvalidSentence}
136 else {
137 unimplemented!();
138 };
139 data.segments.push(ParsedSegment {
140 tp,
141 seg: (top.seg_start, data.index),
142 rank: stack.len(),
143 });
144 }
145 }
146}
147
148
149
150