Lexeur (logos)
Pour écrire un lexeur facilement, on utilise la crate logos
.
Cette crate fournit une macro procédurale qu'on peut appliquer à un enumération. Chaque variante de l'énumération est un token possible, et on les annote avec un attribut indiquant comment reconnaître ce token.
use logos::Logos; // on importe la macro #[derive(Logos)] // on l'utilise pour générer le code du lexeur enum Token { #[token("let")] Let, #[token("function")] Function, #[regex(r"[ \t\n\f]+", logos::skip)] Space, // etc. } fn main() { // la fonction Token::lexer est générée par logos let mut lexer = Token::lexer("let let function let"); // lexer est un itérateur, donc on peut récupérer la liste de tous les // tokens avec un collect let tokens: Vec<_> = lexer.collect(); assert_eq!( tokens, vec![ Token::Let, Token::Let, Token::Function, Token::Let ], ); }
Pour les différents attributs disponibles, voir la documentation de logos.
Normalement le lexeur est complet, mais si besoin d'autres tokens pourront être ajoutés.
Attention, beaucoup de variantes de l'énumaration Token
ne sont en fait pas des tokens
qu'on peut retrouver dans le code source, mais des étiquettes pour l'arbre de syntaxe
(cf. le chapitre suivant). Seuls ceux avec un attribut de logos sont de vrais tokens.
Limitations
TODO