Reconnaissance des commentaires, des chaînes et des nombres
This commit is contained in:
@@ -10,6 +10,10 @@ struct Scanner {
|
|||||||
line: u32,
|
line: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_digit( c: char ) -> bool {
|
||||||
|
c>='0' && c<='9'
|
||||||
|
}
|
||||||
|
|
||||||
impl Scanner {
|
impl Scanner {
|
||||||
fn scan_tokens(&mut self) {
|
fn scan_tokens(&mut self) {
|
||||||
while !self.is_at_end() {
|
while !self.is_at_end() {
|
||||||
@@ -38,11 +42,30 @@ impl Scanner {
|
|||||||
'+' => self.add_simple_token( TokenType::Plus ),
|
'+' => self.add_simple_token( TokenType::Plus ),
|
||||||
';' => self.add_simple_token( TokenType::Semicolon ),
|
';' => self.add_simple_token( TokenType::Semicolon ),
|
||||||
'*' => self.add_simple_token( TokenType::Star ),
|
'*' => self.add_simple_token( TokenType::Star ),
|
||||||
'!' => { if self.matchnext('=') { self.add_simple_token( TokenType::BangEqual ) } else { self.add_simple_token( TokenType::Bang ) } },
|
'!' => { if self.match_next('=') { 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.match_next('=') { 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.match_next('=') { 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 ) } },
|
'>' => { if self.match_next('=') { self.add_simple_token( TokenType::GreaterEqual ) } else { self.add_simple_token( TokenType::Greater ) } },
|
||||||
_ => (), // report error
|
'/' => { 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]
|
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.is_at_end() { return false; }
|
||||||
if self.source[self.current]!=expected { return false; }
|
if self.source[self.current]!=expected { return false; }
|
||||||
|
|
||||||
@@ -59,6 +82,22 @@ impl Scanner {
|
|||||||
true
|
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) {
|
fn add_simple_token(&mut self, t: TokenType) {
|
||||||
self.add_token(t, String::from(""));
|
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 } );
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user