doublify_toolkit/filtering/
parser.rs1use filtering::scanner::{Kind, Token};
24
25use std::boxed::Box;
26use std::fmt::Debug;
27use std::iter::Peekable;
28
29use std::str::FromStr;
30
31#[derive(Debug, PartialEq)]
33pub enum Expression {
34 OrExpression(OrExpression),
36 InExpression(InExpression),
38 VariableDeclaration(VariableDeclaration),
40 Literal(Literal),
42 Unknown,
44}
45
46#[derive(Debug, PartialEq)]
48pub struct OrExpression {
49 pub children: Vec<Box<Expression>>,
51}
52
53#[derive(Debug, PartialEq)]
55pub struct InExpression {
56 pub children: Vec<Box<Expression>>,
58}
59
60#[derive(Debug, PartialEq)]
62pub enum VariableDeclarationKind {
63 IsKeyword,
65 NotKeyword,
67}
68
69#[derive(Debug, PartialEq)]
71pub struct VariableDeclaration {
72 pub kind: Option<VariableDeclarationKind>,
74 pub name: Literal,
76 pub children: Option<Box<Expression>>,
78}
79
80#[derive(Clone, Debug, PartialEq)]
82pub enum Literal {
83 String(String),
85 Integer(f64),
87 Boolean(bool),
89 Identifier(String),
91}
92
93#[derive(Debug, PartialEq)]
95pub struct SourceFile {
96 pub body: Vec<Box<Expression>>,
98}
99
100fn match_keyword(raw_keyword: &str) -> Option<VariableDeclarationKind> {
102 use self::VariableDeclarationKind::{IsKeyword, NotKeyword};
103
104 match raw_keyword {
105 "is" => Some(IsKeyword),
106 "not" => Some(NotKeyword),
107 _ => None,
108 }
109}
110
111fn parse_identifier<'a, It>(it: &mut Peekable<It>, raw_token: &Token) -> Box<Expression>
113 where It: Iterator<Item = &'a Token> + Clone
114{
115 let ref binding = raw_token.binding;
116 let keyword = match_keyword(binding.as_ref());
117 let next_token = it.peek().map(|c| *c);
118 let identifier = Literal::Identifier(binding.to_owned());
119
120 let expression = match next_token {
121 Some(ref token) if token.kind == Kind::Colon => {
122 it.next();
123 let token = it.next().unwrap();
124 let node = parse_expression(it, token).unwrap();
125
126 let variable_declaration = VariableDeclaration {
127 kind: keyword,
128 name: identifier,
129 children: Some(node),
130 };
131
132 Expression::VariableDeclaration(variable_declaration)
133 }
134 _ => Expression::Literal(identifier),
135 };
136
137 Box::new(expression)
138}
139
140fn parse_or_expression<'a, It>(it: &mut Peekable<It>) -> Box<Expression>
142 where It: Iterator<Item = &'a Token> + Clone
143{
144 let mut node = OrExpression { children: vec![] };
145 let predicate_or_expression = &|ref token: &&Token| -> bool {
146 (token.kind != Kind::Curly) ||
147 (token.kind == Kind::Curly && token.binding != "}")
148 };
149
150 while let Some(token) = it.take_while(predicate_or_expression).next() {
151 node.children.push(parse_expression(it, token).unwrap());
152 }
153
154 let expression = Expression::OrExpression(node);
155
156 Box::new(expression)
157}
158
159fn parse_in_expression<'a, It>(it: &mut Peekable<It>) -> Box<Expression>
161 where It: Iterator<Item = &'a Token> + Clone
162{
163 let mut node = InExpression { children: vec![] };
164 let predicate_in_expression = &|ref token: &&Token| -> bool {
165 (token.kind != Kind::Parentheses) ||
166 (token.kind == Kind::Parentheses && token.binding != ")")
167 };
168
169 while let Some(token) = it.take_while(predicate_in_expression).next() {
170 node.children.push(parse_expression(it, token).unwrap());
171 }
172
173 let expression = Expression::InExpression(node);
174
175 Box::new(expression)
176}
177
178fn parse_literal<T>(kind: fn(T) -> Literal, binding: T) -> Expression {
180 let node = kind(binding);
181 let expr = Expression::Literal(node);
182
183 expr
184}
185
186fn parse_type<T>(kind: fn(T) -> Literal, binding: &String) -> Expression
188 where T: FromStr,
189 <T as FromStr>::Err: Debug
190{
191 parse_literal(kind, binding.parse::<T>().unwrap())
192}
193
194fn parse_string(token: &Token) -> Box<Expression> {
196 let node_binding = token
197 .binding
198 .trim_matches('"')
199 .trim_matches('\'')
200 .to_string();
201
202 let expr = parse_literal(Literal::String, node_binding);
203 Box::new(expr)
204}
205
206fn parse_integer(token: &Token) -> Box<Expression> {
208 Box::new(parse_type::<f64>(Literal::Integer, &token.binding))
209}
210
211fn parse_boolean(token: &Token) -> Box<Expression> {
213 Box::new(parse_type::<bool>(Literal::Boolean, &token.binding))
214}
215
216fn parse_expression<'a, It>(it: &mut Peekable<It>,
218 token: &Token)
219 -> Result<Box<Expression>, Box<String>>
220 where It: Iterator<Item = &'a Token> + Clone
221{
222 match token.kind {
223 Kind::String => Ok(parse_string(token)),
224 Kind::Integer => Ok(parse_integer(token)),
225 Kind::Boolean => Ok(parse_boolean(token)),
226 Kind::Identifier => Ok(parse_identifier(it, token)),
227 Kind::Parentheses => Ok(parse_in_expression(it)),
228 Kind::Curly => Ok(parse_or_expression(it)),
229 _ => Err(Box::new(format!("{:?}", token))),
230 }
231}
232
233pub fn parse(tokens: Vec<Token>) -> SourceFile {
235 let mut ast = SourceFile { body: vec![] };
236 let mut it = tokens.iter().peekable();
237
238 while let Some(token) = it.next() {
239 let expression = parse_expression(&mut it, &token).unwrap();
240
241 ast.body.push(expression);
242 }
243
244 ast
245}