Skip to content

Commit 17042a2

Browse files
committed
feat(argus-parser): complete the syntax parser
1 parent 3adf2ff commit 17042a2

File tree

4 files changed

+101
-88
lines changed

4 files changed

+101
-88
lines changed

argus-parser/Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ name = "argus-parser"
33
version = "0.1.0"
44
edition = "2021"
55

6-
[lib]
7-
name = "argus_parser"
8-
9-
[[bin]]
10-
name = "argus_parser"
11-
path = "src/main.rs"
12-
6+
[[example]]
7+
name = "dump_parse_tree"
8+
required-features = ["reporting"]
139

1410
[dependencies]
1511
argus-core = { version = "0.1.0", path = "../argus-core" }
16-
ariadne = "0.3.0"
12+
ariadne = { version = "0.3.0", optional = true }
1713
chumsky = { version = "1.0.0-alpha.4", features = ["default", "label"] }
14+
15+
[features]
16+
17+
reporting = ["dep:ariadne"]

argus-parser/src/main.rs renamed to argus-parser/examples/dump_parse_tree.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
use std::{env, fs};
1+
use std::env;
22

3-
use argus_parser::lexer;
4-
// use crate::parser::{parser, Error as ParseError};
3+
use argus_parser::{lexer, parser};
54
use ariadne::{sources, Color, Label, Report, ReportKind};
5+
use chumsky::prelude::Input;
66
use chumsky::Parser;
77

88
fn main() {
99
let src = env::args().nth(1).expect("Expected expression");
1010

11-
let (tokens, mut errs) = lexer().parse(src.as_str()).into_output_errors();
11+
let (tokens, errs) = lexer().parse(src.as_str()).into_output_errors();
1212

1313
println!("*** Outputting tokens ***");
1414
if let Some(tokens) = &tokens {
@@ -33,7 +33,7 @@ fn main() {
3333

3434
errs.into_iter()
3535
.map(|e| e.map_token(|c| c.to_string()))
36-
// .chain(parse_errs.into_iter().map(|e| e.map_token(|tok| tok.to_string())))
36+
.chain(parse_errs.into_iter().map(|e| e.map_token(|tok| tok.to_string())))
3737
.for_each(|e| {
3838
Report::build(ReportKind::Error, src.clone(), e.span().start)
3939
.with_message(e.to_string())

argus-parser/src/lexer.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,20 @@ pub fn lexer<'src>() -> impl Parser<'src, &'src str, Output<'src>, Error<'src>>
9494
let floating_number = just('-')
9595
.or_not()
9696
.then(digits)
97-
.then(frac.or_not())
98-
.then(exp.or_not())
97+
.then(choice((frac.then(exp).slice(), frac.slice(), exp.slice())))
98+
// .then(frac.or_not())
99+
// .then(exp.or_not())
99100
.map_slice(|s: &str| Token::Float(s.parse().unwrap()))
100101
.boxed();
101102

102103
let signed_int = one_of("+-")
103-
.or_not()
104+
// .or_not()
104105
.then(digits)
106+
.then(frac.not().or(exp.not()))
105107
.map_slice(|s: &str| Token::Int(s.parse().unwrap()));
106-
let unsigned_int = digits.map_slice(|s: &str| Token::UInt(s.parse().unwrap()));
108+
let unsigned_int = digits
109+
.then(frac.not().or(exp.not()))
110+
.map_slice(|s: &str| Token::UInt(s.parse().unwrap()));
107111

108112
let number = choice((floating_number, signed_int, unsigned_int));
109113

@@ -160,10 +164,16 @@ pub fn lexer<'src>() -> impl Parser<'src, &'src str, Output<'src>, Error<'src>>
160164
"false" => Token::Bool(false),
161165
"G" => Token::Always,
162166
"alw" => Token::Always,
167+
"always" => Token::Always,
168+
"globally" => Token::Always,
163169
"F" => Token::Eventually,
164170
"ev" => Token::Eventually,
171+
"eventually" => Token::Eventually,
172+
"finally" => Token::Eventually,
165173
"X" => Token::Next,
174+
"next" => Token::Next,
166175
"U" => Token::Until,
176+
"until" => Token::Until,
167177
_ => Token::Ident(ident),
168178
});
169179

argus-parser/src/parser.rs

Lines changed: 74 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,6 @@ impl<'src> Expr<'src> {
145145
}
146146
}
147147

148-
fn var(name: &'src str) -> Self {
149-
Self::Var {
150-
name,
151-
kind: Type::Unknown,
152-
}
153-
}
154-
155148
fn unary_op(op: UnaryOps, arg: Box<Spanned<Self>>, interval: Option<Spanned<Interval<'src>>>) -> Self {
156149
let mut arg = arg;
157150
(*arg).0.make_typed(op.default_type());
@@ -189,8 +182,7 @@ type ParserInput<'tokens, 'src> = SpannedInput<Token<'src>, Span, &'tokens [(Tok
189182
pub fn num_expr_parser<'tokens, 'src: 'tokens>(
190183
) -> impl Parser<'tokens, ParserInput<'tokens, 'src>, Spanned<Expr<'src>>, Error<'tokens, 'src>> + Clone {
191184
recursive(|num_expr| {
192-
let var = select! { Token::Ident(ident) => Expr::Var{ name: ident.clone(), kind: Type::default()} }
193-
.labelled("variable");
185+
let var = select! { Token::Ident(name) => Expr::Var{ name, kind: Type::default()} }.labelled("variable");
194186

195187
let num_literal = select! {
196188
Token::Int(val) => Expr::Int(val),
@@ -223,24 +215,32 @@ pub fn num_expr_parser<'tokens, 'src: 'tokens>(
223215

224216
// Product ops (multiply and divide) have equal precedence
225217
let product_op = {
226-
let op = just(Token::Times)
227-
.to(BinaryOps::Mul)
228-
.or(just(Token::Divide).to(BinaryOps::Div));
229-
neg_op.clone().foldl(op.then(neg_op).repeated(), |a, (op, b)| {
230-
let span = a.1.start..b.1.end;
231-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
232-
})
218+
let op = choice((
219+
just(Token::Times).to(BinaryOps::Mul),
220+
just(Token::Divide).to(BinaryOps::Div),
221+
));
222+
neg_op
223+
.clone()
224+
.foldl(op.then(neg_op).repeated(), |a, (op, b)| {
225+
let span = a.1.start..b.1.end;
226+
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
227+
})
228+
.boxed()
233229
};
234230

235231
// Sum ops (add and subtract) have equal precedence
236232
let sum_op = {
237-
let op = just(Token::Plus)
238-
.to(BinaryOps::Add)
239-
.or(just(Token::Minus).to(BinaryOps::Sub));
240-
product_op.clone().foldl(op.then(product_op).repeated(), |a, (op, b)| {
241-
let span = a.1.start..b.1.end;
242-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
243-
})
233+
let op = choice((
234+
just(Token::Plus).to(BinaryOps::Add),
235+
just(Token::Minus).to(BinaryOps::Sub),
236+
));
237+
product_op
238+
.clone()
239+
.foldl(op.then(product_op).repeated(), |a, (op, b)| {
240+
let span = a.1.start..b.1.end;
241+
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
242+
})
243+
.boxed()
244244
};
245245

246246
sum_op.labelled("numeric expression").as_context()
@@ -272,8 +272,9 @@ pub fn parser<'tokens, 'src: 'tokens>(
272272
span.into(),
273273
)
274274
})
275+
.boxed()
275276
};
276-
let num_expr = num_expr_parser();
277+
let num_expr = num_expr_parser().boxed();
277278

278279
recursive(|expr| {
279280
let literal = select! {
@@ -284,32 +285,28 @@ pub fn parser<'tokens, 'src: 'tokens>(
284285
let var = select! { Token::Ident(ident) => Expr::Var{ name: ident.clone(), kind: Type::default()} }
285286
.labelled("variable");
286287

287-
// Relational ops (<, <=, >, >=) have equal precedence
288+
// Relational ops (<, <=, >, >=, ==, !=) have equal precedence
288289
let relational_op = {
289-
let op = just(Token::Lt).to(BinaryOps::Lt).or(just(Token::Le)
290-
.to(BinaryOps::Le)
291-
.or(just(Token::Gt).to(BinaryOps::Gt).or(just(Token::Ge).to(BinaryOps::Ge))));
292-
num_expr.clone().foldl(op.then(num_expr).repeated(), |a, (op, b)| {
293-
let span = a.1.start..b.1.end;
294-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
295-
})
296-
};
297-
298-
// Equality ops (==, !=) have equal precedence
299-
let equality_op = {
300-
let op = just(Token::Eq)
301-
.to(BinaryOps::Eq)
302-
.or(just(Token::Neq).to(BinaryOps::Neq));
303-
relational_op
290+
let op = choice((
291+
just(Token::Lt).to(BinaryOps::Lt),
292+
just(Token::Le).to(BinaryOps::Le),
293+
just(Token::Gt).to(BinaryOps::Gt),
294+
just(Token::Ge).to(BinaryOps::Ge),
295+
just(Token::Eq).to(BinaryOps::Eq),
296+
just(Token::Neq).to(BinaryOps::Neq),
297+
));
298+
num_expr
304299
.clone()
305-
.foldl(op.then(relational_op).repeated(), |a, (op, b)| {
300+
.then(op.then(num_expr))
301+
.map(|(a, (op, b))| {
306302
let span = a.1.start..b.1.end;
307303
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
308304
})
305+
.boxed()
309306
}
310307
.labelled("atomic predicate");
311308

312-
let atom = equality_op
309+
let atom = relational_op
313310
.or(var.or(literal).map_with_span(|expr, span| (expr, span)))
314311
// Atoms can also just be normal expressions, but surrounded with parentheses
315312
.or(expr.clone().delimited_by(just(Token::LParen), just(Token::RParen)))
@@ -328,28 +325,23 @@ pub fn parser<'tokens, 'src: 'tokens>(
328325
.foldr(atom, |op, rhs| {
329326
let span = op.1.start..rhs.1.end;
330327
(Expr::unary_op(op.0, Box::new(rhs), None), span.into())
331-
});
332-
333-
let next_op = just(Token::Next)
334-
.map_with_span(|_, span: Span| (UnaryOps::Next, span))
335-
.then(interval.or_not())
336-
.repeated()
337-
.foldr(not_op, |(op, interval), rhs| {
338-
let span = op.1.start..rhs.1.end;
339-
(Expr::unary_op(op.0, Box::new(rhs), interval), span.into())
340-
});
328+
})
329+
.boxed();
341330

342331
let unary_temporal_op = {
343-
let op = just(Token::Eventually)
344-
.to(UnaryOps::Eventually)
345-
.or(just(Token::Always).to(UnaryOps::Always));
332+
let op = choice((
333+
just(Token::Next).to(UnaryOps::Next),
334+
just(Token::Eventually).to(UnaryOps::Eventually),
335+
just(Token::Always).to(UnaryOps::Always),
336+
));
346337
op.map_with_span(|op, span: Span| (op, span))
347-
.then(interval.or_not())
338+
.then(interval.clone().or_not())
348339
.repeated()
349-
.foldr(next_op, |(op, interval), rhs| {
340+
.foldr(not_op, |(op, interval), rhs| {
350341
let span = op.1.start..rhs.1.end;
351342
(Expr::unary_op(op.0, Box::new(rhs), interval), span.into())
352343
})
344+
.boxed()
353345
};
354346

355347
let binary_temporal_op = unary_temporal_op
@@ -363,7 +355,8 @@ pub fn parser<'tokens, 'src: 'tokens>(
363355
Expr::binary_op(op, (Box::new(lhs), Box::new(rhs)), interval),
364356
span.into(),
365357
)
366-
});
358+
})
359+
.boxed();
367360

368361
let and_op = {
369362
let op = just(Token::And).to(BinaryOps::And);
@@ -373,34 +366,44 @@ pub fn parser<'tokens, 'src: 'tokens>(
373366
let span = a.1.start..b.1.end;
374367
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
375368
})
369+
.boxed()
376370
};
377371

378372
let or_op = {
379373
let op = just(Token::Or).to(BinaryOps::Or);
380-
and_op.clone().foldl(op.then(and_op).repeated(), |a, (op, b)| {
381-
let span = a.1.start..b.1.end;
382-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
383-
})
374+
and_op
375+
.clone()
376+
.foldl(op.then(and_op).repeated(), |a, (op, b)| {
377+
let span = a.1.start..b.1.end;
378+
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
379+
})
380+
.boxed()
384381
};
385382

386383
let xor_op = {
387384
let op = just(Token::Xor).to(BinaryOps::Xor);
388-
or_op.clone().foldl(op.then(or_op).repeated(), |a, (op, b)| {
389-
let span = a.1.start..b.1.end;
390-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
391-
})
385+
or_op
386+
.clone()
387+
.foldl(op.then(or_op).repeated(), |a, (op, b)| {
388+
let span = a.1.start..b.1.end;
389+
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
390+
})
391+
.boxed()
392392
};
393393

394394
let implies_equiv_op = {
395395
let op = just(Token::Implies)
396396
.to(BinaryOps::Implies)
397397
.or(just(Token::Equiv).to(BinaryOps::Equiv));
398-
xor_op.clone().foldl(op.then(xor_op).repeated(), |a, (op, b)| {
399-
let span = a.1.start..b.1.end;
400-
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
401-
})
398+
xor_op
399+
.clone()
400+
.foldl(op.then(xor_op).repeated(), |a, (op, b)| {
401+
let span = a.1.start..b.1.end;
402+
(Expr::binary_op(op, (Box::new(a), Box::new(b)), None), span.into())
403+
})
404+
.boxed()
402405
};
403406

404-
implies_equiv_op.labelled("expression").as_context()
407+
implies_equiv_op.labelled("boolean expression").as_context()
405408
})
406409
}

0 commit comments

Comments
 (0)