Skip to content

Commit 2ccee2c

Browse files
Merge pull request #21 from djmattyg007/more_operators_in_lexer
Further improvements to operator parsing in lexer
2 parents 99943ec + 59b2038 commit 2ccee2c

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
## Next
22
- Add operator words `plus`, `minus` and `times`
3+
- Add operator phrases `multiplied by` and `divided by`
4+
- Add operator symbol `÷`
35
- Disallow named number followed by smaller named number (like 1 million thousand)
46
- Fix/improve parsing of multi-word units
57
- Fix light second parsed as light year
68
- Fix `Ω` lexing
9+
- Fix lexing of rpm units
710

811
## 1.6.0 - 2021 Jul 3
912
- Add support for non-US "metre" and "litre" spellings

src/lexer.rs

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::UnaryOperator::{Percent, Factorial};
77
use crate::TextOperator::{Of, To};
88
use crate::NamedNumber::*;
99
use crate::Constant::{E, Pi};
10-
use crate::LexerKeyword::{In, PercentChar, Per, Mercury, Hg, PoundForce, Force, DoubleQuotes};
10+
use crate::LexerKeyword::{In, PercentChar, Per, Mercury, Hg, PoundForce, Force, DoubleQuotes, Revolution};
1111
use crate::FunctionIdentifier::{Cbrt, Ceil, Cos, Exp, Abs, Floor, Ln, Log, Round, Sin, Sqrt, Tan};
1212
use crate::units::Unit;
1313
use crate::units::Unit::*;
@@ -121,7 +121,7 @@ fn parse_token(c: &str, lexer: &mut Lexer) -> Result<(), String> {
121121
"+" => tokens.push(Token::Operator(Plus)),
122122
"-" => tokens.push(Token::Operator(Minus)),
123123
"*" => tokens.push(Token::Operator(Multiply)),
124-
"/" => tokens.push(Token::Operator(Divide)),
124+
"/" | "÷" => tokens.push(Token::Operator(Divide)),
125125
"%" => tokens.push(Token::LexerKeyword(PercentChar)),
126126
"^" => tokens.push(Token::Operator(Caret)),
127127
"!" => tokens.push(Token::UnaryOperator(Factorial)),
@@ -186,6 +186,18 @@ fn parse_word(word: &str, lexer: &mut Lexer) -> Result<(), String> {
186186
"plus" => Token::Operator(Plus),
187187
"minus" => Token::Operator(Minus),
188188
"times" => Token::Operator(Multiply),
189+
"multiplied" => {
190+
match read_word("", lexer).as_str() {
191+
"by" => Token::Operator(Multiply),
192+
string => return Err(format!("Invalid string: {}", string)),
193+
}
194+
},
195+
"divided" => {
196+
match read_word("", lexer).as_str() {
197+
"by" => Token::Operator(Divide),
198+
string => return Err(format!("Invalid string: {}", string)),
199+
}
200+
},
189201
"mod" => Token::Operator(Modulo),
190202

191203
"sqrt" => Token::FunctionIdentifier(Sqrt),
@@ -565,7 +577,8 @@ fn parse_word(word: &str, lexer: &mut Lexer) -> Result<(), String> {
565577
"ghz" | "gigahertz" => Token::Unit(Gigahertz),
566578
"thz" | "terahertz" => Token::Unit(Terahertz),
567579
"phz" | "petahertz" => Token::Unit(Petahertz),
568-
"rpm" | "r/min" | "rev/min" => Token::Unit(RevolutionsPerMinute),
580+
"rpm" => Token::Unit(RevolutionsPerMinute),
581+
"r" | "rev" | "revolution" | "revolutions" => Token::LexerKeyword(Revolution),
569582

570583
"kph" | "kmh" => Token::Unit(KilometersPerHour),
571584
"mps" => Token::Unit(MetersPerSecond),
@@ -753,6 +766,10 @@ pub fn lex(input: &str, remove_trailing_operator: bool, default_degree: Unit) ->
753766
(Token::Unit(Inch), Token::TextOperator(Of), Token::LexerKeyword(Mercury)) => {
754767
tokens[token_index-2] = Token::Unit(InchOfMercury);
755768
},
769+
// revolutions per minute
770+
(Token::LexerKeyword(Revolution), Token::LexerKeyword(Per), Token::Unit(Minute)) => {
771+
tokens[token_index-2] = Token::Unit(RevolutionsPerMinute);
772+
},
756773
_ => {
757774
replaced = false;
758775
},
@@ -927,15 +944,15 @@ mod tests {
927944
run_lex("20 lbf", vec![numtok!(20), Token::LexerKeyword(PoundForce)]);
928945
run_lex("60 hz", vec![numtok!(60), Token::Unit(Hertz)]);
929946
run_lex("1100 rpm", vec![numtok!(1100), Token::Unit(RevolutionsPerMinute)]);
930-
// run_lex("1150 revolutions per minute", vec![numtok!(1150), Token::Unit(RevolutionsPerMinute)]);
931-
// run_lex("1 revolution per min", vec![numtok!(1), Token::Unit(RevolutionsPerMinute)]);
932-
// run_lex("4 revolution / mins", vec![numtok!(4), Token::Unit(RevolutionsPerMinute)]);
933-
// run_lex("1250 r / min", vec![numtok!(1250), Token::Unit(RevolutionsPerMinute)]);
934-
// run_lex("1300 rev / min", vec![numtok!(1300), Token::Unit(RevolutionsPerMinute)]);
935-
// run_lex("1350 rev / minute", vec![numtok!(1350), Token::Unit(RevolutionsPerMinute)]);
936-
// run_lex("1250 r per min", vec![numtok!(1250), Token::Unit(RevolutionsPerMinute)]);
937-
// run_lex("1300 rev per min", vec![numtok!(1300), Token::Unit(RevolutionsPerMinute)]);
938-
// run_lex("1350 rev per minute", vec![numtok!(1350), Token::Unit(RevolutionsPerMinute)]);
947+
run_lex("1150 revolutions per minute", vec![numtok!(1150), Token::Unit(RevolutionsPerMinute)]);
948+
run_lex("1 revolution per min", vec![numtok!(1), Token::Unit(RevolutionsPerMinute)]);
949+
run_lex("4 revolution / mins", vec![numtok!(4), Token::Unit(RevolutionsPerMinute)]);
950+
run_lex("1250 r / min", vec![numtok!(1250), Token::Unit(RevolutionsPerMinute)]);
951+
run_lex("1300 rev / min", vec![numtok!(1300), Token::Unit(RevolutionsPerMinute)]);
952+
run_lex("1350 rev / minute", vec![numtok!(1350), Token::Unit(RevolutionsPerMinute)]);
953+
run_lex("1250 r per min", vec![numtok!(1250), Token::Unit(RevolutionsPerMinute)]);
954+
run_lex("1300 rev per min", vec![numtok!(1300), Token::Unit(RevolutionsPerMinute)]);
955+
run_lex("1350 rev per minute", vec![numtok!(1350), Token::Unit(RevolutionsPerMinute)]);
939956
run_lex("100 kph", vec![numtok!(100), Token::Unit(KilometersPerHour)]);
940957
run_lex("100 kmh", vec![numtok!(100), Token::Unit(KilometersPerHour)]);
941958
run_lex("100 kilometers per hour", vec![numtok!(100), Token::Unit(KilometersPerHour)]);
@@ -965,10 +982,11 @@ mod tests {
965982
run_lex("12 minus 4", vec![numtok!(12), Token::Operator(Minus), numtok!(4)]);
966983
run_lex("50.5 * 2", vec![numtok!(50.5), Token::Operator(Multiply), numtok!(2)]);
967984
run_lex("50.5 times 2", vec![numtok!(50.5), Token::Operator(Multiply), numtok!(2)]);
968-
// run_lex("50.5 multiplied by 2", vec![numtok!(50.5), Token::Operator(Multiply), numtok!(2)]);
985+
run_lex("50.5 multiplied by 2", vec![numtok!(50.5), Token::Operator(Multiply), numtok!(2)]);
969986
run_lex("6 / 3", vec![numtok!(6), Token::Operator(Divide), numtok!(3)]);
970987
run_lex("50 / 10", vec![numtok!(50), Token::Operator(Divide), numtok!(10)]);
971-
// run_lex("6 divided by 3", vec![numtok!(6), Token::Operator(Divide), numtok!(3)]);
988+
run_lex("52 ÷ 12", vec![numtok!(52), Token::Operator(Divide), numtok!(12)]);
989+
run_lex("6 divided by 3", vec![numtok!(6), Token::Operator(Divide), numtok!(3)]);
972990
run_lex("7 mod 5", vec![numtok!(7), Token::Operator(Modulo), numtok!(5)]);
973991

974992
run_lex("(2 + 3) * 4", vec![Token::Operator(LeftParen), numtok!(2), Token::Operator(Plus), numtok!(3), Token::Operator(RightParen), Token::Operator(Multiply), numtok!(4)]);

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub enum LexerKeyword {
175175
Hg,
176176
PoundForce,
177177
Force,
178+
Revolution,
178179
}
179180

180181
#[derive(Clone, Debug, PartialEq)]

0 commit comments

Comments
 (0)