1.1语义分析函数设计
1.1.1 常量语义分析
- 函数接口
void SemanticAnalyseConst(_Constant* constant)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _Constant* constant | 指向该常量标识符的指针 |
函数功能
对常量定义进行语义分析
函数伪代码
void SemanticAnalyseConst(_Constant* constant) {
if(constant==NULL) {
cout << "[SemanticAnalyseConst] pointer of _Constant is null" << endl;
return;
}
用constId.first去查符号表,检查是否重定义
调用checkIsTheSameAsKey函数,检查是否与主程序名、主程序参数名、库程序名同名;
若是,return;
if (符号表记录不为空) {
调用addDuplicateDefinitionErrorInformation函数添加重定义错误信息;
return;
}
if(该常量由另外的常量标识符定义) {
调用findSymbolRecord函数查询该常量标识符的记录;
if(该常量标识符未定义) {
调用addUndefinedErrorInformation函数添加未定义错误信息;
return;
}
if (该标识符不是常量) {
调用addPreFlagErrorInformation函数添加标识符种类错误信息;
return;
}
调用addConst函数将该标识符添加到符号表记录中;
} else//该常量由常数值定义
调用addConst函数将该标识符添加到符号表记录中;
}
1.1.2 变量语义分析
函数接口
void SemanticAnalyseVariant(_Variant* variant)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _Constant* constant | 指向该变量标识符的指针 |
函数功能
对变量定义进行语义分析
- 函数伪代码
void SemanticAnalyseVariant(_Variant* variant) { if(variant==NULL) { cout << "[SemanticAnalyseVariant] pointer of _Variant is null" << endl; return; } 用variantId.first去查符号表,检查是否重定义; 调用checkIsTheSameAsKey函数,检查是否与主程序名、主程序参数名、库程序名同名; 若是,return; if(符号表记录不为空) { 调用addDuplicateDefinitionErrorInformation添加重定义错误信息; return; } if(如果当前变量不是数组) 调用addVar将该变量添加进符号表; else { if(数组每一维上界均大于等于下界) 调用addArray函数将该数组添加进符号表; else 调用addArrayRangeUpSideDownErrorInformation添加数组越界错误信息; } }
1.1.3 语句语义分析
- 函数接口
void SemanticAnalyseStatement(_Statement *statement)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _Statement *statement | 指向该语句标识符的指针 |
函数功能
对语句定义进行语义分析
- 函数伪代码
void SemanticAnalyseStatement(_Statement *statement) { if(statement==NULL) { cout << "[SemanticAnalyseStatement] pointer of _Statement is null" << endl; return; } if(语句类型是"compound") { 调用reinterpret_cast函数将该语句转换为_CompoundStatement类型; 遍历对复合语句块中的每一条语句,调用SemanticAnalyseStatement函数进行语义分析; } else if(语句类型是"repeat") { 调用reinterpret_cast函数将该语句转换为_RepeatStatement类型; 调用SemanticAnalyseExpression得到条件表达式的类型; if (条件表达式的类型 != "boolean") { //repeat语句类型检查,condition表达式类型检查 checked 调用addExpressionTypeErrorInformation函数添加类型错误信息; 该语句类型赋值为"error"; } else 该语句类型赋值为"void"; 调用SemanticAnalyseStatement函数对循环体语句进行语义分析; } else if(语句类型是"while") { 调用reinterpret_cast函数将该语句转换为_WhileStatement类型; 调用SemanticAnalyseExpression得到条件表达式的类型; string type = SemanticAnalyseExpression(whileStatement->condition); if (条件表达式的类型 != "boolean") { //repeat语句类型检查,condition表达式类型检查 checked 调用addExpressionTypeErrorInformation函数添加类型错误信息; 该语句类型赋值为"error"; } else 该语句类型赋值为"void"; 调用SemanticAnalyseStatement函数对循环体语句进行语义分析; } else if(语句类型是"for") { 调用reinterpret_cast函数将该语句转换为_ForStatement类型; 调用 findSymbolRecord函数,找到循环变量的记录; if(记录不为空) { 调用addUndefinedErrorInformation函数添加重定义错误信息; return; } if(该记录类型不为传值参数、传引用参数、普通变量) { } 调用addPreFlagErrorInformation添加标识符种类错误信息; return; } if (循环变量类型不为整型) { 调用addUsageTypeErrorInformation函数添加标识符类型错误信息; return; } //for语句类型检查,start和end表达式类型检查 forStatement语句类型赋值为"void"; string type = SemanticAnalyseExpression(forStatement->start); 调用SemanticAnalyseExpression函数获得forStatement语句的start值的类型; if (start值的类型不为 "integer") { 调用addUsageTypeErrorInformation函数添加标识符类型错误信息; forStatement语句类型赋值为 "error"; } 调用SemanticAnalyseExpression函数获得forStatement语句的end值的类型; if (end值的类型不为 "integer") { 调用addUsageTypeErrorInformation函数添加标识符类型错误信息; forStatement语句类型赋值为 "error"; } 调用SemanticAnalyseStatement函数对循环体语句进行语义分析 } else if(语句类型是"if") { 调用reinterpret_cast函数将该语句转换为_IfStatement类型; 调用SemanticAnalyseExpression函数获得条件表达式的类型; if (条件表达式的类型不为 "boolean") { 调用addUsageTypeErrorInformation函数添加标识符类型错误信息; ifStatement语句类型赋值为 "error"; ; } else ifStatement语句类型赋值为"void"; 调用 SemanticAnalyseStatement对then语句进行语义分析; if(if语句对应的els不等于NULL) 调用SemanticAnalyseStatement函数对 else语句进行语义分析; } else if(语句类型是"assign") { 调用reinterpret_cast函数将该语句转换为_AssignStatement类型; assign语句类型赋值为"void"; 将assign语句的左值的locFlag赋值为-1; 调用SemanticAnalyseVariantReference函数获得assign语句的左值的类型; if (assign语句的左值的类型为 "constant") { 调用addGeneralErrorInformation函数添加通用错误信息; return; } 调用SemanticAnalyseExpression函数获得assign语句的右值的类型 if (assign语句的右值的类型为 "function return reference") { if (assign语句的右值的类型不等于函数返回值类型 && !(assign语句的右值的类型为"integer"且函数返回值类型为"real")) { 调用addGeneralErrorInformation函数添加通用错误信息; assign语句类型赋值为"error"; } assign语句是返回值语句; return; } //比较左值和右值类型,获得赋值语句的类型;类型不同时,只支持整型到实型的隐式转换 if (左值类型不等于右值类型 && !(左值类型=="real" && 右值类型=="integer")) { 调用addAssignTypeMismatchErrorInformation函数添加左值类型与右值类型不匹配的错误信息; assign语句赋值为 "error"; } else assign语句类型赋值为"void"; } else if(语句类型是"procedure") { //read的参数只能是变量或数组元素; 调用reinterpret_cast函数将该语句转换为_ProcedureCall类型; 通过procedureId,调用findSymbolRecord函数查主表,获得这条语句的记录; if (记录为空) 通过procedureId,调用findSymbolRecord函数查当前符号表,获得这条语句的记录; 将procedure语句类型赋值为 "void"; if (记录为空) { 调用addUndefinedErrorInformation函数添加重定义错误信息;; 将procedure语句类型赋值为"error"; return; } if (该记录类型不是 "procedure") { 调用addPreFlagErrorInformation函数添加标识符种类错误信息; 将procedure语句类型赋值为"error"; return; } if (语句类型是 "exit") { if (当前程序是"procedure") { if (exit语句的实参个数 != 0) { 调用addGeneralErrorInformation函数添加通用错误信息; exit语句类型赋值为"error"; } return; } //如果是函数 if (exit语句的实参个数 != 1) { if (exit语句的实参个数== 0) 调用addGeneralErrorInformation函数添加通用错误信息; else 调用addGeneralErrorInformation函数添加通用错误信息; return; } 调用SemanticAnalyseExpression函数获得函数返回值的类型 if (实参表达式的类型 !=函数返回值的类型 && !(实参表达式的类型为 "real" && 函数返回值的类型为"integer")) { 调用addGeneralErrorInformation函数添加通用错误信息; 将procedure语句类型赋值为"error"; } procedure语句是返回值语句; return; } if (记录的id类型为 "read" || 记录的id类型为"write") { if (procedure语句的参数为0) { 调用addGeneralErrorInformation函数添加通用错误信息; 将procedure语句类型赋值为"error"; } } if (记录的id类型为 "read") { 遍历read函数中的每一个参数,调用SemanticAnalyseExpression得到read函数各个参数的参数类型; if (!(read函数的参数类型引用域type为 "var" && (read函数的参数类型为"var" || read函数的参数类型为 "array"))) 调用addactualParameterOfReadErrorInformation函数来添加read的实参错误信息; if (read函数的参数表达式类型 == "boolean") 调用addReadBooleanErrorInformation函数来添加添加read读取boolean类型变量错误的信息; if (read函数的参数类型== "error") read语句的类型赋值为 "error"; } return; } if (记录的amount值 == -1) { 遍历对语句块中的每一条语句,调用SemanticAnalyseExpression函数得到read函数各个参数的参数类型 { if (read函数的参数类型 == "error") read语句类型赋值为"error"; } return; } if (语句的参数个数!= 记录的语句参数个数) { 调用addNumberErrorInformation函数添加参数个数不匹配错误新; read语句类型赋值为"error"; return; } 遍历对语句块中的每一条语句,调用SemanticAnalyseExpression函数得到read函数的各个参数的参数类型 { 调用findXthFormalParaType函数,得到对应的每一个实参的参数类型; 调用isXthFormalParaRefered函数来得到每一个实参的类型是否是传引用调用; if (实参类型是传引用调用 && !(语句变量调用变量值为"var" && (实参传引用调用表达式类型为 "var" || 实参传引用调用表达式类型为"array"))) { 调用addGeneralErrorInformation函数添加通用错误信息; continue; } if (实参类型是传值调用) { if (实参类型与形参类型不一致 && !(实参类型为"integer" && 形参类型为"real")) { 调用addExpressionTypeErrorInformation函数添加类型错误信息; procedureCall->statementType = "error"; } } else { if (实参类型与形参类型不一致) { 调用addExpressionTypeErrorInformation函数添加类型错误信息; procedureCall->statementType = "error"; } } } } else { cout << "[SemanticAnalyseStatement] statement type error" << endl; return; } }
1.1.4 表达式语义分析
- 函数接口
string SemanticAnalyseExpression(_Expression* expression)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _Expression* expression | 指向该表达式标识符的指针 |
函数功能
对表达式定义进行语义分析
- 函数伪代码
string SemanticAnalyseExpression(_Expression* expression) { if(expression==NULL) { cout << "[SemanticAnalyseExpression] pointer of _Expression is null" << endl; return ""; } if (表达式类型为 "var") { 调用SemanticAnalyseVariantReference函数获得常量的类型; if (常量引用类型为"integer" && 该常量类型为 "constant") { 调用findSymbolRecord函数来查符号表查出常量值 if (记录不存在) { cout << "[SemanticAnalyseExpression] pointer of record is null" << endl; return ""; } if (记录的类型!= "constant") { cout << "[SemanticAnalyseExpression] the record should be a constant" << endl; return ""; } 将记录的常数值赋值给该表达式的值; if (表达式的值为负值) 将记录的值加上负号之后赋值给表达式的值; 常量表达式的值存在; } return 表达式的类型; } else if (表达式类型为 "integer") { 将表达式的整数值赋值给该表达式的值; 整型表达式的值存在; return 表达式的具体类型为 "integer"; } else if (表达式类型为 "real") return 表达式的类型为 "real"; else if (表达式类型为 "char") return表达式的类型为 "char"; else if (表达式类型为"function") return 调用SemanticAnalyseFunctionCall函数获得函数调用的返回值类型; else if (表达式类型为"compound") { if (表达式的操作类型为 "relop") { 调用SemanticAnalyseExpression函数获得表达式左值的类型; 调用SemanticAnalyseExpression函数获得表达式右值的类型; if ((表达式左值的类型不等于表达式右值的类型 && 表达式左值的类型不为 "error") || (表达式左值的类型为 "integer" && 表达式右值的类型为 "real") || (表达式左值的类型为"real" &&表达式右值的类型为"integer")) return 表达式的具体类型为 "boolean"; else { if(表达式左值的类型不等于表达式右值的类型 &&表达式左值的类型不等于"error" &&表达式左值的类型不等于 "error") 调用addOperandExpressionsTypeMismatchErrorInformation函数来添加操作符两边类型不一致错误信息; return 表达式的具体类型为 "error"; } } else if (表达式的操作类型为 "not") { 调用SemanticAnalyseExpression函数获得表达式的类型; if (表达式的类型为"boolean") return 表达式的具体类型 "boolean"; else { if(表达式的类型不为 "error" && 表达式的类型不为"boolean") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; return 表达式的具体类型为 "error"; } } else if (表达式的操作类型为 "minus") { 调用SemanticAnalyseExpression函数获得表达式的类型; if(表达式的类型为"integer" && 表达式操作数的值存在) { 将表达式操作数的值取负之后,重新赋值为表达式的值; 表达式的值存在; } if (表达式的类型为"integer" || 表达式的类型为 "real") return 返回表达式的具体类型; else { if(表达式的类型不为 "error" &&表达式的类型不为"integer" &&表达式的类型不为"real") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; return 表达式的具体类型为 "error"; } } else if (表达式的操作类型为"bracket") { 调用SemanticAnalyseExpression函数获得表达式的类型; if(表达式的类型为 "integer" && 表达式操作数的值存在) { 将表达式操作数的值赋值为表达式的值; 表达式的值存在; } return 表达式的类型; } else if (表达式的操作类型为 "+" ||表达式的操作类型为 "-" || 表达式的操作类型为 "*" || 表达式的操作类型为"/") { 调用SemanticAnalyseExpression函数获得表达式第一个操作数的类型; 调用SemanticAnalyseExpression函数获得表达式第二个操作数的类型; if (表达式的操作类型为"/" && 除数类型为"integer" &&除数的值存在&& 除数的值为 0) 调用addDivideZeroErrorInformation函数添加除0错误信息; if(第一个操作数类型为"integer" &&第二个操作数的类型为 "integer" && 第一个操作数的值存在 && 第二个操作数的值存在) { 表达式的值存在; if(表达式的操作类型为"+") 表达式的值等于第一个操作数的值+第二个操作数的值; else if(表达式的操作类型为"-") 表达式的值等于第一个操作数的值-第二个操作数的值; else if(表达式的操作类型为"*") 表达式的值等于第一个操作数的值*第二个操作数的值; else 表达式的值等于第一个操作数的值/第二个操作数的值; } if((第一个操作数类型为"integer" || 第一个操作数类型为"real") && (第二个操作数类型为"integer" || 第二个操作数类型为"real")) { if(第一个操作数类型为"integer" && 第二个操作数类型为"integer") return 表达式的类型为"integer"; return 表达式的类型为"real"; } if(第一个操作数类型不为 "error" && 第一个操作数类型不为 "integer" && 第一个操作数类型不为"real") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; if(第二个操作数类型不为"error" && 第二个操作数类型不为 "integer" && 第二个操作数类型不为 "real") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; return 表达式的类型为"error"; } else if (表达式的操作类型 "div" || 表达式的操作类型"mod") { 调用SemanticAnalyseExpression函数获得表达式第一个操作数的类型; 调用SemanticAnalyseExpression函数获得表达式第二个操作数的类型; if (第二个操作数的类型"integer" && 第二个操作数的值存在&& 第二个操作数的值为0) 调用addDivideZeroErrorInformation函数添加除0错误信息; if (第一个操作数类型为"integer" && 第二个操作数类型为"integer") { if((第一个操作数的值存在 && 第二个操作数的值存在) { if(表达式的操作类型 "div") 表达式的值等于第一个操作数的值/第二个操作数的值; else 表达式的值等于第一个操作数的值%第二个操作数的值; 表达式的值存在; } return 表达式的类型为"integer"; } if(第一个操作数类型不为"error" &&第一个操作数类型不为"integer") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; if(第二个操作数类型不为"error" && 第二个操作数类型不为"integer") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; return 表达式的类型为"error"; } else if (表达式的操作类型为 "and" || 表达式的操作类型为"or") { 调用SemanticAnalyseExpression函数获得表达式第一个操作数的类型; 调用SemanticAnalyseExpression函数获得表达式第二个操作数的类型; if (第一个操作数类型为"boolean" && 第二个操作数类型为 "boolean") return expression->expressionType = "boolean"; if (第一个操作数类型不为 "error" && 第一个操作数类型不为"boolean") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; if (第二个操作数类型不为 "error" && 第二个操作数类型不为"boolean") 调用addSingleOperandExpressionTypeMismatchErrorInformation函数添加某个操作数类型错误信息; return 表达式的类型为 "error"; } else { cout << "[_Expression::SemanticAnalyseExpression] ERROR: operation not found" << endl; return "error"; } } }
1.1.5 程序语义分析
- 函数接口
void SemanticAnalyseProgram(_Program *program)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _Statement *statement | 指向该程序标识符的指针 |
函数功能
对程序定义进行语义分析
- 函数伪代码
void SemanticAnalyseProgram(_Program *program) { if (program == NULL) { cout << "[SemanticAnalyseProgram] pointer of _Program is null" << endl; return; } 调用lib.insert函数将read、write、writeln、exit 4个库函数加入函数库; if (程序与库函数名同名) 调用addGeneralErrorInformation添加通用错误信息; 调用addProgramName函数将该程序的函数名存储到主符号表的第0个位置,将主程序的参数添加到主符号表中,flag定为"parameter of program; 遍历主程序参数{ if (该程序名是否和主程序名同名) 调用addGeneralErrorInformation函数添加通用错误信息; else if (该程序名是否和主程序参数名同名) 调用addGeneralErrorInformation函数添加通用错误信息; else 调用addVoidPara函数将主程序参数加入到符号表中; } 调用addProcedure函数添加read过程,该过程变参 调用addProcedure函数添加write过程,该过程变参 调用addProcedure函数添加writeln过程,该过程变参 调用addProcedure函数添加exit过程; 调用SemanticAnalyseSubprogram对分程序进行语义分析; }
1.1.6 分程序语义分析
- 函数接口
void SemanticAnalyseSubprogram(_SubProgram* subprogram)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _SubProgram* subprogram | 指向该分程序标识符的指针 |
函数功能
对分程序定义进行语义分析
- 函数伪代码
void SemanticAnalyseSubprogram(_SubProgram* subprogram) { if(subprogram==NULL) { cout << "[SemanticAnalyseSubprogram] pointer of _Subprogram is null" << endl; return; } 遍历分程序的常量列表 调用SemanticAnalyseConst函数对常量进行语义分析; 遍历分程序的变量列表 调用SemanticAnalyseVariant函数对变量进行语义分析; 遍历分程序的子程序定义列表 { 调用SemanticAnalyseSubprogramDefinition函数对子程序定义进行语义分析; 进行符号表的重定位; } 调用 SemanticAnalyseStatement函数对语句进行语义分析; }
1.1.7 子程序语义分析
- 函数接口
void SemanticAnalyseSubprogramDefinition(_FunctionDefinition* functionDefinition)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _FunctionDefinition* functionDefinition | 指向该子程序标识符的指针 |
函数功能
对子程序定义进行语义分析
- 函数伪代码
void SemanticAnalyseSubprogramDefinition(_FunctionDefinition* functionDefinition) { if(functionDefinition==NULL) { cout << "[SemanticAnalyseSubprogramDefinition] pointer of _FunctionDefinition is null" << endl; return; } 调用findSymbolRecord函数查找该子程序定义的记录; if(记录不为空) { 调用addDuplicateDefinitionErrorInformation函数添加未定义错误信息; return; } if (子程序无返回值) 子程序的类型为 "procedure"; else 子程序的类型为"function"; 调用 createSubSymbolTableAndInit()函数创建并定位到子符号表; 调用addProgramName函数将子程序名等信息添加到子符号表中; if (如果该程序是过程)//如果是过程 调用addProcedure函数将过程添加到主程序表中; else 调用addFunction函数将函数添加到主程序表中; 遍历子程序的形参列表 { 调用SemanticAnalyseFormalParameter函数对形式参数列表进行语义分析,并将形式参数添加到子符号表中; } 遍历子程序的常量列表 { 调用SemanticAnalyseConst函数对常数列表进行语义分析,并将常数添加到子符号表中; } 遍历子程序的变量列表 { 调用SemanticAnalyseVariant函数对变量列表进行语义分析,并将变量添加到子符号表中; } 调用SemanticAnalyseStatement函数对compound进行语义分析; 调用returnExistedCheckFunctionDefinition函数对函数进行返回值语句的存在性检查; }
1.1.8 函数调用语义分析
- 函数接口
string SemanticAnalyseFunctionCall(_FunctionCall *functionCall)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _FunctionCall *functionCall | 指向该函数调用标识符的指针 |
函数功能
对函数调用定义进行语义分析
- 函数伪代码
string SemanticAnalyseFunctionCall(_FunctionCall *functionCall) { if(functionCall==NULL) { cout << "[SemanticAnalyseFunctionCall] pointer of _FunctionCall is null" << endl; return ""; } 调用findSymbolRecord函数在主符号表查找该函数调用定义的记录 if (记录为空) 调用findSymbolRecord函数在当前符号表查找该函数调用定义的记录 if (记录为空) { 调用addaddUndefinedErrorInformation函数添加未定义错误信息; return 函数调用类型为 "error"; } if (记录类型不是"function") { 调用addPreFlagErrorInformation函数添加标识符种类错误信息; return 函数调用类型为 "error"; } if (函数的参数量为-1) { 遍历函数的参数列表 调用SemanticAnalyseExpression函数对每一个参数进行表达式的语义分析; return 记录的类型; } if (参数个数不一致) { 调用addNumberErrorInformation函数添加参数个数不一致错误信息; return 记录的类型; } //检查各位置的实参和形参类型是否一致 形参在符号表中的定位 遍历函数的参数列表 { string actualType = SemanticAnalyseExpression(functionCall->actualParaList[i]); string formalType = record->findXthFormalParaType(i + 1); 调用SemanticAnalyseExpression函数得到每一个实参的类型; 调用findXthFormalParaType函数得到每一个形参的类型; 调用isXthFormalParaRefered函数检查第X维形式参数是否是引用调用; if (是引用调用 && !(实参类型引用为 "var" && (实参类型为 "var" || 实参类型为"array"))) { 调用addGeneralErrorInformation函数添加通用错误信息; continue; } if (是传值参数) { if (实参类型与形参不一致&& !(实参类型为 "integer" && 形参类型为 "real")) 调用addExpressionTypeErrorInformation函数添加表达式类型错误信息; } else { if (实参类型与形参不一致) 调用addExpressionTypeErrorInformation函数添加表达式类型错误信息; } } return 函数调用类型; }
1.1.9 形式参数语义分析
- 函数接口
void SemanticAnalyseFormalParameter(_FormalParameter *formalParameter)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _FunctionCall *functionCall | 指向该形式参数标识符的指针 |
函数功能
对形式参数定义进行语义分析
- 函数伪代码
void SemanticAnalyseFormalParameter(_FormalParameter* formalParameter) { if(formalParameter==NULL) { cout << "[SemanticAnalyseFormalParameter] pointer of _FormalParameter is null" << endl; return; } if (调用checkIsTheSameAsKey函数检查是否与库程序名、主程序名、主程序参数同名) return; 调用findSymbolRecord函数在当前符号表中寻找该标识符记录; if(记录不为空) 调用addDuplicateDefinitionErrorInformation函数添加重定义错误信息; if(形参类型传值参数) 调用addPara函数添加传值参数标识符到符号表中; else 调用addVarPara函数添加传引用参数标识符到符号表中; }
1.1.10 变量引用语义分析
- 函数接口
string SemanticAnalyseVariantReference(_VariantReference* variantReference)
- 返回值
void
参数列表 | 参数 | 描述 | | —- | —- | | _VariantReference* variantReference | 指向该变量引用标识符的指针 |
函数功能
对变量引用定义进行语义分析
- 函数伪代码
string SemanticAnalyseVariantReference(_VariantReference* variantReference) { if(variantReference==NULL) { cout << "[SemanticAnalyseVariantReference] pointer of _VariantReference is null" << endl; return ""; } 调用findSymbolRecord函数在当前符号表查找该变量引用定义的记录 if (记录为空) { 调用addaddUndefinedErrorInformation函数添加未定义错误信息; return 该变量引用类型为 "error"; } if (该变量引用不是数组) { if (记录类型引用为"(sub)program name") { if (记录类型为 "procedure") { 调用addGeneralErrorInformation函数添加通用错误信息; return 该变量引用类型为"error"; } if (变量引用为左值) { 变量引用的种类为 "function return reference"; return 变量引用的类型; } //如果是右值 if (变量引用为右值且形参个数不为0) { 调用addNumberErrorInformation函数添加参数个数不一致错误信息; return 变量引用的类型; } 变量引用的种类为"function call"; return 变量引用的类型; } if (记录类型为 "function") { 变量引用类型为 "function"; if (变量引用为左值) { return 变量引用的类型为 "error"; 调用addGeneralErrorInformation函数添加通用错误信息; } if (如果形参个数不为0) { addNumberErrorInformation(variantReference->variantId.first, variantReference->variantId.second, 0, record->amount, "function"); 调用addNumberErrorInformation函数添加参数个数不一致错误信息; return 变量引用的类型; } return 变量引用的类型; } if (!(记录类型为"value parameter" || 记录类型为 "var parameter" || 记录类型为 "normal variant" || 记录类型为 "constant")) { 调用addGeneralErrorInformation函数添加通用错误信息; return 变量引用的类型"error"; } 变量引用的种类为 "var"; if (记录的类型为 "constant") 变量引用的类型赋值为"constant"; return 变量引用的类型; } else if (变量引用的类型为数组) { if (记录不是 "array") { 调用addPreFlagErrorInformation函数添加标识符种类错误信息; return 变量引用的类型为"error"; } 变量引用的种类赋值为 "array"; if (变量引用的下标维数和符号表所存记录不一致) { 调用addNumberErrorInformation函数添加参数个数不一致错误信息; 变量引用的类型赋值为 "error"; return 变量引用的类型; } 将符号表记录类型赋值给变量引用类型; 遍历变量引用的的表达式列表 { 调用SemanticAnalyseExpression函数得到每一个表达式的类型; if (表达式下标类型不为"integer") { variantReference->variantType = "error"; 调用addExpressionTypeErrorInformation函数添加表达式类型错误信息; 变量引用的类型赋值为 "error"; } if(变量引用的值存在) { if(调用checkArrayXthIndexRange函数检查每一维是否越界) { 调用addArrayRangeOutOfBoundErrorInformation函数添加数组下标越界错误信息; 变量引用的类型赋值为 "error"; } } } return 记录的类型; } else { cout << "[SemanticAnalyseVariantReference] flag of variantReference is not 0 or 1" << endl; return 变量引用的类型为 "error"; } }