From 2627a17a43ffe3f803de7a5837144e1bdce0d9c8 Mon Sep 17 00:00:00 2001 From: JohannaSimoens Date: Tue, 18 Jun 2019 11:08:45 +0200 Subject: [PATCH] Portuguese V1 --- grammar/it/src/rules.rs | 25 +- grammar/pt/src/rules.rs | 1863 +++++++++++++++++++++++++++++++++--- grammar/pt/src/training.rs | 337 ++++++- 3 files changed, 2093 insertions(+), 132 deletions(-) diff --git a/grammar/it/src/rules.rs b/grammar/it/src/rules.rs index 5961793a..0916ae2c 100644 --- a/grammar/it/src/rules.rs +++ b/grammar/it/src/rules.rs @@ -91,11 +91,11 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { ); // This is not recognized for a very obscure reason b.rule_1_terminal("RUB", - b.reg(r#"rub(?:l[oi])?"#)?, + b.reg(r#"rub(?:l[oi])?(?: russ[oi])?"#)?, |_| Ok(MoneyUnitValue { unit: Some("RUB") }) ); b.rule_1_terminal("INR", - b.reg(r#"inr|rupi[ae]"#)?, + b.reg(r#"inr|rupi[ae](?: indian[ae])?"#)?, |_| Ok(MoneyUnitValue { unit: Some("INR") }) ); b.rule_1_terminal("JPY", @@ -317,6 +317,16 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.reg(r#"(?:all'in)?circa|più o meno"#)?, |duration, _| Ok(duration.value().clone().precision(Precision::Approximate)) ); + b.rule_2("exactly ", + b.reg(r#"esattamente"#)?, + duration_check!(), + |_, duration| Ok(duration.value().clone().precision(Precision::Exact)) + ); + b.rule_2(" exactly", + duration_check!(), + b.reg(r#"(?:esatt|precis)(?:[aoie]|amente)"#)?, + |duration, _| Ok(duration.value().clone().precision(Precision::Exact)) + ); b.rule_2("during ", b.reg(r#"(?:durante|per)"#)?, duration_check!(), @@ -884,6 +894,11 @@ pub fn rules_time(b: &mut RuleSetBuilder) -> RustlingResult<()> { integer_check_by_range!(1, 23), |_, integer| Ok(helpers::hour(integer.value().value as u32, integer.value().value < 12)?.not_latent()) ); + b.rule_2(" oclock", + b.reg(r#"l['e]"#)?, + integer_check_by_range!(1, 23), + |_, integer| Ok(helpers::hour(integer.value().value as u32, integer.value().value < 12)?.not_latent()) + ); b.rule_2("around ", b.reg(r#"verso|interno a|(?:approssim|indic|orient)ativamente|(?:all'in)?circa|più o meno|pressappoco|suppergiù|grosso modo"#)?, time_check!(form!(Form::TimeOfDay(_))), @@ -1729,9 +1744,9 @@ pub fn rules_temperature(b: &mut RuleSetBuilder) -> RustlingResult<() latent: false, }) }); - b.rule_2(" temp below zero", - temperature_check!(), - b.reg(r#"(?:grad[oi] |° )?(?:sotto (?:lo )?zero)"#)?, + b.rule_2(" temp below zero", + temperature_check!(|temp: &TemperatureValue| !temp.latent), + b.reg(r#"sotto (?:lo )?zero"#)?, |a, _| { Ok(TemperatureValue { value: -1.0 * a.value().value, diff --git a/grammar/pt/src/rules.rs b/grammar/pt/src/rules.rs index a0d570d8..c1354700 100644 --- a/grammar/pt/src/rules.rs +++ b/grammar/pt/src/rules.rs @@ -27,6 +27,7 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { amount_of_money_check!(|money: &AmountOfMoneyValue| money.unit != Some("cent")), number_check!(), |a, b| helpers::compose_money_number(&a.value(), &b.value())); + b.rule_1_terminal("$", b.reg(r#"\$|d[oó]lar(?:es)?"#)?, |_| Ok(MoneyUnitValue { unit: Some("$") }) @@ -40,73 +41,91 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { |_| Ok(MoneyUnitValue { unit: Some("£") }) ); b.rule_1_terminal("GBP", - b.reg(r#"gbp|libras? esterlinas?"#)?, + b.reg(r#"gbp|libras? esterlinas?|libras? inglesas?|libras? britânicas?"#)?, |_| Ok(MoneyUnitValue { unit: Some("GBP") }) ); b.rule_1_terminal("USD", - b.reg(r#"d[oó]lar(?:es)? americanos?"#)?, + b.reg(r#"d[oó]lar(?:es)? americanos?|d[oó]lar(?:es)? estadunidenses?|us[d\$]"#)?, |_| Ok(MoneyUnitValue { unit: Some("USD") }) ); b.rule_1_terminal("CAD", - b.reg(r#"d[oó]lar(?:es)? canadenses?"#)?, + b.reg(r#"d[oó]lar(?:es)? canadenses?|cad"#)?, |_| Ok(MoneyUnitValue { unit: Some("CAD") }) ); b.rule_1_terminal("AUD", - b.reg(r#"d[oó]lar(?:es) australianos?"#)?, + b.reg(r#"d[oó]lar(?:es)? australianos?"#)?, |_| Ok(MoneyUnitValue { unit: Some("AUD") }) ); b.rule_1_terminal("Bitcoin", - b.reg(r#"฿|bitcoins?"#)?, + b.reg(r#"฿|bitcoins?|btc|xbt"#)?, |_| Ok(MoneyUnitValue { unit: Some("฿") }) ); - b.rule_1_terminal("GBP", - b.reg(r#"libras? inglesas?"#)?, - |_| Ok(MoneyUnitValue { unit: Some("GBP") }) - ); b.rule_1_terminal("JPY", - b.reg(r#"jpy|[yi]en(?:es)?(?: japoneses?)?"#)?, + b.reg(r#"jpy|[yi]en(?:es?)?(?: japoneses?)?"#)?, |_| Ok(MoneyUnitValue { unit: Some("JPY") }) ); b.rule_1_terminal("¥", b.reg(r#"¥"#)?, |_| Ok(MoneyUnitValue { unit: Some("¥") }) ); + b.rule_1_terminal("₽", + b.reg(r#"₽"#)?, + |_| Ok(MoneyUnitValue { unit: Some("₽") }) + ); b.rule_1_terminal("KRW", - b.reg(r#"wons?|₩"#)?, + b.reg(r#"krw|₩|won(?:e?s)? (?:sul[- ])?coreanos?|won(?:e?s)?"#)?, |_| Ok(MoneyUnitValue { unit: Some("KRW") }) ); -// b.rule_1_terminal("RMB|CNH|CNY", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("CNY") }) -// ); + b.rule_1_terminal("RMB|CNH|CNY", + b.reg(r#"yuan(?:e?s)?(?: chineses?)?|renminbis?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("CNY") }) + ); b.rule_1_terminal("INR", b.reg(r#"r[uú]pias?"#)?, |_| Ok(MoneyUnitValue { unit: Some("INR") }) ); -// b.rule_1_terminal("HKD", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("HKD") }) -// ); + b.rule_1_terminal("INR", + b.reg(r#"r[uú]pias? indianas?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("INR") }) + ); + b.rule_1_terminal("HKD", + b.reg(r#"d[oó]lar(?:es)? de hong kong"#)?, + |_| Ok(MoneyUnitValue { unit: Some("HKD") }) + ); b.rule_1_terminal("CHF", - b.reg(r#"francos? suíços?"#)?, + b.reg(r#"francos? su[íi]ços?"#)?, |_| Ok(MoneyUnitValue { unit: Some("CHF") }) ); -// b.rule_1_terminal("KR", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("KR") }) -// ); -// b.rule_1_terminal("DKK", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("DKK") }) -// ); -// b.rule_1_terminal("NOK", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("NOK") }) -// ); -// b.rule_1_terminal("SEK", -// b.reg(r#""#)?, -// |_| Ok(MoneyUnitValue { unit: Some("SEK") }) -// ); + b.rule_1_terminal("KR", + b.reg(r#"kr|coroas?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("KR") }) + ); + b.rule_1_terminal("DKK", + b.reg(r#"dkk|coroas? dinamarquesas?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("DKK") }) + ); + b.rule_1_terminal("NOK", + b.reg(r#"nok|coroas? norueguesas?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("NOK") }) + ); + b.rule_1_terminal("SEK", + b.reg(r#"sek|coroas? suecas?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("SEK") }) + ); + + b.rule_1_terminal("RUB", + b.reg(r#"rub"#)?, + |_| Ok(MoneyUnitValue { unit: Some("RUB") }) + ); + b.rule_1_terminal("RUB", + b.reg(r#"rublos?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("RUB") }) + ); + b.rule_1_terminal("RUB", + b.reg(r#"rublos? russos?"#)?, + |_| Ok(MoneyUnitValue { unit: Some("RUB") }) + ); + b.rule_1_terminal("cent", b.reg(r#"centavos?"#)?, |_| Ok(MoneyUnitValue { unit: Some("cent") }) @@ -143,7 +162,7 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { }) }); b.rule_2("about ", - b.reg(r#"cerca de"#)?, + b.reg(r#"quase|aproximadamente|cerca de|por (?:cerca|volta) de|em torno de|uns|umas"#)?, amount_of_money_check!(), |_, a| { Ok(AmountOfMoneyValue { @@ -151,17 +170,17 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { ..a.value().clone() }) }); -// b.rule_2(" about", -// amount_of_money_check!(), -// b.reg(r#""#)?, -// |a, _| { -// Ok(AmountOfMoneyValue { -// precision: Approximate, -// ..a.value().clone() -// }) -// }); + b.rule_2(" about", + amount_of_money_check!(), + b.reg(r#"aproximadamente|mais ou menos"#)?, + |a, _| { + Ok(AmountOfMoneyValue { + precision: Approximate, + ..a.value().clone() + }) + }); b.rule_2("exactly ", - b.reg(r#"exatamente"#)?, + b.reg(r#"exatamente|precisamente"#)?, amount_of_money_check!(), |_, a| { Ok(AmountOfMoneyValue { @@ -169,16 +188,16 @@ pub fn rules_finance(b: &mut RuleSetBuilder) -> RustlingResult<()> { ..a.value().clone() }) }); -// b.rule_2(" exactly", -// amount_of_money_check!(), -// b.reg(r#""#)?, -// |a, _| { -// Ok(AmountOfMoneyValue { -// precision: Exact, -// ..a.value().clone() -// }) -// } -// ); + b.rule_2(" exactly", + amount_of_money_check!(), + b.reg(r#"exatamente|precisamente|exatos?"#)?, + |a, _| { + Ok(AmountOfMoneyValue { + precision: Exact, + ..a.value().clone() + }) + } + ); Ok(()) } @@ -211,8 +230,12 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.reg(r#"anos?"#)?, |_| Ok(UnitOfDurationValue::new(Grain::Year)) ); + b.rule_1_terminal("trimester (unit-of-duration)", + b.reg(r#"trimestres?"#)?, + |_| Ok(UnitOfDurationValue::new(Grain::Quarter)) + ); b.rule_1_terminal("quarter of an hour", - b.reg(r#"quarto de hora"#)?, + b.reg(r#"(?:um )?quarto de hora"#)?, |_| Ok(DurationValue::new(PeriodComp::minutes(15).into())) ); b.rule_1_terminal("half an hour", @@ -223,6 +246,16 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.reg(r#"tr[eê]s quartos de hora"#)?, |_| Ok(DurationValue::new(PeriodComp::minutes(45).into())) ); + b.rule_3(" h ", + integer_check_by_range!(0), + b.reg(r#"h(?:oras?)?"#)?, + integer_check_by_range!(0,59), + |hour, _, minute| { + let hour_period = Period::from(PeriodComp::new(Grain::Hour, hour.value().clone().value)); + let minute_period = Period::from(PeriodComp::new(Grain::Minute, minute.value().clone().value)); + Ok(DurationValue::new(hour_period + minute_period)) + } + ); b.rule_2(" ", integer_check_by_range!(0), unit_of_duration_check!(), @@ -231,7 +264,7 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.rule_3(" and a half", integer_check_by_range!(0), unit_of_duration_check!(), - b.reg(r#"e meia"#)?, + b.reg(r#"e mei[ao]"#)?, |integer, uod, _| { let half_period: Period = uod.value().grain.half_period().map(|a| a.into()).ok_or_else(|| RuleError::Invalid)?; Ok(DurationValue::new(half_period + PeriodComp::new(uod.value().grain, integer.value().value))) @@ -246,11 +279,30 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { // Ok(DurationValue::new(half_period + PeriodComp::new(uod.value().grain, integer.value().value))) // } // ); + // FUTUR b.rule_2("in (future moment)", - b.reg(r#"em"#)?, + b.reg(r#"em|daqui a|dentro de"#)?, duration_check!(), |_, duration| duration.value().in_present() ); + // FUTUR + b.rule_2(" later", + duration_check!(), + b.reg(r#"depois"#)?, + |duration, _| duration.value().in_present() + ); + // PAST + b.rule_2(" ago", + duration_check!(), + b.reg(r#"atr[aá]s"#)?, + |duration, _| duration.value().ago() + ); + // PAST + b.rule_2(" ago", + b.reg(r#"há|faz"#)?, + duration_check!(), + |_, duration| duration.value().ago() + ); b.rule_3(" y ", duration_check!(|duration: &DurationValue| !duration.suffixed), b.reg(r#"e"#)?, @@ -267,24 +319,35 @@ pub fn rules_duration(b: &mut RuleSetBuilder) -> RustlingResult<()> { integer_check_by_range!(0), |duration, integer| helpers::compose_duration_with_integer(duration.value(), integer.value()) ); - b.rule_2(" ago", + b.rule_2("during ", + b.reg(r#"por|durante"#)?, duration_check!(), - b.reg(r#"atr[aá]s"#)?, - |duration, _| duration.value().ago() + |_, duration| Ok(duration.value().clone().prefixed()) ); - b.rule_2(" later", + b.rule_2("approx ", + b.reg(r#"aproximadamente|cerca de|por cerca de|por volta de|em torno de"#)?, duration_check!(), - b.reg(r#"depois"#)?, - |duration, _| duration.value().in_present() + |_, duration| Ok(duration.value().clone().precision(Precision::Approximate)) ); - b.rule_2("during ", - b.reg(r#"por"#)?, + b.rule_2(" approx", duration_check!(), - |_, duration| Ok(duration.value().clone().prefixed()) + b.reg(r#"aproximadamente|mais ou? menos"#)?, + |duration, _| Ok(duration.value().clone().precision(Precision::Approximate)) + ); + b.rule_2("precisely ", + b.reg(r#"exactamente|precisamente"#)?, + duration_check!(), + |_, duration| Ok(duration.value().clone().precision(Precision::Exact)) + ); + b.rule_2("precisely ", + duration_check!(), + b.reg(r#"exactamente|precisamente"#)?, + |duration , _| Ok(duration.value().clone().precision(Precision::Exact)) ); Ok(()) } + pub fn rules_cycle(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.rule_1_terminal("second (cycle)", b.reg(r#"segundos?"#)?, @@ -314,7 +377,124 @@ pub fn rules_cycle(b: &mut RuleSetBuilder) -> RustlingResult<()> { b.reg(r#"anos?"#)?, |_| CycleValue::new(Grain::Year) ); - + b.rule_1_terminal("trimester (cycle)", + b.reg(r#"trimestres?"#)?, + |_| CycleValue::new(Grain::Year) + ); + // FUTUR + b.rule_2("next ", + b.reg(r#"(?:n?[oa] )?próxim[oa]"#)?, + cycle_check!(), + |_, cycle| helpers::cycle_nth(cycle.value().grain, 1) + ); + // FUTUR + b.rule_2(" next", + cycle_check!(), + b.reg(r#"que vem|depois"#)?, + |cycle, _| helpers::cycle_nth(cycle.value().grain, 1) + ); + // FUTUR + b.rule_3("o next", + b.reg(r#"n?[oa]"#)?, + cycle_check!(), + b.reg(r#"que vem|depois"#)?, + |_, cycle, _| helpers::cycle_nth(cycle.value().grain, 1) + ); + // PAST + b.rule_2("last ", + b.reg(r#"[oa] últim[oa]"#)?, + cycle_check!(), + |_, cycle| helpers::cycle_nth(cycle.value().grain, -1) + ); + // PAST + b.rule_2(" last", + cycle_check!(), + b.reg(r#"atr[aá]s|antes|passad[oa]|anteriore"#)?, + |cycle, _| helpers::cycle_nth(cycle.value().grain, -1) + ); + // PAST + b.rule_3("o last", + b.reg(r#"o|a"#)?, + cycle_check!(), + b.reg(r#"atr[aá]s|antes|passad[oa]|anteriore"#)?, + |_, cycle, _| helpers::cycle_nth(cycle.value().grain, -1) + ); + // FUTUR (Date|Time) period + b.rule_3("os next n ", + b.reg(r#"(?:n?[ao]s )?próxim[ao]s"#)?, + integer_check_by_range!(2, 9999), + cycle_check!(), + |_, integer, cycle| helpers::cycle_n_not_immediate(cycle.value().grain, integer.value().value) + ); + // FUTUR (Date|Time) period + b.rule_4("os n next ", + b.reg(r#"n?[ao]s"#)?, + integer_check_by_range!(2, 9999), + b.reg(r#"próxim[ao]s"#)?, + cycle_check!(), + |_, integer, _, cycle| helpers::cycle_n_not_immediate(cycle.value().grain, integer.value().value) + ); + // FUTUR (Date|Time) period + b.rule_3("n next ", + integer_check_by_range!(2, 9999), + b.reg(r#"próxim[ao]s"#)?, + cycle_check!(), + |integer, _, cycle| helpers::cycle_n_not_immediate(cycle.value().grain, integer.value().value) + ); + // FUTUR (Date|Time) period + b.rule_4("os n next ", + b.reg(r#"n?[ao]s"#)?, + integer_check_by_range!(2, 9999), + cycle_check!(), + b.reg(r#"que vem|depois"#)?, + |_, integer, cycle, _| helpers::cycle_n_not_immediate(cycle.value().grain, integer.value().value) + ); + // PAST (Date|Time) period + b.rule_4("os n last ", + b.reg(r#"n?[ao]s"#)?, + integer_check_by_range!(2, 9999), + cycle_check!(), + b.reg(r#"passad[oa]s|anteriores"#)?, + |_, integer, cycle, _| helpers::cycle_n_not_immediate(cycle.value().grain, -1 * integer.value().value) + ); + // PAST (Date|Time) period + b.rule_3("os last n ", + b.reg(r#"(?:n?[ao]s )?últim[ao]s"#)?, + integer_check_by_range!(2, 9999), + cycle_check!(), + |_, integer,cycle| helpers::cycle_n_not_immediate(cycle.value().grain, -1 * integer.value().value) + ); + // PAST (Date|Time) period + b.rule_4("o n last ", + b.reg(r#"n?[oa]s"#)?, + integer_check_by_range!(2, 9999), + b.reg(r#"últim[ao]s"#)?, + cycle_check!(), + |_, integer, _, cycle| helpers::cycle_n_not_immediate(cycle.value().grain, -1 * integer.value().value) + ); + // PAST (Date|Time) period + b.rule_3("n last ", + integer_check_by_range!(2, 9999), + b.reg(r#"últim[ao]s"#)?, + cycle_check!(), + |integer, _, cycle| helpers::cycle_n_not_immediate(cycle.value().grain, -1 * integer.value().value) + ); +// b.rule_2("last ", +// b.reg(r#"h[àá]"#)?, +// cycle_check!(), +// |_, cycle| helpers::cycle_nth(cycle.value().grain, -1) +// ); +// b.rule_3("in ", +// b.reg(r#"daqui a|dentro de"#)?, +// integer_check_by_range!(2, 9999), +// cycle_check!(), +// |_, integer, cycle| helpers::cycle_nth(cycle.value().grain, integer.value().value) +// ); +// b.rule_2("in ", +// b.reg(r#"daqui a|dentro de"#)?, +// cycle_check!(), +// |_, cycle| helpers::cycle_nth(cycle.value().grain, 1) +// ); Ok(()) } @@ -324,12 +504,14 @@ pub fn rules_time(b: &mut RuleSetBuilder) -> RustlingResult<()> { time_check!(|time: &TimeValue| !time.latent), |a, b| a.value().intersect(b.value()) ); - b.rule_3("intersect by `de`", - time_check!(|time: &TimeValue| !time.latent), - b.reg(r#"de"#)?, - time_check!(|time: &TimeValue| !time.latent), - |a, _, b| a.value().intersect(b.value()) - ); + +// b.rule_3("intersect by `de`", +// datetime_check!(|datetime: &DatetimeValue| !datetime.latent), +// b.reg(r#"d[eo]"#)?, +// datetime_check!(|datetime: &DatetimeValue| !datetime.latent), +// |a, _, b| a.value().intersect(b.value()) +// ); + b.rule_3("two time tokens separated by \",\"", time_check!(|time: &TimeValue| !time.latent), b.reg(r#","#)?, @@ -337,31 +519,31 @@ pub fn rules_time(b: &mut RuleSetBuilder) -> RustlingResult<()> { |a, _, b| a.value().intersect(b.value()) ); b.rule_1_terminal("named-day", - b.reg(r#"segunda(?:[- ]feira)?"#)?, + b.reg(r#"(segunda|2ª)(?:[- ]feira| f.)?"#)?, |_| helpers::day_of_week(Weekday::Mon) ); b.rule_1_terminal("named-day", - b.reg(r#"ter[cç]a(?:[- ]feira)?"#)?, + b.reg(r#"(ter[cç]a|3ª)(?:[- ]feira| f.)?"#)?, |_| helpers::day_of_week(Weekday::Tue) ); b.rule_1_terminal("named-day", - b.reg(r#"quarta(?:[- ]feira)?"#)?, + b.reg(r#"(quarta|4ª)(?:[- ]feira| f.)?"#)?, |_| helpers::day_of_week(Weekday::Wed) ); b.rule_1_terminal("named-day", - b.reg(r#"quinta(?:[- ]feira)?"#)?, + b.reg(r#"(quinta|5ª)(?:[- ]feira| f.)?"#)?, |_| helpers::day_of_week(Weekday::Thu) ); b.rule_1_terminal("named-day", - b.reg(r#"sexta(?:[- ]feira)?"#)?, + b.reg(r#"(sexta|6ª)(?:[- ]feira| f.)?"#)?, |_| helpers::day_of_week(Weekday::Fri) ); b.rule_1_terminal("named-day", - b.reg(r#"s[aá]bado"#)?, + b.reg(r#"s[aá]bado|s[aá]b."#)?, |_| helpers::day_of_week(Weekday::Sat) ); b.rule_1_terminal("named-day", - b.reg(r#"domingo"#)?, + b.reg(r#"domingo|dom."#)?, |_| helpers::day_of_week(Weekday::Sun) ); b.rule_1_terminal("named-month", @@ -413,34 +595,1153 @@ pub fn rules_time(b: &mut RuleSetBuilder) -> RustlingResult<()> { |_| helpers::month(12) ); b.rule_1_terminal("right now", - b.reg(r#"agora mesmo"#)?, + b.reg(r#"neste exato momento"#)?, |_| helpers::cycle_nth(Grain::Second, 0) ); b.rule_1_terminal("now", - b.reg(r#"agora"#)?, - |_| helpers::cycle_nth(Grain::Day, 0) + b.reg(r#"agora(?: mesmo)?|neste momento"#)?, + |_| helpers::cycle_nth(Grain::Second, 0) ); + // Date HOLIDAY + b.rule_1_terminal("Christmas", + b.reg(r#"(?:dia de )?natal"#)?, + |_| helpers::month_day(12, 25) + ); + // Date HOLIDAY + b.rule_1_terminal("New year's eve", + b.reg(r#"ano novo|primeiro dia do ano"#)?, + |_| Ok(helpers::month_day(1, 1)?.form(Form::Celebration)) + ); + // Date HOLIDAY + b.rule_1_terminal("Christmas", + b.reg(r#"véspera de natal|(?:a )?noite de natal"#)?, + |_| { + let start = helpers::month_day(12, 24)?.intersect(&helpers::hour(18, false)?)?; + let end = helpers::month_day(12, 25)?.intersect(&helpers::hour(0, false)?)?; + Ok(start.span_to(&end, false)? + .form(Form::Celebration)) + } + ); + // Date HOLIDAY + b.rule_1_terminal("All saint's day", + b.reg(r#"(?:(?:no )?dia de )?(?:todos os santos|finados)"#)?, + |_| Ok(helpers::month_day(11, 1)?.form(Form::Celebration)) + ); + // Date HOLIDAY + b.rule_1_terminal("1st of May", + b.reg(r#"dia do (?:trabalho|trabalhador)"#)?, + |_| Ok(helpers::month_day(5, 1)?.form(Form::Celebration)) + ); + // Date b.rule_1_terminal("today", b.reg(r#"hoje"#)?, |_| helpers::cycle_nth(Grain::Day, 0) ); + // Date b.rule_1_terminal("tomorrow", b.reg(r#"amanh[aã]"#)?, |_| helpers::cycle_nth(Grain::Day, 1) ); + // Date b.rule_1_terminal("yesterday", b.reg(r#"ontem"#)?, |_| helpers::cycle_nth(Grain::Day, -1) ); -// b.rule_1_terminal("the day after tomorrow", -// b.reg(r#""#)?, -// |_| helpers::cycle_nth(Grain::Day, 2) + // Date + b.rule_1_terminal("the day after tomorrow", + b.reg(r#"(?:o )?dia depois de amanhã"#)?, + |_| helpers::cycle_nth(Grain::Day, 2) + ); + // Date + b.rule_1_terminal("the day after tomorrow", + b.reg(r#"depois de amanhã"#)?, + |_| helpers::cycle_nth(Grain::Day, 2) + ); + // Date + b.rule_1_terminal("the day before yesterday", + b.reg(r#"anteontem"#)?, + |_| helpers::cycle_nth(Grain::Day, -2) + ); + // Date + b.rule_2("this ", //assumed to be in the future + b.reg(r#"n?est[ea]"#)?, + time_check!(form!(Form::DayOfWeek{..})), + |_, time| time.value().the_nth_not_immediate(0) + ); + // DateTime IS IT NECESSARY ? + b.rule_2("this ", + b.reg(r#"n?est[ea]|(?:n?[oa])? próxim[oa]"#)?, + time_check!(), + |_, time| time.value().the_nth(0) + ); + // Date period + b.rule_2("'prep'? month 'prep' ", + b.reg(r#"(?:o )?mês de"#)?, + time_check!(form!(Form::Month(_))), + |_, time| Ok(time.value().clone()) + ); + b.rule_2("month 'preposition' ", + b.reg(r#"mês de"#)?, + time_check!(form!(Form::Month(_))), + |_, a| Ok(a.value().clone()) + ); + // Date period + b.rule_2("this ", + b.reg(r#"d?est[ea]"#)?, + cycle_check!(), + |_, cycle| helpers::cycle_nth(cycle.value().grain, 0) + ); + b.rule_2("in ", + b.reg(r#"durante|em|para(?: [oa])?|n[oa]"#)?, + time_check!(), + |_, a| Ok(a.value().clone()) + ); + b.rule_2("in approximately (approximation)", + b.reg(r#"pela"#)?, + time_check!(|time: &TimeValue| form!(Form::PartOfDay(_))(time) || form!(Form::Meal)(time)), + |_, a| Ok(a.value().clone()) + ); +// b.rule_2("last