From 3fd9f2bd3abaa16b77be0614ec0b498eb43cd349 Mon Sep 17 00:00:00 2001 From: Emmanuel BERNAT Date: Wed, 3 Apr 2024 08:27:23 +0200 Subject: [PATCH] =?UTF-8?q?Reconnaissance=20des=20commentaires,=20des=20ch?= =?UTF-8?q?a=C3=AEnes=20et=20des=20nombres?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/rlox/scanner.rs | 83 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/src/rlox/scanner.rs b/src/rlox/scanner.rs index 3e2d943..98caaa8 100644 --- a/src/rlox/scanner.rs +++ b/src/rlox/scanner.rs @@ -10,6 +10,10 @@ struct Scanner { line: u32, } +fn is_digit( c: char ) -> bool { + c>='0' && c<='9' +} + impl Scanner { fn scan_tokens(&mut self) { while !self.is_at_end() { @@ -38,11 +42,30 @@ impl Scanner { '+' => self.add_simple_token( TokenType::Plus ), ';' => self.add_simple_token( TokenType::Semicolon ), '*' => self.add_simple_token( TokenType::Star ), - '!' => { if self.matchnext('=') { self.add_simple_token( TokenType::BangEqual ) } else { self.add_simple_token( TokenType::Bang ) } }, - '=' => { if self.matchnext('=') { self.add_simple_token( TokenType::EqualEqual ) } else { self.add_simple_token( TokenType::Equal ) } }, - '<' => { if self.matchnext('=') { self.add_simple_token( TokenType::LessEqual ) } else { self.add_simple_token( TokenType::Less ) } }, - '>' => { if self.matchnext('=') { self.add_simple_token( TokenType::GreaterEqual ) } else { self.add_simple_token( TokenType::Greater ) } }, - _ => (), // report error + '!' => { if self.match_next('=') { self.add_simple_token( TokenType::BangEqual ) } else { self.add_simple_token( TokenType::Bang ) } }, + '=' => { if self.match_next('=') { self.add_simple_token( TokenType::EqualEqual ) } else { self.add_simple_token( TokenType::Equal ) } }, + '<' => { if self.match_next('=') { self.add_simple_token( TokenType::LessEqual ) } else { self.add_simple_token( TokenType::Less ) } }, + '>' => { if self.match_next('=') { self.add_simple_token( TokenType::GreaterEqual ) } else { self.add_simple_token( TokenType::Greater ) } }, + '/' => { if self.match_next('/') { + // commentaire : avance jusqu'à la fin de la ligne sans ajouter de token + while self.peek()!='\n' && !self.is_at_end() { + self.advance(); + } + } else { + self.add_simple_token( TokenType::Slash ) } + }, + ' ' => (), + '\r' => (), + '\t' => (), + '\n' => self.line += 1, + '"' => self.string(), + _ => { + if is_digit(c) { + self.number(); + } else { + // Erreur : lexeme inconnu + } + } } } @@ -51,7 +74,7 @@ impl Scanner { self.source[self.current] } - fn matchnext(&mut self, expected: char) -> bool { + fn match_next(&mut self, expected: char) -> bool { if self.is_at_end() { return false; } if self.source[self.current]!=expected { return false; } @@ -59,6 +82,22 @@ impl Scanner { true } + fn peek(&self) -> char { + if self.is_at_end() { + '\0' + } else { + self.source[self.current] + } + } + + fn peek_next(&self) -> char { + if self.current+1 >= self.source.len() { + '\0' + } else { + self.source[self.current + 1] + } + } + fn add_simple_token(&mut self, t: TokenType) { self.add_token(t, String::from("")); } @@ -68,4 +107,36 @@ impl Scanner { self.tokens.push(Token{ token_type: t, lexeme: text, literal: l, line: self.line } ); } + fn string(&mut self) { + // Consomme les caractères jusqu'à trouver le délimiteur de chaînes ou la fin du fichier + while self.peek()!='"' && !self.is_at_end() { + if self.peek()=='\n' { + self.line += 1; // les chaînes peuvent être multilignes + } + self.advance(); + } + + if self.is_at_end() { + // Erreur : chaîne non terminée + return; + } + + self.advance(); // Consomme le délimiteur final + + self.add_token( TokenType::String, self.source[self.start+1..self.current-1].into_iter().collect() ); + } + + fn number(&mut self) { + while is_digit(self.peek()) { + self.advance(); + } + + if self.peek()=='.' && is_digit(self.peek_next()) { + while is_digit(self.peek()) { + self.advance(); + } + } + + self.add_token( TokenType::Number, self.source[self.start..self.current].into_iter().collect() ); // Il faudra faire un parse sur la chaîne pour connaître la valeur effective + } } \ No newline at end of file