1.1错误信息处理

1.1.1 存储错误信息的数据结构

错误信息均存储于以下的错误信息列表中:

  1. vector<string> semanticErrorInformation

1.1.2 添加错误信息函数

添加错误信息的函数分为两种。
一种是具体的,具有明确用途的添加错误函数,只要给这些函数提供必要的信息,它就可以帮你将这些信息组装成一条具体针对某一错误的报错信息,该种函数主要针对在语义分析的过程中重复出现的错误,也可以是将某些错误归为一类,再提供诸如用途之类的信息,就可以统一使用一个接口来添加错误信息。
另一种,或者说一个,是直接把提供的字符串加入错误信息列表的函数,主要用于那些仅出现一次的错误类型,无需封装成单独的函数。

1.1.2.1 重定义

  • 接口

void addDuplicateDefinitionErrorInformation(string preId, int preLineNumber, string preFlag, string preType,int curLineNumber)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string preId, | 之前已定义的标识符id | | int preLineNumber | 之前已定义的标识符所在行号 | | string preFlag | 之前已定义的标识符的种类 | | string preType | 之前已定义的标识符的类型 | | int curLineNumber | 当前标识符的行号 |

  • 函数功能

获得重复定义的语义错误信息。

  • 输出格式:

与其他标识符同名时,输出:

errorInformation += "\"" + preId + "\"" + " has already been defined as a " + preFlag + " at line " + itos(preLineNumber) + ".";


与主程序名、主程序参数名、库程序名同名时,输出:

errorInformation += "\"" + preId + "\"" + " has already been defined as a lib program.";

1.1.2.2 未定义

  • 接口

void addUndefinedErrorInformation(string id, int curLineNumber)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string id | 标识符的id | | int curLineNumber | 标识符所在行号 |

  • 函数功能

获得未定义的语义错误信息。

  • 输出格式:
    errorInformation = "[Undefined identifier!] <Line " + itos(curLineNumber) + "> ";  
    errorInformation += id + " has not been defined.";
    

1.1.2.3 标识符类型错误

  • 接口

void addUsageTypeErrorInformation(string curId, int curLineNumber, string curType, string usage, string correctType)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string curId | 当前标识符的id | | int curLineNumber | 当前标识符所在行号 | | string curType | 当前标识符类型 | | string usage | 之前标识符的位置 | | string correctType | 之前标识符的类型 |

  • 函数功能

标识符类型只能为为基本类型:”integer”,”real”,”char”,”boolean”
该函数能获得标识符类型错误的语义错误信息。

  • 输出格式:
    errorInformation = "[Usage type error!] <Line " + itos(curLineNumber) + "> ";  
    errorInformation += "\"" + curId + "\"" + " used for " + usage + " should be " + correctType + " but not " + curType + ".";
    

1.1.2.4 数组下标、参数个数不匹配

  • 接口

void addNumberErrorInformation(string curId, int curLineNumber, int curNumber, int correctNumber, string usage)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string curId | 当前标识符的id | | int curLineNumber | 当前标识符所在行号 | | int curNumber | 当前参数个数 | | int correctNumber | 正确的参数个数 | | string usage | 之前标识符的位置 |

  • 函数功能

获得数组下标不匹配、函数或过程参数个数不匹配的语义错误信息。

  • 输出格式:

数组下标个数不匹配时:

errorInformation += "[Array index number mismatch!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += "Array \"" + curId + "\"" + " should have " + itos(correctNumber) + " but not " + itos(curNumber) + " indices.";


过程参数个数不匹配时:

errorInformation += "[Procedure parameter number mismatch!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += "Procedure \"" + curId + "\"" + " should have " + itos(correctNumber) + " but not " + itos(curNumber) + " parameters.";


函数参数个数不匹配时:

errorInformation += "[Function parameter number mismatch!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += "Function \"" + curId + "\"" + " should have " + itos(correctNumber) + " but not " + itos(curNumber) + " parameters.";

1.1.2.5 标识符种类错误

  • 接口

void addPreFlagErrorInformation(string curId, int curLineNumber, string curFlag, int preLineNumber, string preFlag)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string curId | 当前标识符的id | | int curLineNumber | 当前标识符所在行号 | | string curFlag | 当前标识符种类 | | int preLineNumber | 之前标识符行数 | | string preFlag | 之前标识符的种类 |

  • 函数功能

标识符种类有以下几种:”value parameter”表示传值参数,”var parameter”表示传引用参数,”normal variant”表示普通变量,”constant”表示常量,,”array”表示数组,”procedure”表示过程,”function”表示函数,”(sub)program name”表示该条记录是当前符号表对应的程序名信息,”parameter of program”表示主程序的参数,该程序将添加标识符种类错误信息。

  • 输出格式:

当标识符种类错误时,输出如下信息:

errorInformation += "[Symbol kinds mismatch!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += "\"" + curId + "\"" + " defined at line " + itos(preLineNumber) + " is a " + preFlag + " but not a " + curFlag + ".";

1.1.2.6 表达式类型错误

  • 接口

void addExpressionTypeErrorInformation(_Expression *exp, string curType, string correctType, string description)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression *exp | 指向该表达式的指针 | | string curType | 当前表达式的类型 | | string correctType | 表达式正确的类型 | | string description | 表达式作用的描述 |

  • 函数功能

表达式类型主要有以下几种,”var”表示变量,”integer”表示整数,”real”表示浮点数,”char”表示常量字符,”function”表示函数调用,”compound”表示复合表达式,compound有普通的二目运算符,还有”minus”、”not”、”bracket”等单目运算符。该函数将添加表达式类型错误信息。

  • 输出格式:
    errorInformation += "Expression \"" + expression + "\" used for " + description + " should be " + correctType + " but not " + curType + ".";
    

1.1.2.7 赋值语句两边类型不匹配错误

  • 接口

void addAssignTypeMismatchErrorInformation(_VariantReference leftVariantReference, _Expression rightExpression)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _VariantReference leftVariantReference | 左值的参数引用列表的指针 | | _Expression rightExpression | 指向表达式右值的指针 |

  • 函数功能

添加赋值语句左值和右值类型不匹配错误信息。

  • 输出格式:

    左值和右值类型不匹配时,输出:

    errorInformation += "[Assign statement type mismatch!] ";  
    errorInformation += "<Left at line " + itos(leftVariantReference->variantId.second) + ", right at line " + itos(rightExpression->lineNumber) + "> ";  
    errorInformation += "Left \"" + varRef + "\" type is " + leftVariantReference->variantType + " while right \"" + exp + "\" type is " + rightExpression->expressionType + ".";
    

1.1.2.8 数组下标越界

  • 接口

void addArrayRangeOutOfBoundErrorInformation(_Expression *expression, string arrayId, int X, pair range)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression *exp | 指向该表达式的指针 | | string arrayId | 数组id | | int X | 数组第X维 | | pair range | 数组各维上下界 |

  • 函数功能

添加数组下标越界错误信息。

  • 输出格式:

数组上下界越界,输出如下信息:

errorInformation += "[Array range out of bound!] ";  
errorInformation += "<Line " + itos(expression->lineNumber) + "> ";  
errorInformation += "The value of expression \"" + exp + "\"" + " is " + itos(expression->totalIntValue);  
errorInformation += ", but the range of array \"" + arrayId + "\" " + itos(X) + "th index is " + itos(range.first) + " to " + itos(range.second) + ".";

1.1.2.9 数组下界比上界大

  • 接口

void addArrayRangeOutOfBoundErrorInformation(_Expression *expression, string arrayId, int X, pair range)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression *exp | 指向该表达式的指针 | | string arrayId | 数组id | | int X | 数组第X维 | | pair range | 数组各维上下界 |

  • 函数功能

添加数组下界比上界大的错误信息。

  • 输出格式:

数组下界比上界大时,输出如下信息:

errorInformation += "[Array range upsidedown error!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += itos(X) + "th range of array \"" + curId + "\" have larger low bound and smaller high bound, which is " + itos(lowBound) + " and " + itos(highBound) + ".";

1.1.2.10 运算符两边的操作数类型不一致

  • 接口

void addOperandExpressionsTypeMismatchErrorInformation(_Expression exp1, _Expression exp2)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression exp1 | 指向表达式左值的指针 | | _Expression exp2 | 指向表达式右值的指针 |

  • 函数功能

添加运算符两边的操作数类型不一致的错误信息。

  • 输出格式:

当运算符两边的操作数类型不一致时,输出如下信息:

errorInformation += "[Operands expression type mismatch!] ";  
errorInformation += "<Left at line " + itos(exp1->lineNumber) + ", right at line " + itos(exp2->lineNumber) + "> ";  
errorInformation += "Left \"" + expStr1 + "\" type is " + exp1->expressionType + " while right " + "\"" + expStr2 + "\" type is " + exp2->expressionType + ".";

1.1.2.11 某个操作数类型错误

  • 接口

void addSingleOperandExpressionTypeMismatchErrorInformation(_Expression *exp, string correctType)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression *exp | 指向表达式的指针 | | string correctType | 操作数的正确类型 |

  • 函数功能

添加某个操作数类型错误的信息。如mod操作符左边标识符类型为real。

  • 输出格式:

当某个操作数类型错误时,输出如下信息:

errorInformation += "[Operand expression type error!] ";  
errorInformation += "<Line " + itos(exp->lineNumber) + "> ";  
errorInformation += "Expression \"" + expStr + "\" type should be " + correctType + " but not " + exp->expressionType + ".";

1.1.2.12 read函数参数出现错误

  • 接口

void addactualParameterOfReadErrorInformation(int curLineNumber, string procedureId, int X, _Expression *exp)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | int curLineNumber | 过程所在行号 | | string procedureId | 过程的id | | int X | read函数的第X个参数 | | _Expression *exp | 指向表达式的指针 |

  • 函数功能

添加read的实参错误信息。

  • 输出格式:

当read函数参数出现错误,输出如下信息:

errorInformation += "[Actual parameter of read procedure type error!] ";  
errorInformation += "<Line " + itos(curLineNumber) + "> ";  
errorInformation += "\"" + procedureId + "\" " + itos(X) + "th expression parameter \"" + expression + "\" is not a variant or an array element.";

1.1.2.13 除0错误

  • 接口

void addDivideZeroErrorInformation(string operation, _Expression *exp)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | string operation | 操作符id | | _Expression *exp | 指向该表达式的指针 |

  • 函数功能

添加除0错误信息。

  • 输出格式:

当出现除0错误时,输出如下信息:

errorInformation += "[Divide zero error!] ";  
errorInformation += "<Line " + itos(exp->lineNumber) + "> ";  
errorInformation += "The value of expression \"" + expression + "\" is 0, which is the second operand of operation \"" + operation + "\".";

1.1.2.14 read读取boolean类型错误

  • 接口

void addReadBooleanErrorInformation(_Expression *exp, int X)

  • 返回值

     void
    
  • 参数列表 | 参数 | 描述 | | —- | —- | | _Expression *exp | 指向该表达式的指针 | | int X | read函数的第X维参数 |

  • 函数功能

添加read读取boolean类型变量错误的信息。

  • 输出格式:

当出现read读取boolean类型错误时,输出如下信息:

errorInformation = "[Read boolean error!] ";  
errorInformation += "<Line " + itos(exp->lineNumber) + "> ";  
errorInformation += "The " + itos(X) + "th actual parameter of read \"" + expression + "\" is boolean, it can't be read.";

1.1.2.15 直接添加错误

  • 接口

void addGeneralErrorInformation(string errorInformation)

  • 返回值

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

  • 函数功能

添加除上述提及错误之外其他错误的信息。

  • 调用该函数的错误场景与输出格式:

    • 程序名与主程序名相同时,输出以下信息:

      addGeneralErrorInformation("[Invalid reference] <Line " + itos(variantReference->variantId.second) + "> Procedure name \"" + record->id + "\" can't be referenced");
      
    • 变量引用类型为函数,作为左值时,输出以下信息:

      addGeneralErrorInformation("[Invalid reference!] <Line " + itos(variantReference->variantId.second) + "> function name \"" + record->id + "\" can't be referenced as l-value.");
      
  • 变量引用类型不是传值参数、不是传引用参数、不是常量、不是普通变量时,输出以下信息:

    addGeneralErrorInformation("[Invalid reference!] <Line " + itos(variantReference->variantId.second) + "> \"" + variantReference->variantId.first + "\" is a " + record->flag + ", it can't be referenced.");
    
  • 当左值为常量时,输出以下信息:

    addGeneralErrorInformation("[Invalid reference!] <Line " + itos(variantReference->variantId.second) + "> \"" + variantReference->variantId.first + "\" is a " + record->flag + ", it can't be referenced.");
    
  • 当语句返回值和函数参数类型不一致时,输出以下信息:

    addGeneralErrorInformation("[Return type of funciton mismatch!] <Line " + itos(assignStatement->expression->lineNumber) + "> The type of return expression is " + rightType + " ,but not " + assignStatement->variantReference->variantType + " as function \"" + assignStatement->variantReference->variantId.first + "\" defined.");
    
  • 如果exit过程所在程序为过程,exit过程参数不为0,输出以下信息:

    addGeneralErrorInformation("[Return value redundancy!] <Line " + itos(procedureCall->procedureId.second) + "> Number of return value of procedure must be 0, that is, exit must have no actual parameters.");
    
  • 如果exit过程所在程序为函数,exit过程参数为0,输出以下信息:

    addGeneralErrorInformation("[Return value missing!] <Line " + itos(procedureCall->procedureId.second) + "> Number of return value of function must be 1, that is, exit must have 1 actual parameters.");
    
  • 如果exit过程所在程序为函数,exit过程参数不为1,输出以下信息:

    addGeneralErrorInformation("[Return value redundancy!] <Line " + itos(procedureCall->procedureId.second) + "> Number of return value of function must be 1, that is, exit must have 1 actual parameters.");
    
  • 如果exit过程所在程序为函数,exit过程参数为1,但与与函数返回值类型不一致,输出以下信息:

    addGeneralErrorInformation("[Return type of funciton mismatch!] <Line " + itos(procedureCall->actualParaList[0]->lineNumber) + "> The type of return expression is " + returnType + " ,but not " + currentSymbolTable->recordList[0]->type + " as function \"" + currentSymbolTable->recordList[0]->id + "\" defined.");
    
  • 如果read、write的参数个数为0,输出以下信息:

    addGeneralErrorInformation("[" + tmp + " actual parameter missing!] <Line " + itos(procedureCall->procedureId.second) + "> procedure \"" + record->id + "\" must have at least one actual parameter.");
    
  • 当表达式不能作为引用形参对应的实参时,输出以下信息:

    addGeneralErrorInformation("[Referenced actual parameter error!] <Line " + itos(procedureCall->actualParaList[i]->lineNumber) + "> The " + itos(i + 1) + "th actual parameter expression should be a normal variable、value parameter、referenced parameter or array element.");
    
  • 当标识符与主程序同名时,输出以下信息:

    addGeneralErrorInformation("[Duplicate defined error!] <Line " + itos(program->programId.second) + "> Name of program \"" + program->programId.first + "\" has been defined as a lib program.");
    
  • 当标识符与主程序参数同名时,输出以下信息:

    addGeneralErrorInformation("[Duplicate defined error!] <Line " + itos(program->programId.second) + "> parameter of program \"" + program->programId.first + "\" is the same as name of program.");
    
  • 当标识符与库程序同名时,输出以下信息:

    addGeneralErrorInformation("[Dulicate defined error!] <Line " + itos(program->paraList[i].second) + "> parameter of program \"" + program->paraList[i].first + "\" has been defined as a lib program.");