1. 程式人生 > >詞法分析器

詞法分析器

詞法分析器

函式

  • skip_one_line: 跳過一行, 會在skip_comment中註釋為//的時候呼叫
  • skip_comment: // 和 /**/
  • skip_blanks: 跳過空白行, 會在skip_comment處理完註釋之後呼叫, 同時在get_next_token這個核心的詞法分析器的介面函式中呼叫防止獲取到的token含有空白字元
  • to_next_char: 將parser中的next_char_ptr指向的字元賦給cur_char, 並++next_char_ptr
  • to_next_char_if: 和to_next_char類似, 返回型別為bool型別, 當nextchar是我們期望的值的時候呼叫to_next_char並返回true, 否則直接返回false
  • peek_next_char: *parser->next_char_ptr
  • peek_cur_char: parser->cur_char
  • get_next_token: 給語法分析器呼叫的函式, 在get_next_token函式中主要由一個偽while迴圈(之所以是偽while迴圈, 是因為在while的結尾有return語句), 裡面還有continue語句, 主要在遇到了註釋, 呼叫了skip_comment之後continue繼續獲取Token, 因為註釋並不是我們的token, 它是無用的; 在while中有switch case語句, 主要是通過字元判斷token的型別, 這是parser->cur_token.type的值
  • parser_id: 解析id, 在該函式中, 會呼叫is_id_or_keyword, 來判斷TokenType到底是id還是keyword
  • is_id_or_keyword: 會在parser_id中呼叫
  • parser_string: 解析字串, 注意轉義字元的處理, 有switch case

資料結構

  • Parser, 詞法解析器

typedef Parser {
    const char *fname;
    const char *source;
    Token cur_token; // 不會為cur_token和pre_token賦整個的值, 而是一直在不斷的更新cur_token的屬性, 而pre_token則是直接通過cur_token拷貝過來的
    Token pre_token;
    char cur_char;
    char *next_char_ptr;
    VM *vm; // 在詞法分析的時候可能會需要分配記憶體空間, 這個時候需要vm來記錄分配的記憶體空間
} Parser;
  • Token, 簡而言之就是字串加上Token的型別

typedef struct Token {
    TokenType type;
    // ptr 與 length 表示一個單詞
    char *ptr;
    unsigned int length;
    unsigned int line_no;
} Token;
  • TokenType, 一個包含著Token型別的enum

typedef enum TokenType {
    /*
    符號:
        1. 比較關係符: >, >=, ==, <=, <, !=
        2. 邏輯關係符: &&, ||, !
        3. 位運算子: &, |, ~
        4. 符號: (, [, {, }, ], ), comma(,), dot(.), dotdot(..)
    
    關鍵字:
        1. while
        2. for
        3. if
        4. else
        5. break
        6. continue
        7. import
        8. class
        9. ...
     其他:
        1. number
        2. string
        3. id
    */
} TokenType;