Skip to content

Commit 9f26a87

Browse files
authored
Merge pull request #203 from snipsco/fix/misc-issues
Fix various issues from the backlog, incl. float parsing
2 parents 44035de + 4e4c127 commit 9f26a87

30 files changed

+763
-509
lines changed

grammar/de/src/rules.rs

Lines changed: 76 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,12 @@ pub fn rules_duration(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
335335
b.reg(r#"fr[üu]her"#)?,
336336
|duration, _| duration.value().ago()
337337
);
338+
b.rule_2("seit <duration>",
339+
b.reg(r#"seit"#)?,
340+
duration_check!(),
341+
|_, duration| duration.value().ago()?
342+
.span_to(&helpers::cycle_nth(Grain::Second, 0)?, false)
343+
);
338344
b.rule_3("<duration> after <datetime>",
339345
duration_check!(),
340346
b.reg(r#"nach"#)?,
@@ -1089,26 +1095,42 @@ pub fn rules_datetime(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
10891095
b.rule_1("year",
10901096
integer_check_by_range!(1900, 2100),
10911097
|integer| {
1092-
helpers::year(integer.value().value as i32)
1098+
if integer.value().suffixed {
1099+
return Err(RuleError::Invalid.into())
1100+
} else {
1101+
helpers::year(integer.value().value as i32)
1102+
}
10931103
}
10941104
);
10951105
b.rule_2("year",
10961106
b.reg(r#"(?:de[rnms]|das|die) jahre?s?n?"#)?,
10971107
integer_check_by_range!(-1000, 2100),
10981108
|_, integer| {
1099-
helpers::year(integer.value().value as i32)
1109+
if integer.value().suffixed {
1110+
return Err(RuleError::Invalid.into())
1111+
} else {
1112+
helpers::year(integer.value().value as i32)
1113+
}
11001114
}
11011115
);
11021116
b.rule_1("year (latent)",
11031117
integer_check_by_range!(-1000, 1899),
11041118
|integer| {
1105-
Ok(helpers::year(integer.value().value as i32)?.latent())
1119+
if integer.value().suffixed {
1120+
return Err(RuleError::Invalid.into())
1121+
} else {
1122+
Ok(helpers::year(integer.value().value as i32)?.latent())
1123+
}
11061124
}
11071125
);
11081126
b.rule_1("year (latent)",
11091127
integer_check_by_range!(2101, 2200),
11101128
|integer| {
1111-
Ok(helpers::year(integer.value().value as i32)?.latent())
1129+
if integer.value().suffixed {
1130+
return Err(RuleError::Invalid.into())
1131+
} else {
1132+
Ok(helpers::year(integer.value().value as i32)?.latent())
1133+
}
11121134
}
11131135
);
11141136
b.rule_2("the <day-of-month> (ordinal)",
@@ -1254,50 +1276,50 @@ pub fn rules_datetime(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
12541276
);
12551277
b.rule_1_terminal("quarter (relative minutes)",
12561278
b.reg(r#"vie?rtel"#)?,
1257-
|_| Ok(RelativeMinuteValue(15))
1279+
|_| helpers::relative_minute_value(15)
12581280
);
12591281
b.rule_1_terminal("half (relative minutes)",
12601282
b.reg(r#"halbe?"#)?,
1261-
|_| Ok(RelativeMinuteValue(30))
1283+
|_| helpers::relative_minute_value(30)
12621284
);
12631285
b.rule_1_terminal("number (as relative minutes for minute=1)",
12641286
b.reg(r#"eins"#)?,
1265-
|_| Ok(RelativeMinuteValue(1))
1287+
|_| helpers::relative_minute_value(1)
12661288
);
12671289
b.rule_1("number (as relative minutes for minute>1)",
12681290
integer_check_by_range!(2, 59),
1269-
|integer| Ok(RelativeMinuteValue(integer.value().value as i32))
1291+
|integer| helpers::relative_minute_value(integer.value().value as i32)
12701292
);
12711293
b.rule_2("number <minutes> (as relative minutes)",
12721294
integer_check_by_range!(1, 59),
12731295
b.reg(r#"minuten?"#)?,
1274-
|a, _| Ok(RelativeMinuteValue(a.value().value as i32))
1296+
|a, _| helpers::relative_minute_value(a.value().value as i32)
12751297
);
12761298
b.rule_3("<hour-of-day> <integer> (as relative minutes)",
12771299
datetime_check!(|datetime: &DatetimeValue| !datetime.latent && form!(Form::TimeOfDay(TimeOfDayForm::Hour { .. }))(datetime)),
12781300
b.reg(r#"\s|und"#)?,
12791301
relative_minute_check!(),
1280-
|datetime, _, relative_minute| helpers::hour_relative_minute(
1302+
|datetime, _, relative_minutes| helpers::hour_relative_minute(
12811303
datetime.value().form_time_of_day()?.full_hour(),
1282-
relative_minute.value().0,
1304+
relative_minutes.value().value,
12831305
datetime.value().form_time_of_day()?.is_12_clock())
12841306
);
12851307
b.rule_3("relative minutes to|till|before <integer> (hour-of-day)",
12861308
relative_minute_check!(),
12871309
b.reg(r#"vor"#)?,
12881310
datetime_check!(form!(Form::TimeOfDay(TimeOfDayForm::Hour { .. }))),
1289-
|relative_minute, _, datetime| helpers::hour_relative_minute(
1311+
|relative_minutes, _, datetime| helpers::hour_relative_minute(
12901312
datetime.value().form_time_of_day()?.full_hour(),
1291-
-1 * relative_minute.value().0,
1313+
-1 * relative_minutes.value().value,
12921314
datetime.value().form_time_of_day()?.is_12_clock())
12931315
);
12941316
b.rule_3("relative minutes after|past <integer> (hour-of-day)",
12951317
relative_minute_check!(),
12961318
b.reg(r#"nach"#)?,
12971319
datetime_check!(form!(Form::TimeOfDay(TimeOfDayForm::Hour { .. }))),
1298-
|relative_minute, _, datetime| helpers::hour_relative_minute(
1320+
|relative_minutes, _, datetime| helpers::hour_relative_minute(
12991321
datetime.value().form_time_of_day()?.full_hour(),
1300-
relative_minute.value().0,
1322+
relative_minutes.value().value,
13011323
datetime.value().form_time_of_day()?.is_12_clock())
13021324
);
13031325
b.rule_2("viertel <integer> (german style hour-of-day)",
@@ -1695,37 +1717,44 @@ pub fn rules_datetime(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
16951717
friday.span_to(&monday, false)
16961718
}
16971719
);
1698-
b.rule_1_terminal("season",
1720+
b.rule_1_terminal("season - summer",
16991721
b.reg(r#"sommer(?:zeit|s)?"#)?,
17001722
|_| Ok(helpers::month_day(6, 21)?
17011723
.span_to(&helpers::month_day(9, 23)?, false)?
1702-
.form(Form::PartOfYear))
1724+
.form(Form::Season))
17031725
);
17041726
b.rule_1_terminal("Summer solstice",
17051727
b.reg(r#"sommersonn(?:en)?wende"#)?,
17061728
|_| Ok(helpers::month_day(6, 21)?.form(Form::Celebration).too_ambiguous())
17071729
);
1708-
b.rule_1_terminal("season",
1730+
b.rule_1_terminal("season - fall",
17091731
b.reg(r#"herbst(?:zeit|s|es)?|sp[äa]tjahr(?:es)?"#)?,
17101732
|_| Ok(helpers::month_day(9, 23)?
17111733
.span_to(&helpers::month_day(12, 21)?, false)?
1712-
.form(Form::PartOfYear))
1734+
.form(Form::Season))
17131735
);
1714-
b.rule_1_terminal("season",
1736+
b.rule_1_terminal("season - winter",
17151737
b.reg(r#"winter(?:zeit|s)?"#)?,
17161738
|_| Ok(helpers::month_day(12, 21)?
17171739
.span_to(&helpers::month_day(3, 20)?, false)?
1718-
.form(Form::PartOfYear))
1740+
.form(Form::Season))
1741+
);
1742+
b.rule_2("season - winter <year>",
1743+
b.reg(r#"winter(?:zeit|s)?"#)?,
1744+
datetime_check!(form!(Form::Year(_))),
1745+
|_, year| Ok(helpers::year_month_day(year.value().form_year()?, 12, 21)?
1746+
.span_to(&helpers::year_month_day(year.value().form_year()? + (1 as i32), 3, 20)?, false)?
1747+
.form(Form::Season))
17191748
);
17201749
b.rule_1_terminal("Winter solstice",
17211750
b.reg(r#"wintersonnwende"#)?,
17221751
|_| Ok(helpers::month_day(12, 21)?.form(Form::Celebration).too_ambiguous())
17231752
);
1724-
b.rule_1_terminal("season",
1753+
b.rule_1_terminal("season - spring",
17251754
b.reg(r#"(?:fr[üu]hlings?|fr[üu]hjahr(?:es)?)(?:zeit)?"#)?,
17261755
|_| Ok(helpers::month_day(3, 20)?
17271756
.span_to(&helpers::month_day(6, 21)?, false)?
1728-
.form(Form::PartOfYear))
1757+
.form(Form::Season))
17291758
);
17301759
b.rule_2("im <part-of-year>",
17311760
b.reg(r#"(?:(?:in )?(?:de[nrms]|die|das)|im|ins)"#)?,
@@ -1849,11 +1878,23 @@ pub fn rules_datetime(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
18491878
// |_, datetime| Ok(datetime.value().clone().mark_before_end_all())
18501879
// );
18511880
b.rule_2("before <datetime>",
1852-
b.reg(r#"vor(?: de[nmr]| )|bis(?:(?: zu[rm]?(?: den)?)| in d(?:en|ie|as))?"#)?,
1881+
b.reg(r#"vor(?: de[nmr])?"#)?,
18531882
datetime_check!(excluding_form!(Form::PartOfForm(_))),
18541883
|_, datetime| Ok(datetime.value().clone().mark_before_start())
18551884
);
18561885

1886+
b.rule_2("until <datetime>",
1887+
b.reg(r#"bis(?:(?: zu[rm]?(?: de[nmr])?))?"#)?,
1888+
datetime_check!(|datetime: &DatetimeValue| excluding_form!(Form::PartOfForm(_))(datetime) && excluding_form!(Form::TimeOfDay(_))(datetime)),
1889+
|_, datetime| Ok(datetime.value().clone().mark_before_end_all())
1890+
);
1891+
1892+
b.rule_2("until <time-of-day>",
1893+
b.reg(r#"bis"#)?,
1894+
datetime_check!(|datetime: &DatetimeValue| excluding_form!(Form::PartOfForm(_))(datetime) && form!(Form::TimeOfDay(_))(datetime)),
1895+
|_, datetime| Ok(datetime.value().clone().mark_before_end())
1896+
);
1897+
18571898
b.rule_2("before <part-of-form> (specific cases)",
18581899
b.reg(r#"vor(?: de[nmr]| )|bis(?:(?: zu[rm]?(?: den)?)| in d(?:en|ie|as))?"#)?,
18591900
datetime_check!(form!(Form::PartOfForm(_))),
@@ -2287,28 +2328,26 @@ pub fn rules_numbers(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
22872328
|text_match| FloatValue::new(text_match.group(1).replace(",", ".").parse()?)
22882329
);
22892330
b.rule_3("number dot number",
2290-
number_check!(|number: &NumberValue| !number.prefixed()),
2331+
integer_check!(|integer: &IntegerValue| !integer.prefixed),
22912332
b.reg(r#"komma"#)?,
2292-
number_check!(|number: &NumberValue| !number.suffixed()),
2333+
integer_check!(|integer: &IntegerValue| !integer.suffixed),
22932334
|a, _, b| {
2294-
let power = b.value().value().to_string().chars().count();
2295-
let coeff = 10.0_f32.powf(-1.0 * power as f32);
2335+
let value: f64 = format!("{}.{}", a.value().value, b.value().value).parse()?;
22962336
Ok(FloatValue {
2297-
value: b.value().value() * coeff + a.value().value(),
2337+
value,
22982338
..FloatValue::default()
22992339
})
2300-
}
2301-
);
2340+
});
23022341
b.rule_4("number dot zero ... number",
2303-
number_check!(|number: &NumberValue| !number.prefixed()),
2342+
integer_check!(|integer: &IntegerValue| !integer.prefixed),
23042343
b.reg(r#"komma"#)?,
23052344
b.reg(r#"(?:(?:null )*(?:null))"#)?,
2306-
number_check!(|number: &NumberValue| !number.suffixed()),
2345+
integer_check!(|integer: &IntegerValue| !integer.suffixed),
23072346
|a, _, zeros, b| {
2308-
let power = zeros.group(0).split_whitespace().count() + b.value().value().to_string().chars().count();
2309-
let coeff = 10.0_f32.powf(-1.0 * power as f32);
2347+
let zeros_string = std::iter::repeat("0").take(zeros.group(0).split_whitespace().count()).collect::<String>();
2348+
let value: f64 = format!("{}.{}{}", a.value().value, zeros_string, b.value().value).parse()?;
23102349
Ok(FloatValue {
2311-
value: b.value().value() * coeff + a.value().value(),
2350+
value,
23122351
..FloatValue::default()
23132352
})
23142353
});
@@ -2383,7 +2422,7 @@ pub fn rules_numbers(b: &mut RuleSetBuilder<Dimension>) -> RustlingResult<()> {
23832422
.into()
23842423
}
23852424
NumberValue::Float(float) => {
2386-
let product = float.value * (multiplier as f32);
2425+
let product = float.value * (multiplier as f64);
23872426
if product.floor() == product {
23882427
IntegerValue {
23892428
value: product as i64,

grammar/de/src/training.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ pub fn examples_datetime(v: &mut Vec<::rustling::train::Example<Dimension>>) {
185185
example!(v, check_moment!(c, [2013, 12]), "ein jahr nach weihnachten");
186186
example!(v, check_moment_span!(c, [2013, 6, 21], [2013, 9, 24]), "diesen sommer");
187187
example!(v, check_moment_span!(c, [2012, 12, 21], [2013, 3, 21]), "diesen winter");
188+
example!(v, check_moment!(c, [2014, 6, 1], Grain::Month), "juni 2014", "in juni 2014");
189+
example!(v, check_moment!(c, [2005, 5, 1], Grain::Month), "mai 2005", "in mai 2005");
190+
example!(v, check_moment_span!(c, [2014, 6, 21], [2014, 9, 24]), "sommer 2014", "in sommer 2014");
191+
example!(v, check_moment_span!(c, [2014, 12, 21], [2015, 3, 21]), "winter 2014", "in winter 2014");
188192
example!(v, check_moment!(c, [2013, 12, 25]), "Weihnachten", "Weihnachtstag");
189193
example!(v, check_moment!(c, [2013, 12, 31]), "Silvester");
190194
example!(v, check_moment!(c, [2014, 1, 1]), "Neujahrstag", "Neujahr");
@@ -286,7 +290,8 @@ pub fn examples_datetime(v: &mut Vec<::rustling::train::Example<Dimension>>) {
286290
example!(v, check_moment!(c, [2013, 2, 12, 13, 44]), "ein uhr und vierundvierzig minuten");
287291
example!(v, check_moment_span!(c, [2013, 2, 11, 1, 9], [2013, 2, 11, 3, 25]), "gestern zwischen ein uhr und neun minuten und drei uhr und fünfundzwanzig minuten");
288292
example!(v, check_moment_span!(c, [2013, 2, 13, 00, 45], [2013, 2, 13, 1, 00]), "zwischen dreiviertel eins und ein uhr morgen");
289-
example!(v, check_moment_with_direction!(c, [2013, 2, 14], Direction::Before), "bis Donnerstag");
293+
example!(v, check_moment_with_direction!(c, [2013, 2, 14], Direction::Before), "vor Donnerstag");
294+
example!(v, check_moment_with_direction!(c, [2013, 2, 15], Direction::Before), "bis Donnerstag");
290295

291296
}
292297

@@ -304,6 +309,8 @@ pub fn examples_numbers(v: &mut Vec<::rustling::train::Example<Dimension>>) {
304309
example!(v, check_integer(102), "102", "hundert zwei");
305310
example!(v, check_float(1.1), "1,1", "1 komma 1", "1,10", "01,10");
306311
example!(v, check_float(0.77), "0,77", ",77");
312+
example!(v, check_float(0.3), "0,3", "null komma drei");
313+
example!(v, check_float(0.03), "0,03", "null komma null drei");
307314
example!(v, check_integer(100000), "100.000", "100000", "100K", "100k");
308315
example!(v, check_integer(3000000), "3M", "3000K", "3000000", "3.000.000");
309316
example!(v, check_integer(1200000), "1.200.000", "1200000", "1,2M", "1200K", ",0012G");

0 commit comments

Comments
 (0)