1.1 符号表设计

1.1.1 主符号表分析

主符号表首先需要保存全局常量、变量,子函数/过程。其次,为了保证库程序名、主程序名、主程序参数名不被重定义,主符号表中还需保存库程序项、主程序名项、主程序参数项。
各成分的存储顺序如下图所示:
image.png

注:amount指主程序参数的个数

1.1.2 子符号表分析

子符号表中,除了需要保存局部常量、变量等,还需保存子程序参数(传值参数、引用参数),当然为了避免子程序中的标识符与当前子程序名同名,还需将子程序名保存到子符号表中;由于我们不支持函数/过程的嵌套定义,所以子符号表不包含子程序这一项。
各成分的存储顺序如下图所示:
image.png

1.1.3 符号表分析总结

符号表的第0个位置,存放的必然是该符号表对应的程序名,第1到第amount个位置,存放的必然是该符号表对应的程序所定义的amount个参数;另外主符号表还将read、write、writeln、exit存放在了第amount+1到第amount+4个的位置。主符号表和子符号表接下来的位置都先存放了所有的常量定义,再存放了所有的变量定义。最后主符号表还保存了所有的子程序定义,按照文法规定,子过程和子函数的存放位置没有必然的先后关系,可以混合存储。

1.1.4 在符号表中存放当前程序名的必要性

首先需要保证程序定义中的所有符号都不能和程序名同名,这一点就足以支撑将当前程序名加入当前符号表,且需放在一开始的位置;其次,赋值语句有一种很特殊的情况,就是将函数名作为左值,表达式作为右值的情况,这实际上是一条返回值语句,在进行类型检查时,需要查符号表获得左值的类型,那么如果已经将当前的函数名保存在了当前的子符号表中,将检查类型检查中需要特判的情况,便于程序的编写。

1.1.5 表项分析

综合上述分析,我们发现主符号表和子符号表的逻辑结构差别不大,所以表类和表项类均统一设计。各种不同的标识符分析如下表所示:

标识符种类 是否可能出现在主符号表中 是否可能出现在子符号表中 附加属性
变量 变量类型
常量 常量类型、常量值(需根据常量类型设置不同的域)、常量是否是负数
数组 数组元素类型、数组维数、数组各维上下界
传值参数 × 类型
引用参数 × 类型
过程 × 参数个数、指向子符号表的指针
函数 × 参数个数、返回值类型、指向子符号表的指针
主/子程序名 程序类型(函数还是过程)、程序参数个数、返回值类型(如果是函数,则该项有意义)
主程序参数 × 无(主程序参数不带类型)

注:附加属性指的是除了标识符、行号之外的属性。

1.1.6 表类定义

1.1.6.1 变量

名字 类型 描述
tableType string 主符号表标识为“main”,子符号表标识为“sub”
recordList vector<_SymbolRecord*> _SymbolRecord类型的vector,_SymbolRecord即表项类。 用于存储每一个标识符的信息,符号表记录类型的数据结构会在下文具体描述
idToLoc map 存储标识符id及其位置对应关系的map结构。每加入一个符号,都要将其id和其所在recordList中的下标存储到该map中,可以加快查询速度。

1.1.6.2 添加传值参数方法

  • 接口

void addPara(string id, int lineNumber, string type)

  • 返回值

    1. void
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 传值参数的id | | int lineNumber | 传值参数所在行号 | | string type | 传值参数的类型 |

  • 函数功能

将传值参数类型的标识符加到符号表中

  • 函数伪代码
    void _SymbolTable::addPara(string id, int lineNumber, string type) {
      遍历参数列表,查看当前标识符是否在符号表中已有记录 {
          若已有记录,在当前标识符id的前面添加存储次数个_;
      }
      新建符号表记录;
      调用setPara将传值参数的id、行号、传值参数类型写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
      若当前标识符在符号表中已有记录,存储次数加1;
      若当前标识符在符号表中未有记录,存储次数为1;
    }
    

1.1.6.3 添加引用参数方法

  • 接口

void addVarPara(string id, int lineNumber, string type)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 传引用参数的id | | int lineNumber | 传引用参数所在行号 | | string type | 传引用参数的类型 |

  • 函数功能

将传引用参数类型的标识符加到符号表中

  • 函数伪代码
    void _SymbolTable::addVarPara(string id, int lineNumber, string type) {
      遍历参数列表,查看当前标识符是否在符号表中已有记录 {
          若已有记录,在当前标识符id的前面添加存储次数个_;
      }
      新建符号表记录;
      调用setVarPara将传引用参数的id、行号、传引用参数类型写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
      若当前标识符在符号表中已有记录,存储次数加1;
      若当前标识符在符号表中未有记录,存储次数为1;
    }
    

1.1.6.4 添加普通变量方法

  • 接口

void addVar (string id, int lineNumber, string type)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 变量的id | | int lineNumber | 变量所在行号 | | string type | 变量的类型 |

  • 函数功能

将变量类型的标识符加到符号表中

void _SymbolTable::addVar (string id, int lineNumber, string type) {
    新建符号表记录;
    调用setVar将变量的id、行号、变量类型写入记录中;
    将记录添加到当前符号表中;
    将记录的位置保存到idToLoc中;
}

1.1.6.5 添加常量方法

  • 接口

void addConst(string id, int lineNumber, string type, bool isMinusShow, string value)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 常量的id | | int lineNumber | 常量所在行号 | | string type | 常量的类型 | | bool isMinusShow | 用于判断常量标识符符号正负的bool类型量 | | string value | 常量标识符的值 |

  • 函数功能

将常量类型的标识符加到符号表中

  • 函数伪代码

    void _SymbolTable::addConst(string id, int lineNumber, string type, bool isMinusShow, string value ) {
      新建符号表记录;
      调用setConst将常量的id、行号、常量类型、判断正负号的bool量、
      常量的值写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
    }
    

    1.1.6.6 添加数组方法

  • 接口

void addArray (string id, int lineNumber, string type, int amount, vector< pair > arrayRangeList)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 数组的id | | int lineNumber | 数组所在行号 | | string type | 数组的类型 | | int amount | 数组的维数 | | vector< pair > arrayRangeList | 存储数组各维上下界的vector |

  • 函数功能

将数组类型的标识符加到符号表中

  • 函数伪代码
    void _SymbolTable::addArray(string id, int lineNumber, string type, int amount, vector< pair<int, int> > arrayRangeList) {
      新建符号表记录;
      调用setArray将数组的id、行号、数组元素类型、数组维数、数组各维上下界写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
    }
    

1.1.6.7 添加过程方法

  • 接口

void addProcedure(string id, int lineNumber, int amount, _SymbolTable *subSymbolTable)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | Procedure的id | | int lineNumber | Procedure所在行号 | | int amount | Procedure参数的个数 | | _SymbolTable *subSymbolTable=NULL | Procedure子符号表的指针 |

  • 函数功能

将Procedure类型的标识符加到符号表中

  • 函数伪代码
    void _SymbolTable::addProcedure(string id, int lineNumber, int amount, _SymbolTable *subSymbolTable) {
      新建符号表记录;
      调用setProcedure将过程的id、行号、过程参数个数、指向该过程子符号表的指针写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
    }
    

1.1.6.8 添加函数方法

  • 接口

void addFunction(string id, int lineNumber, string type, int amount, _SymbolTable *subSymbolTable)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | Function的id | | int lineNumber | Function所在行号 | | string type | Function返回值的类型 | | int amount | Function参数的个数 | | _SymbolTable *subSymbolTable=NULL | Function子符号表的指针 |

  • 函数功能

将Function类型的标识符加到符号表中

  • 函数伪代码
    void _SymbolTable::addFunction(string id, int lineNumber, string type, int amount, _SymbolTable *subSymbolTable=NULL) {
      新建符号表记录;
      调用setFunction将函数的id、行号、函数返回值类型、函数参数个数、
      指向该函数子符号表的指针写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
    }
    

1.1.6.9 添加子程序符号表指针方法

  • 接口

addSubSymbolTable(string id, _SymbolTable *subSymbolTable)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 子符号表的指针的id | | _SymbolTable *subSymbolTable=NULL | 指向子符号表的指针 |

  • 函数功能

将指向子符号表的指针加到主符号表中

  • 函数伪代码
    void _SymbolTable::addSubSymbolTable(string id, _SymbolTable* symbolTable) {
      判断idToloc中id是否已经存在,
      若存在,则将idToLoc[id]相应内容作为recordList的下标,将指向子符号表的指针放到符号表中;
      若不存在,则报错:子程序不存在;
    }
    

1.1.6.10 添加主/子程序名方法

  • 接口

addProgramName(string id, int lineNumber, string subprogramType, int amount, string returnType)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 程序名的id | | int lineNumber | 程序名所在行号 | | string subprogramType | 该program的类型,只有Function和Procedure两种 | | int amount | 该program的参数个数 | | string returnType | 该program的返回值类型,若为Procedure,其返回值类型为void |

  • 函数功能

将当前program的程序名添加到其符号表第0个位置上

  • 函数伪代码
    void _SymbolTable::addProgramName(string id, int lineNumber, string subprogramType, int amount, string returnType) {
      判断记录列表是否为空,若不为空,则报错;
      遍历参数列表,查看当前标识符是否在符号表中已有记录 {
          若已有记录,在当前标识符id的前面添加存储次数个_;
      }
      新建符号表记录;
      调用setProgramName将当前Program的id、行号、Program的类型(函数还是过程)、Program参数个数、Program返回值类型写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
      若当前标识符在符号表中已有记录,存储次数加1;
      若当前标识符在符号表中未有记录,存储次数为1;
    }
    

1.1.6.11 添加主程序参数方法

  • 接口

addVoidPara(string id, int lineNumber)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 主程序参数的id | | int lineNumber | 主程序参数所在行号 |

  • 函数功能

将主程序参数加入到符号表中

  • 函数伪代码
    void _SymbolTable::addVoidPara(string id, int lineNumber) {
      遍历参数列表,查看当前标识符是否在符号表中已有记录 {
          若已有记录,在当前标识符id的前面添加存储次数个_;
      }
      新建符号表记录;
      调用setVoidPara将主函数参数的id、行号写入记录中;
      将记录添加到当前符号表中;
      将记录的位置保存到idToLoc中;
      若当前标识符在符号表中已有记录,存储次数加1;
      若当前标识符在符号表中未有记录,存储次数为1;
    }
    

1.1.7 表项类定义

1.1.7.1 变量

名字 类型 描述
flag string “value parameter”表示传值参数,
“var parameter”表示传引用参数,
“normal variant”表示普通变量,
“constant”表示常量,
“array”表示数组,
“procedure”表示过程,
“function”表示函数
“(sub)program name”表示该条记录是当前符号表对应的程序名信息
“parameter of program”表示主程序的参数
id string 当前标识符的id
lineNumber int 当前标识符定义位置的行号
type string 如果是变量/常量,则表示变量/常量类型;
如果是数组,则表示数组元素的类型;
如果是函数,则表示函数返回值类型,类型只能为基本类型,”integer”,”real”,”char”,”boolean”
value string 如果当前标识符是常量,则表示常量取值,这里面存的一定是无符号数(也就是非负数)
isMinusShow bool 表示常量前是否带负号,换句话说表示常量是否是负数
amount int 如果是数组,则表示数组维数,如果是函数/过程,则表示参数个数
arrayRangeList vector< pair > 数组各维上下界
subSymbolTable _SymbolTable* 指向过程/函数对应的子符号表的指针
subprogramType string 这是一条特殊的记录,表示当前符号表对应的程序名称等信息,该变量表示程序是函数还是过程


1.1.7.2 各种类标识符与其拥有的属性情况

flag id lineNumber type value isMinusShow
value parameter × ×
var parameter × ×
normal variant × ×
constant
array × ×
procedure × × ×
fucntion × ×
(sub)program name × × ×
parameter of program × × ×
flag amount arrayRangeList subSymbolTable subprogramType
value parameter × × × ×
var parameter × × × ×
normal variant × × × ×
constant × × × ×
array × ×
procedure × ×
fucntion × ×
(sub)program name × ×
parameter of program × × × ×

1.1.7.3 设置为传值参数方法

  • 接口

void setPara(string id, int lineNumber, string type)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 传值参数的id | | int lineNumber | 传值参数所在行号 | | string type | 传值参数的类型 |

  • 函数功能

设置传值参数类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setPara(string id, int lineNumber, string type) {
      将当前记录的flag设为"value parameter";
      将传入的传值参数id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的传值参数类型赋值给将当前记录的type;
    }
    

1.1.7.4 设置为引用参数方法

  • 接口

void setVarPara(string id, int lineNumber, string type)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 传引用参数的id | | int lineNumber | 传引用参数所在行号 | | string type | 传引用参数的类型 |

  • 函数功能

设置传引用参数类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setPara(string id, int lineNumber, string type) {
      将当前记录的flag设为" var parameter";
      将传入的传引用参数id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的传引用参数类型赋值给将当前记录的type;
    }
    

1.1.7.5 设置为普通变量方法

  • 接口

void setVar (string id, int lineNumber, string type)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 变量的id | | int lineNumber | 变量所在行号 | | string type | 变量的类型 |

  • 函数功能

设置变量类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setVar(string id, int lineNumber, string type) {
      将当前记录的flag设为" normal variant";
      将传入的变量id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的变量类型赋值给将当前记录的type;
    }
    

1.1.7.6 设置为常量方法

  • 接口

void setConst(string id, int lineNumber, string type, bool isMinusShow, string value)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 常量的id | | int lineNumber | 常量所在行号 | | string type | 常量的类型 | | bool isMinusShow | 用于判断常量标识符符号正负的bool类型量 | | string value | 常量标识符的值 |

  • 函数功能

设置常量类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setConst(string id, int lineNumber, string type, bool isMinusShow, string value) {
      将当前记录的flag设为"constant";
      将传入的常量id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的常量类型赋值给将当前记录的type;
      将传入的记录常量正负号的isMinusShow赋值给当前记录的isMinusShow;
      将传入的常量的值赋值给当前记录的值;
    }
    

1.1.7.7 设置为数组方法

  • 接口

void setArray (string id, int lineNumber, string type, int amount, vector< pair > arrayRangeList)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 数组的id | | int lineNumber | 数组所在行号 | | string type | 数组的类型 | | int amount | 数组的维数 | | vector< pair > arrayRangeList | 存储数组各维上下界的vector |

  • 函数功能

设置数组类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setArray(string id, int lineNumber, string type, int amount, vector< pair<int,int> > arrayRangeList) {
      将当前记录的flag设为"array";
      将传入的数组id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的数组元素类型赋值给将当前记录的type;
      将传入的数组维数赋值给当前记录的amount;
      将传入的数组记录各维上下界的值的vector赋值给当前记录的arrayRangeList;
    }
    

1.1.7.8 设置为过程方法

  • 接口

void setProcedure(string id, int lineNumber, int amount, _SymbolTable *subSymbolTable=NULL)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | Procedure的id | | int lineNumber | Procedure所在行号 | | int amount | Procedure参数的个数 | | _SymbolTable *subSymbolTable=NULL | Procedure子符号表的指针 |

  • 函数功能

设置Procedure类型标识符所在记录的具体信息

  • 函数伪代码

    void _SymbolRecord::setProcedure(string id, int lineNumber, int amount, _SymbolTable *subSymbolTable) {
      将当前记录的flag设为"procedure";
      将传入的过程id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的过程参数个数赋值给当前记录的amount;
      将传入的指向该过程子符号表指针赋值给当前记录的subSymbolTable;
    }
    


    1.1.7.9 设置为函数方法

  • 接口

void setFunction(string id, int lineNumber, string type, int amount, _SymbolTable *subSymbolTable=NULL)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | Function的id | | int lineNumber | Function所在行号 | | string type | Function返回值的类型 | | int amount | Function参数的个数 | | _SymbolTable *subSymbolTable=NULL | Function子符号表的指针 |

  • 函数功能

设置Function类型标识符所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setFunction(string id, int lineNumber, string type, int amount, _SymbolTable *subSymbolTable) {
      将当前记录的flag设为"function";
      将传入的函数id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的函数返回值类型赋值给将当前记录的type;
      将传入的函数参数个数赋值给当前记录的amount;
      将传入的指向该函数子符号表指针赋值给当前记录的subSymbolTable;
    }
    

1.1.7.10 设置为主/子程序名方法

  • 接口

setProgramName(string id, int lineNumber, string subprogramType, int amount, string returnType)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | program的id | | int lineNumber | program所在行号 | | string subprogramType | 该program的类型,只有Function和Procedure两种 | | int amount | 该program的参数个数 | | string returnType | 该program的返回值类型,若为Procedure,其返回值类型为void |

  • 函数功能

设置当前program的程序名所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setProgramName(string id, int lineNumber, string subprogramType, int amount, string returnType) {
      将当前记录的flag设为"(sub)program name";
      将传入的主程序名id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
      将传入的程序类型赋值给将当前记录的type;
      将传入的程序参数个数赋值给当前记录的amount;
      将传入的该程序返回值的类型赋值给当前记录的returnType;
    }
    

1.1.7.11 设置为主程序参数方法

  • 接口

setVoidPara(string id, int lineNumber)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 主程序参数的id | | int lineNumber | 主程序参数所在行号 |

  • 函数功能

设置主程序参数所在记录的具体信息

  • 函数伪代码
    void _SymbolRecord::setVoidPara(string id, int lineNumber) {
      将当前记录的flag设为"parameter of program";
      将传入的主程序参数id赋值给将当前记录的id;
      将传入的行号赋值给将当前记录的lineNumber;
    }
    

1.1.8 对外接口

1.1.8.1 查找所在符号表位置

  • 接口

_SymbolRecord findSymbolRecord(_SymbolTable currentSymbolTable, string id, int mode)

  • 返回值

_SymbolRecord* findSymbolRecord

  • 参数列表 | 参数 | 描述 | | —- | —- | | _SymbolTable* currentSymbolTable | 指向当前符号表的指针 | | string id | 标识符id | | int mode | 判断当前符号表是否为主符号表 |

  • 函数功能

找出标识符在符号表中的位置

  • 函数伪代码

1.1.8.2 检查是否与库程序名、主程序名、主程序参数同名

  • 接口

bool checkIsTheSameAsKey(string id, int lineNumber)

  • 返回值

bool

  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 标识符id | | int lineNumber | 标识符行号 |

  • 函数功能

检查标识符是否与库程序名、主程序名、主程序参数同名

  • 函数伪代码
    bool checkIsTheSameAsKey(string id, int lineNumber) {
      遍历主符号表的第0个到第amount+4个记录 {
          if (标识符与记录中的id同名) {
              if (与主程序名同名)
              调用addGeneralErrorInformation函数添加通用错误信息; else if (主程序参数同名)
              调用addGeneralErrorInformation函数添加通用错误信息; else
              调用addGeneralErrorInformation函数添加通用错误信息;
              return true;
          }
      }
      return false;
    }
    

1.1.8.3 找到第X个形式参数的类型

  • 接口

string findXthFormalParaType(int X)

  • 返回值

     string
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | int X | 第X维形式参数 |

  • 函数功能

找到第X维形式参数的类型

  • 函数伪代码

    string _SymbolRecord::findXthFormalParaType(int X) {
      检查当前flag是否为"function"或者"procedure",并且传入的维度值未越界;
      若是,则返回recordList第x个元素的type值;
      若不是,则该记录不是"function"也不是"procedure",或者是维度值越界;
    }
    

    1.1.8.4 检查第X个形式参数是否是引用调用

  • 接口

bool isXthFormalParaRefered(int X)

  • 返回值

     bool
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | int X | 第X维形式参数 |

  • 函数功能

检查第X维形式参数是否是引用调用

  • 函数伪代码

    bool _SymbolRecord::isXthFormalParaRefered(int X) {
      检查当前flag是否为"function"或者"procedure",并且传入的维度值未越界;
      若是,则检查返回recordList第x个元素的flag值是否为"var parameter",
      若是,则返回ture;
      若不是,则返回false;
      若不是,则该记录不是"function"也不是"procedure",或者是维度值越界;
    }
    

    1.1.8.5 检查第X维下标是否越界

  • 接口

bool checkArrayXthIndexRange(int X,int index)

  • 返回值

bool

  • 参数列表 | 参数 | 描述 | | —- | —- | | int X | 第X维形式参数 | | int index | 第X个形式参数的下标 |

  • 函数功能

检查第X维下标是否越界,true表示越界,false表示未越界

  • 函数伪代码

    bool _SymbolRecord::isXthFormalParaRefered(int X) {
      检查当前flag是否为"array",并且传入的维度值未越界;
      若是,则检查第x个元素的下标值是否大于数组下界并且小于数组上界,
      若两者都符合,返回ture;
      否则,返回false;
      若不是,则该记录不是"array",或者是维度值越界;
    }
    

    1.1.8.6 检查id是否是引用参数

  • 接口

bool checkIsReferedPara(_SymbolTable* currentSymbolTable, string id)

  • 返回值

bool

  • 参数列表 | 参数 | 描述 | | —- | —- | | _SymbolTable* currentSymbolTable | 指向当前符号表的指针 | | string id | 标识符id |

  • 函数功能

检查检查id是否是引用参数

  • 函数伪代码
    bool checkIsReferedPara(_SymbolTable* currentSymbolTable, string id) {
      if (当前符号表为主符号表)
      return false;
      if (当前符号表的id列表有值) {
          根据id列表的下标找到记录在符号表中的下标;
          从符号表中找到该记录;
          return 该记录的类型赋值为"var parameter";
      } else {
          cout << "[checkIsReferedPara] id not found" << endl;
      }
    }
    

    1.1.8.7 符号表指针

    _SymbolTable mainSymbolTable;
    指向主符号表的指针;
    extern _SymbolTable
    currentSymbolTable;
    指向当前符号表的指针。

    1.1.9 符号表定位与重定位

    1.1.9.1 定位

    在进入到抽象语法树每个子程序的定义节点时,创建子符号表,将程序名、参数个数、子符号表指针等信息保存到主符号表后,再定位到子符号表,继续进行程序定义部分的语义分析。

    1.1.9.2 重定位

    在退出抽象语法树某个子程序的定义节点时,需要重定位到主符号表。