5

私は現在、パターン マッチングを実行する一種の静的解析ツールを開発しています。Flexを使用して語彙アナライザーを生成し、シンボル テーブルを管理するコードを作成しました。私はCの経験があまりないので、シンボル テーブルを線形リンク リストとして実装することにしました。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct symtab {
   int id;
   char *name;
   int type;
   struct symtab *next;
};

enum types {
   KEYWORD = 1,
   CONSTANT,
   IDENTIFIER,
   OPERATOR,
   DELIMITER,
   WHITESPACE
};

struct symtab *last_entry(struct symtab *start)
{
   struct symtab *p;
   p = start;
   while(p -> next != NULL) {
      p = p -> next;
   }
   return p;
}

void add_entry(char* name, int type, struct symtab *start)
{
   struct symtab *new;
   new = last_entry(start);
   int id;
   if(new == start) {
      new = start;
      id = 0;
   }
   else {
      new = malloc(sizeof(struct symtab));
      id = last_entry(start) -> id;
      last_entry(start) -> next = new;
   }
   new -> id = id + 1;
   new -> name = name;
       new -> type = type;
   new -> next = NULL;
}

struct symtab *find_entry(char* name, struct symtab *start)
{
   struct symtab *p;
   p = start;
   while(p -> next != NULL) {
      if(strcmp(p -> name, name) == 0) {
         return p;
      }
   }
}

ただし、add_entry()記号を追加してから で検索しようとするとfind_entry()find_entry()null が返されます。誰か助けてくれませんか?

4

1 に答える 1

5

リストをヘッダーオブジェクト(開始)として表現し、その後にリストの実際の要素を表示しようとしているようです。これは空のリストの場合を単純化するので良い考えですが、実装が正しくありません。

追加するときは、last_entryを開始するために取得した特殊なケースのコードを削除する必要があります。開始ノードにシンボルデータが含まれることはありません。

ルックアップするときは、シンボルデータが含まれていないため、ヘッドをスキップ(開始)する必要があります。ルックアップコードの2番目のバグは、p-> nextがNULLのときに検索を停止することです(つまり、リストの最後の要素を返すことはできません)。pがNULLのときに停止する必要があります。

もちろん、リンクリストを使用するべきではありません。パフォーマンスとメモリ効率が向上するため、ハッシュテーブルの方が適しています。

于 2011-05-28T14:26:26.770 に答える