rustemo/lr/
context.rs

1use std::ops::Range;
2
3use crate::{context::Context, input::Input, lexer::Token, location::Location, parser::State};
4
5/// [`Context`] implementation for LR parsing
6#[derive(Debug)]
7pub struct LRContext<'i, I: Input + ?Sized, S, TK> {
8    position: usize,
9
10    /// The range of token/non-terminal during shift/reduce operation.
11    range: Range<usize>,
12
13    /// Similar to position but has line/column format for text based inputs.
14    ///
15    /// If this prove to be pricey overhead we might make tracking of this info
16    /// configurable.
17    location: Location,
18
19    /// Layout before the lookahead token (e.g. whitespaces, comments...)
20    layout_ahead: Option<&'i I>,
21
22    token_ahead: Option<Token<'i, I, TK>>,
23
24    state: S,
25}
26
27impl<I: Input + ?Sized, S: Default, TK> Default for LRContext<'_, I, S, TK> {
28    fn default() -> Self {
29        Self::new(0)
30    }
31}
32
33impl<I: Input + ?Sized, S: Default, TK> LRContext<'_, I, S, TK> {
34    pub fn new(position: usize) -> Self {
35        Self {
36            position,
37            location: I::start_location(),
38            layout_ahead: None,
39            range: 0..0,
40            token_ahead: None,
41            state: S::default(),
42        }
43    }
44}
45
46impl<'i, I, S, TK> Context<'i, I, S, TK> for LRContext<'i, I, S, TK>
47where
48    I: Input + ?Sized,
49    S: State,
50{
51    #[inline]
52    fn state(&self) -> S {
53        self.state
54    }
55
56    #[inline]
57    fn set_state(&mut self, state: S) {
58        self.state = state
59    }
60
61    #[inline]
62    fn position(&self) -> usize {
63        self.position
64    }
65
66    #[inline]
67    fn set_position(&mut self, position: usize) {
68        self.position = position
69    }
70
71    #[inline]
72    fn location(&self) -> Location {
73        self.location
74    }
75
76    #[inline]
77    fn set_location(&mut self, location: Location) {
78        self.location = location
79    }
80
81    #[inline]
82    fn range(&self) -> Range<usize> {
83        self.range.clone()
84    }
85
86    #[inline]
87    fn set_range(&mut self, range: Range<usize>) {
88        self.range = range
89    }
90
91    #[inline]
92    fn token_ahead(&self) -> Option<&Token<'i, I, TK>> {
93        self.token_ahead.as_ref()
94    }
95
96    #[inline]
97    fn set_token_ahead(&mut self, token: Token<'i, I, TK>) {
98        self.token_ahead = Some(token)
99    }
100
101    #[inline]
102    fn layout_ahead(&self) -> Option<&'i I> {
103        self.layout_ahead
104    }
105
106    #[inline]
107    fn set_layout_ahead(&mut self, layout: Option<&'i I>) {
108        self.layout_ahead = layout
109    }
110}