Skip to content

first tokenize

yuyabu edited this page Jul 5, 2019 · 2 revisions

「ステップ3:トークナイザを導入」のプログラムが100行ぐらいあって、ポインタとか使いまくってたので流し読みではなく精読した。 このページはその時の大まかなメモ。

該当ページ

https://www.sigbus.info/compilerbook#%E3%82%B9%E3%83%86%E3%83%83%E3%83%973%E3%83%88%E3%83%BC%E3%82%AF%E3%83%8A%E3%82%A4%E3%82%B6%E3%82%92%E5%B0%8E%E5%85%A5

定義している関数

error consume expect expect_number at_eof new_token tokenize

プログラムの大体のコールグラフ

  • main
    • tokenize
      • new_token
    • at_eof
    • expect
      • error
    • expect_number
      • error

のコードでやってること

  • tokenizeでコマンドライン引数をトークンのlinked listに変換する
  // トークナイズする
  token = tokenize(argv[1]);

// トークン型
struct Token {
  TokenKind kind; // トークンの型
  Token *next;    // 次の入力トークン
  int val;        // kindがTK_NUMの場合、その数値
  char *str;      // トークン文字列
};

new_tokenではトークナイズする文字ポインタ(後置インクリメントなので文の実効後にポインタが変更される)とトークンリストの終端のpointerであるcurを引数に実行し、文字から新しいトークンを作り呼び出し元に返す。なおその時、curの次の要素(cur->next)を新しいトークンで更新する

  Token head;
  head.next = NULL;
  Token *cur = &head;

  while (*p) {
    // 空白文字をスキップ
    ...空文字処理略...

    if (*p == '+' || *p == '-') {
      cur = new_token(TK_RESERVED, cur, p++);
      continue;
    }

    if (isdigit(*p)) {
      cur = new_token(TK_NUM, cur, p);
      cur->val = strtol(p, &p, 10);
      continue;
    }

Clone this wiki locally