diff options
Diffstat (limited to 'src/fexpr/grammar.lalrpop')
| -rw-r--r-- | src/fexpr/grammar.lalrpop | 55 | 
1 files changed, 51 insertions, 4 deletions
| diff --git a/src/fexpr/grammar.lalrpop b/src/fexpr/grammar.lalrpop index 45f4fde..092407e 100644 --- a/src/fexpr/grammar.lalrpop +++ b/src/fexpr/grammar.lalrpop @@ -4,12 +4,16 @@ use super::{      FightOutcome,      filters,      PlayerClass, + +    DateProducer, +    DurationProducer, +    CountProducer,  };  use evtclib::Boss;  use std::collections::HashSet;  use lalrpop_util::ParseError; -use chrono::{DateTime, Local, TimeZone, Utc, Weekday}; +use chrono::{DateTime, Local, TimeZone, Utc, Weekday, Duration};  use regex::{Regex, RegexBuilder};  grammar; @@ -48,8 +52,12 @@ LogPredicate: Box<dyn filters::log::LogFilter> = {      "-outcome" <Comma<FightOutcome>> => filters::log::outcome(<>),      "-weekday" <Comma<Weekday>> => filters::log::weekday(<>), -    "-before" <Date> => filters::log::before(<>), -    "-after" <Date> => filters::log::after(<>), +    "-before" <Date> => filters::values::comparison( +        filters::values::time(), filters::values::CompOp::Less, filters::values::constant(<>) +    ), +    "-after" <Date> => filters::values::comparison( +        filters::values::time(), filters::values::CompOp::Greater, filters::values::constant(<>) +    ),      "-log-before" <Date> => filters::log::log_before(<>),      "-log-after" <Date> => filters::log::log_after(<>), @@ -68,6 +76,10 @@ LogPredicate: Box<dyn filters::log::LogFilter> = {      "any" "(" "player" ":" <PlayerFilter> ")" => filters::player::any(<>),      "exists" "(" "player" ":" <PlayerFilter> ")" => filters::player::any(<>), +    <Comparison<DateProducer>>, +    <Comparison<DurationProducer>>, +    <Comparison<CountProducer>>, +      "(" <LogFilter> ")",  } @@ -175,6 +187,22 @@ Date: DateTime<Utc> = {          .map(|d| d.with_timezone(&Utc)),  } +Duration: Duration = { +    duration => Duration::from_std(humantime::parse_duration(<>).unwrap()).unwrap(), +} + +CompOp: filters::values::CompOp = { +    "<" => filters::values::CompOp::Less, +    "<=" => filters::values::CompOp::LessEqual, +    "=" => filters::values::CompOp::Equal, +    ">=" => filters::values::CompOp::GreaterEqual, +    ">" => filters::values::CompOp::Greater, +} + +Comparison<T>: Box<dyn filters::log::LogFilter> = { +    <lhs:T> <op:CompOp> <rhs:T> => filters::values::comparison(lhs, op, rhs), +} +  Comma<T>: HashSet<T> = {      <v:(<T> ",")*> <e:T> => {          let mut result = v.into_iter().collect::<HashSet<_>>(); @@ -183,6 +211,22 @@ Comma<T>: HashSet<T> = {      },  } +DateProducer: Box<dyn DateProducer> = { +    <Date> => filters::values::constant(<>), +    "-time" => filters::values::time(), +} + +DurationProducer: Box<dyn DurationProducer> = { +    <Duration> => filters::values::constant(<>), +    "-duration" => filters::values::duration(), +} + +CountProducer: Box<dyn CountProducer> = { +    <integer> => filters::values::constant(<>.parse().unwrap()), +    "count" "(" "player" ":" <PlayerFilter> ")" => filters::values::player_count(<>), +    "count" "(" "player" ")" => filters::values::player_count(filters::constant(true)), +} +  match {      "player" => "player",      "not" => "not", @@ -191,10 +235,13 @@ match {      "any" => "any",      "all" => "all",      "exists" => "exists", +    "count" => "count",      r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d" => datetime,      r"\d\d\d\d-\d\d-\d\d" => date, -    r"[\w]+" => word, +    r"((\d+m ?)?\d+s)|(\d+m)" => duration, +    r"\d+" => integer, +    r"[[:alpha:]][\w]*" => word,      r#""[^"]*""# => string,      _ | 
