Skip to content

Commit

Permalink
Refactor lexer and parser structs to use lifetimes for input references.
Browse files Browse the repository at this point in the history
  • Loading branch information
DaviRain-Su committed Oct 10, 2023
1 parent 7c6d0cc commit 9ab0620
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 16 deletions.
10 changes: 5 additions & 5 deletions src/lexer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ mod tests;
/// 始终指向所输入字符串中的“下一个”字符,position 则指向所输入字符串中与 ch
/// 字节对应的字符。
#[derive(Debug, Default, Clone)]
pub struct Lexer {
input: String,
pub struct Lexer<'a> {
input: &'a str,
position: usize, // 所输入字符串中的当前位置(指向当前字符)
read_position: usize, // 所输入字符串中的当前读取位置(指向当前字符之后的一个字符)
ch: char, // 当前正在查看的字符
}

impl Lexer {
pub fn new(input: &str) -> anyhow::Result<Self> {
impl<'a> Lexer<'a> {
pub fn new(input: &'a str) -> anyhow::Result<Self> {
let mut lexer = Self {
input: String::from(input),
input,
..Default::default()
};

Expand Down
22 changes: 11 additions & 11 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,31 @@ use std::collections::HashMap;
/// 前缀解析函数
/// 前缀运算符左侧为空。
/// 在前缀位置遇到关联的词法单元类型时会调用 prefixParseFn
type PrefixParseFn = fn(&mut Parser) -> anyhow::Result<Expression>;
type PrefixParseFn<'a> = fn(&mut Parser<'a>) -> anyhow::Result<Expression>;

/// 中缀解析函数
/// infixParseFn 接受另一个 ast.Expression 作为参数。该参数是所解析的中缀运算符
/// 左侧的内容。
/// 在中缀位置遇到词法单元类型时会调用 infixParseFn
type InferParseFn = fn(&mut Parser, Expression) -> anyhow::Result<Expression>;
type InferParseFn<'a> = fn(&mut Parser<'a>, Expression) -> anyhow::Result<Expression>;

#[derive(Clone)]
pub struct Parser {
pub struct Parser<'a> {
/// lexer 是指向词法分析器实例的指针,在该实例上重复调用NextToken()能不断获取输入中的下一个词法单元
lexer: Lexer,
lexer: Lexer<'a>,
/// curToken和 peekToken 的行为与词法分析器中的两个“指针”position 和 readPosition 完全
/// 相同,但它们分别指向输入中的当前词法单元和下一个词法单元,而不是输入中的字
/// 符。查看 curToken(当前正在检查的词法单元)是为了决定下
/// 一步该怎么做,如果 curToken 没有提供足够的信息,还需要根据 peekToken 来做决
/// 策。
current_token: Token,
peek_token: Token,
prefix_parse_fns: HashMap<TokenType, PrefixParseFn>,
infix_parse_fns: HashMap<TokenType, InferParseFn>,
prefix_parse_fns: HashMap<TokenType, PrefixParseFn<'a>>,
infix_parse_fns: HashMap<TokenType, InferParseFn<'a>>,
}

impl Parser {
pub fn new(lexer: Lexer) -> anyhow::Result<Self> {
impl<'a> Parser<'a> {
pub fn new(lexer: Lexer<'a>) -> anyhow::Result<Self> {
let mut parser = Parser {
lexer,
current_token: Token::default(),
Expand Down Expand Up @@ -100,7 +100,7 @@ impl Parser {
}

// TODO 因为使用 PrefixParseFn 和InferParseFn 的原因,其中的第一个参数是parser
fn update_parser(&mut self, parse: Parser) {
fn update_parser(&mut self, parse: Parser<'a>) {
self.lexer = parse.lexer;
self.current_token = parse.current_token;
self.peek_token = parse.peek_token;
Expand Down Expand Up @@ -670,12 +670,12 @@ impl Parser {
}

/// register prefix
fn register_prefix(&mut self, token_type: TokenType, prefix_parse_fn: PrefixParseFn) {
fn register_prefix(&mut self, token_type: TokenType, prefix_parse_fn: PrefixParseFn<'a>) {
self.prefix_parse_fns.insert(token_type, prefix_parse_fn);
}

/// register infix
fn register_infix(&mut self, token_type: TokenType, infix_parse_fn: InferParseFn) {
fn register_infix(&mut self, token_type: TokenType, infix_parse_fn: InferParseFn<'a>) {
self.infix_parse_fns.insert(token_type, infix_parse_fn);
}
}

0 comments on commit 9ab0620

Please sign in to comment.