詞法分析器


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中調用
  • parse_string: 解析字符串, 注意轉義字符的處理, 有switch case
  • parse_num: 解析hex, dec, oct類型的token, 在該函數中調用根據前綴(0x, 0)判斷, 調用對應的parse_hex, parse_dec, parse_oct, 在這寫函數用主要用到C標准庫中的strtol和strtod將字符串轉為對應禁止的數字, 通過isxdigit和isdigit函數判斷是否一個字符是合法的進制字符
  • consume_token: 和match_token一樣, 這是如果不匹配就會直接退出進程

數據結構

  • 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;
    
    Value value; // 這里為什么會有一個Value呢, 主要是為了方便, 如果Token的類型為num, 則Value直接存放這個值, 如果是其他的則存放其他對象頭

} 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;
  • VM虛擬機的結構

typedef struct VM {
    Class *string_class; // 用於讓內置的ObjString對象指向它的類對象, 內置的類對象就在這個VM中
    Class *fn_class; // 用於讓內置的ObjFunc對象的ObjHeader指向Func類對象
    Class *num_class;
    Class *bool_class;
    Class *thread_class;
    Class *class_class;
    Class *list_class;
    Class *map_class;
    Class *range_class;
    
    Parser *cur_parser;
    int allocated_bytes;
    ObjHeader *all_objects; // 有了這個, VM可以調用GC回收對象
    ObjThread *cur_thread;
    ObjModule *modules;
    MethodBuffer allMethodNames;
} VM;

方法
initVM
newVM, 在newVM中會調用initVM, 緊接着就調用buildCore函數, 在buildCore函數中會調用defineClass函數, 定義出內置的ObjectClass, ObjectMetaClass, ClassOfClass類, 並為他們綁定方法(C語言上的函數), 接着executeModule加載執行核心模塊

注意

  1. 詞法分析器不負責解析時候的報錯, 報錯是交給編譯模塊的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM