parser_pda/
parser_pda.rs

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