1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
use crate::expression::*;
use crate::token::*;
#[derive(Debug, Clone)]
pub enum ParseError {
UnexpectedToken {
found: Token, // Own the token, don't borrow it
expecting: &'static str,
},
UnexpectedEndOfInput {
expecting: &'static str,
},
}
struct ParseContext {
tokens: Vec<Token>,
pos: usize,
}
impl ParseContext {
fn advance(&mut self) -> Result<(), ParseError> {
self.pos += 1;
if self.pos >= self.tokens.len() {
Err(ParseError::UnexpectedEndOfInput {
expecting: "more tokens",
})
} else {
Ok(())
}
}
fn current(&self) -> Result<Token, ParseError> {
self.tokens
.get(self.pos)
.cloned()
.ok_or(ParseError::UnexpectedEndOfInput { expecting: "token" })
}
}
pub fn parse(tokens: Vec<Token>) -> Result<SelectionValuedExpr, ParseError> {
let mut context = ParseContext {
tokens: tokens,
pos: 0,
};
let func = parse_function(&mut context)?;
Ok(SelectionValuedExpr::NullaryApplicationS(func))
}
fn parse_function(context: &mut ParseContext) -> Result<SelectionFn, ParseError> {
let func = parse_builtin_function_s(context)?;
Ok(SelectionFn::Function {
func: func,
search_mod: None,
result_transform: None,
})
}
fn parse_builtin_function_s(context: &mut ParseContext) -> Result<BuiltinSelectionFn, ParseError> {
let token = context.current()?;
match token {
Token::Empty => Ok(BuiltinSelectionFn::Empty),
Token::EndOfBuffer => Ok(BuiltinSelectionFn::EndOfBuffer),
Token::Span => Ok(BuiltinSelectionFn::Span),
Token::CharacterOffset => parse_char_offset(context),
Token::Number(n) => Ok(BuiltinSelectionFn::Line(n)),
Token::Regex(pattern) => Ok(BuiltinSelectionFn::Regex(pattern)),
Token::AllMatches => parse_all_matches(context),
Token::PositiveLineOffset => parse_relative_line(context),
Token::BufferMatch => parse_buffer_match(context),
_ => Err(ParseError::UnexpectedToken {
found: token,
expecting: "selection function",
}),
}
}
fn parse_char_offset(context: &mut ParseContext) -> Result<BuiltinSelectionFn, ParseError> {
context.advance()?;
let token = context.current()?;
match token {
Token::Number(n) => Ok(BuiltinSelectionFn::CharOffset(n)),
_ => Err(ParseError::UnexpectedToken {
found: token,
expecting: "number",
}),
}
}
fn parse_all_matches(context: &mut ParseContext) -> Result<BuiltinSelectionFn, ParseError> {
context.advance()?;
let token = context.current()?;
match token {
Token::Regex(pattern) => Ok(BuiltinSelectionFn::AllMatches(pattern)),
_ => Err(ParseError::UnexpectedToken {
found: token,
expecting: "regex",
}),
}
}
fn parse_relative_line(context: &mut ParseContext) -> Result<BuiltinSelectionFn, ParseError> {
context.advance()?;
let token = context.current()?;
match token {
Token::Number(n) => Ok(BuiltinSelectionFn::RelativeLine(n)),
_ => Err(ParseError::UnexpectedToken {
found: token,
expecting: "number",
}),
}
}
fn parse_buffer_match(context: &mut ParseContext) -> Result<BuiltinSelectionFn, ParseError> {
context.advance()?;
let token = context.current()?;
match token {
Token::Regex(pattern) => Ok(BuiltinSelectionFn::BufferMatch(pattern)),
_ => Err(ParseError::UnexpectedToken {
found: token,
expecting: "regex",
}),
}
}
|