summaryrefslogtreecommitdiff
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/parser.rs b/src/parser.rs
new file mode 100644
index 0000000..fe414b0
--- /dev/null
+++ b/src/parser.rs
@@ -0,0 +1,91 @@
+extern crate core;
+use core::str::Chars;
+
+#[derive(Debug, PartialEq)]
+pub enum Token {
+ Number(i32),
+ Plus,
+ Minus,
+ Multiply,
+ Divide,
+}
+
+pub struct Lexer<'a> {
+ chars: Chars<'a>,
+}
+
+impl<'a> Lexer<'a> {
+ // Constructor
+ pub fn new(input: &'a str) -> Self {
+ Lexer { chars: input.chars() }
+}
+
+ fn next_token(&mut self) -> Option<Token> {
+ let next_char = self.chars.next()?;
+
+ match next_char {
+ '+' => Some(Token::Plus),
+ '-' => Some(Token::Minus),
+ '*' => Some(Token::Multiply),
+ '/' => Some(Token::Divide),
+ '1'..='9' => {
+ let mut number = next_char.to_digit(10)? as i32;
+ while let Some(next_char) = self.chars.clone().next() {
+ if let Some(digit) = next_char.to_digit(10) {
+ number = number * 10 + digit as i32;
+ self.chars.next();
+ } else {
+ break;
+ }
+ }
+ Some(Token::Number(number))
+ }
+ '0' => {
+ let base = match self.chars.next().unwrap() {
+ 'b' => Some(2),
+ 'o' => Some(8),
+ 'x' => Some(16),
+ _ => None,
+ };
+ if base.is_none() {
+ return None;
+ }
+
+ let mut number = next_char.to_digit(base.clone().unwrap())?;
+ while let Some(next_char) = self.chars.clone().next() {
+ if let Some(digit) = next_char.to_digit(base.clone().unwrap()) {
+ number = number * base.clone().unwrap() + digit;
+ self.chars.next();
+ } else {
+ break;
+ }
+ }
+ Some(Token::Number(number as i32))
+ }
+ _ => None,
+ }
+ }
+
+ pub fn tokenize(&mut self) -> Vec<Token> {
+ let mut tokens = Vec::new();
+ while let Some(token) = self.next_token() {
+ tokens.push(token);
+ }
+ tokens
+ }
+}
+
+fn main() {
+ let mut lexer = Lexer::new("0x6A+0b001101*0o13");
+ let tokens = lexer.tokenize();
+ assert_eq!(
+ tokens,
+ vec![
+ Token::Number(106),
+ Token::Plus,
+ Token::Number(13),
+ Token::Multiply,
+ Token::Number(11),
+ ]
+ );
+} \ No newline at end of file