用rust写一个玩具解释器3

我们两清 提交于 2020-02-06 12:49:42

项目目录

项目地址
项目目录
画质有点渣
其实不应该创建太多的包,因为里面其实只有一个有效文件(mod.rs和test.rs算是辅助) . 所以说目录可以更简单一些.

token

在上文中提到了把token看为字符串, 而其大致分为两种.

  1. 我们预先定义的
    比如 +,-,*,/,if,return,fn和let等
  2. 留给用户的
    比如: 变量名,整数
//token/token.rs
//不想下载第三方包, 所以这样子是一个可接受的选择
use std::collections::HashMap;
pub fn lookup_ident(ident:& String) -> TokenType {
    let  mmap: HashMap<String,TokenType> = {
        let mut  map = HashMap::new();
        map.insert("fn".to_string(), FUNCTION);
        map.insert("let".to_string(), LET);
        map.insert("true".to_string(),TRUE);
        map.insert("false".to_string(),FALSE);
        map.insert("if".to_string(), IF);
        map.insert("else".to_string(),ELSE);
        map.insert("return".to_string(), RETURN);
        map
    };
    mmap.get(ident).unwrap_or(&IDENT)
}


pub const ILLEGAL: &'static str  =  "ILLEGAL";
pub const EOF: &'static str =  "EOF";

//identifier + literal
pub const IDENT :&'static str =  "IDENT";
pub const INT :&'static str =  "INT";

// operator
pub const ASSIGN :&'static str =  "=";
pub const PLUS :&'static str =  "+";
pub const MINUS :&'static str = "-";
pub const BANG:&'static str = "!";
pub const ASTERISK :&'static str = "*";
pub const SLASH: &'static str =  "/";
pub const LT :&'static str = "<";
pub const GT :&'static str = ">";
pub const EQ :&'static str = "==";
pub const NOT_EQ :&'static str = "!=";
//delimiters
pub const COMMA :&'static str =  ",";
pub const SEMICOLON :&'static str =  ";";

pub const LPAREN :&'static str =  "(";
pub const RPAREN :&'static str =  ")";
pub const LBRACE :&'static str =  "{";
pub const RBRACE :&'static str =  "}";

//keywords
pub const FUNCTION : &'static str = "FUNCTION";
pub const LET : &'static str = "LET";
pub const TRUE : &'static str = "TRUE";
pub const FALSE : &'static str = "FALSE";
pub const IF : &'static str = "IF";
pub const ELSE : &'static str = "ELSE";
pub const RETURN : &'static str = "RETURN";


pub type TokenType  =  &'static str;

//支持clone是为了不去思考太多的所有权概念
#[derive(Debug,Clone,PartialEq)]
pub struct Token {
    pub Type: TokenType,
    pub Literal:String, 
}


impl Token {
    pub fn new(token_type: TokenType, ch: char) -> Token {
        Token {
            Type:token_type, 
            Literal: ch.to_string(),
        }
    }
    pub fn default() -> Token {
        Token {
            Type:ILLEGAL, 
            Literal: String::new(),
        }
    }
    pub fn new_with_string<S: Into<String>>(token_type: TokenType, string: S) -> Token {
        Token { 
            Type: token_type,
            Literal: string.into(),
        }
    }
}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!