📜  C++程序实现符号表

📅  最后修改于: 2021-04-17 12:03:47             🧑  作者: Mango

先决条件:符号表

符号表是编译器使用的数据结构,程序源代码中的每个标识符都与它的声明相关联的信息一起存储在该表中。它存储标识符及其相关属性,例如范围,类型,出现的行号等。

可以使用各种数据结构来实现符号表,例如:

  • 链表
  • 哈希表

用于实现符号表的常见数据结构是HashTable。

符号表的操作–符号表上定义的基本操作包括:

考虑以下C++函数:

上面代码的符号表:

Name Type Scope
add function global
a int function parameter b int function parameter sum int local

以下是使用带有单独链接的散列概念的Symbol Table的C++实现:

// C++ program to implement Symbol Table
#include 
using namespace std;
  
const int MAX = 100;
  
class Node {
  
    string identifier, scope, type;
    int lineNo;
    Node* next;
  
public:
    Node()
    {
        next = NULL;
    }
  
    Node(string key, string value, string type, int lineNo)
    {
        this->identifier = key;
        this->scope = value;
        this->type = type;
        this->lineNo = lineNo;
        next = NULL;
    }
  
    void print()
    {
        cout << "Identifier's Name:" << identifier
             << "\nType:" << type
             << "\nScope: " << scope
             << "\nLine Number: " << lineNo << endl;
    }
    friend class SymbolTable;
};
  
class SymbolTable {
    Node* head[MAX];
  
public:
    SymbolTable()
    {
        for (int i = 0; i < MAX; i++)
            head[i] = NULL;
    }
  
    int hashf(string id); // hash function
    bool insert(string id, string scope,
                string Type, int lineno);
  
    string find(string id);
  
    bool deleteRecord(string id);
  
    bool modify(string id, string scope,
                string Type, int lineno);
};
  
// Function to modify an identifier
bool SymbolTable::modify(string id, string s,
                         string t, int l)
{
    int index = hashf(id);
    Node* start = head[index];
  
    if (start == NULL)
        return "-1";
  
    while (start != NULL) {
        if (start->identifier == id) {
            start->scope = s;
            start->type = t;
            start->lineNo = l;
            return true;
        }
        start = start->next;
    }
  
    return false; // id not found
}
  
// Function to delete an identifier
bool SymbolTable::deleteRecord(string id)
{
    int index = hashf(id);
    Node* tmp = head[index];
    Node* par = head[index];
  
    // no identifier is present at that index
    if (tmp == NULL) {
        return false;
    }
    // only one identifier is present
    if (tmp->identifier == id && tmp->next == NULL) {
        tmp->next = NULL;
        delete tmp;
        return true;
    }
  
    while (tmp->identifier != id && tmp->next != NULL) {
        par = tmp;
        tmp = tmp->next;
    }
    if (tmp->identifier == id && tmp->next != NULL) {
        par->next = tmp->next;
        tmp->next = NULL;
        delete tmp;
        return true;
    }
  
    // delete at the end
    else {
        par->next = NULL;
        tmp->next = NULL;
        delete tmp;
        return true;
    }
    return false;
}
  
// Function to find an identifier
string SymbolTable::find(string id)
{
    int index = hashf(id);
    Node* start = head[index];
  
    if (start == NULL)
        return "-1";
  
    while (start != NULL) {
  
        if (start->identifier == id) {
            start->print();
            return start->scope;
        }
  
        start = start->next;
    }
  
    return "-1"; // not found
}
  
// Function to insert an identifier
bool SymbolTable::insert(string id, string scope,
                         string Type, int lineno)
{
    int index = hashf(id);
    Node* p = new Node(id, scope, Type, lineno);
  
    if (head[index] == NULL) {
        head[index] = p;
        cout << "\n"
             << id << " inserted";
  
        return true;
    }
  
    else {
        Node* start = head[index];
        while (start->next != NULL)
            start = start->next;
  
        start->next = p;
        cout << "\n"
             << id << " inserted";
  
        return true;
    }
  
    return false;
}
  
int SymbolTable::hashf(string id)
{
    int asciiSum = 0;
  
    for (int i = 0; i < id.length(); i++) {
        asciiSum = asciiSum + id[i];
    }
  
    return (asciiSum % 100);
}
  
// Driver code
int main()
{
    SymbolTable st;
    string check;
    cout << "**** SYMBOL_TABLE ****\n";
  
    // insert 'if'
    if (st.insert("if", "local", "keyword", 4))
        cout << " -successfully";
    else
        cout << "\nFailed to insert.\n";
  
    // insert 'number'
    if (st.insert("number", "global", "variable", 2))
        cout << " -successfully\n\n";
    else
        cout << "\nFailed to insert\n";
  
    // find 'if'
    check = st.find("if");
    if (check != "-1")
        cout << "Identifier Is present\n";
    else
        cout << "\nIdentifier Not Present\n";
  
    // delete 'if'
    if (st.deleteRecord("if"))
        cout << "if Identifier is deleted\n";
    else
        cout << "\nFailed to delete\n";
  
    // modify 'number'
    if (st.modify("number", "global", "variable", 3))
        cout << "\nNumber Identifier updated\n";
  
    // find and print 'number'
    check = st.find("number");
    if (check != "-1")
        cout << "Identifier Is present\n";
    else
        cout << "\nIdentifier Not Present";
  
    return 0;
}
输出:
**** SYMBOL_TABLE ****

if inserted -successfully
number inserted -successfully

Identifier's Name:if
Type:keyword
Scope: local
Line Number: 4
Identifier Is present

if Identifier is deleted

number Identifier updated

Identifier's Name:number
Type:variable
Scope: global
Line Number: 3
Identifier Is present