博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单的C语言语法检查器的实现
阅读量:4348 次
发布时间:2019-06-07

本文共 77670 字,大约阅读时间需要 258 分钟。

  我自己的实现方法的核心过程:首先用一个非终结符代表所有要检查的程序代码,然后根据文法将这个整体的符号不断展开,以拼凑成按检查的程序的顺序排列的终结符序列,能成功说明语法正确,否则有错误。

关键词:分词;First集;Select集;

  目前还存在的问题:

    1.因为同一个非终结符->终结符的转化可能有多种解释,所以目前我的非终结符展开这里是用递归写的,因此不能定位具体错在哪里。

    2.int a={1,2};int a[2]={1,'b'};这种该出错的地方不会出错。这个比较致命,但目前还没想好怎么解决。

  代码部分借鉴了,我直接用了他的分词的scnner函数和宏定义的部分。他的程序总共2000+行,我改了一下,总共只用1000行就实现了他的功能,其中500行是抄的他的分词......并且修改了他的程序里的一些错误。

Grammar.txt:文法的定义

<程序闭包>
->
<声明语句闭包>
#
<程序闭包>
->
<函数定义>
#
<程序闭包>
-> $ #
<函数定义>
->
<修饰词闭包>
<类型>
<变量>
(
<参数声明>
) {
<函数块>
} #
<修饰词闭包>
->
<修饰词>
<修饰词闭包>
#
<修饰词闭包>
-> $ #
<修饰词>
-> describe #
<类型>
-> type
<取地址>
#
<取地址>
->
<星号闭包>
#
<星号闭包>
->
<星号>
<星号闭包>
#
<星号闭包>
-> $ #
<星号>
-> * #
<变量>
->
<标志符>
<数组下标>
#
<标志符>
-> id #
<数组下标>
-> [
<因式>
] #
<数组下标>
-> $ #
<因式>
-> (
<表达式>
) #
<因式>
->
<变量>
#
<因式>
->
<数字>
#
<数字>
-> digit #
<数字>
-> string #
<表达式>
->
<因子>
<项>
#
<因子>
->
<因式>
<因式递归>
#
<因式递归>
-> *
<因式>
<因式递归>
#
<因式递归>
-> /
<因式>
<因式递归>
#
<因式递归>
-> $ #
<项>
-> +
<因子>
<项>
#
<项>
-> -
<因子>
<项>
#
<项>
-> $ #
<参数声明>
->
<声明>
<声明闭包>
#
<参数声明>
-> $ #
<声明>
->
<修饰词闭包>
<类型>
<变量>
<赋初值>
#
<赋初值>
-> =
<右值>
#
<赋初值>
-> $ #
<右值>
->
<表达式>
#
<右值>
-> {
<多个数据>
} #
<多个数据>
->
<数字>
<数字闭包>
#
<数字闭包>
-> ,
<数字>
<数字闭包>
#
<数字闭包>
-> $ #
<声明闭包>
-> ,
<声明>
<声明闭包>
#
<声明闭包>
-> $ #
<函数块>
->
<声明语句闭包>
<函数块闭包>
#
<声明语句闭包>
->
<声明语句>
<声明语句闭包>
#
<声明语句闭包>
-> $ #
<声明语句>
->
<声明>
; #
<函数块闭包>
->
<赋值函数>
<函数块闭包>
#
<函数块闭包>
->
<函数块闭包>
#
<函数块闭包>
->
<条件语句>
<函数块闭包>
#
<函数块闭包>
->
<函数返回>
<函数块闭包>
#
<函数块闭包>
-> $ #
<赋值函数>
->
<变量>
<赋值或函数调用>
#
<赋值或函数调用>
-> =
<右值>
; #
<赋值或函数调用>
-> (
<参数列表>
) ; #
<参数列表>
->
<参数>
<参数闭包>
#
<参数闭包>
-> ,
<参数>
<参数闭包>
#
<参数闭包>
-> $ #
<参数>
->
<标志符>
#
<参数>
->
<数字>
#
<参数>
->
<字符串>
#
<字符串>
-> string #
-> for (
<赋值函数>
<逻辑表达式>
;
<后缀表达式>
) {
<函数块>
} #
<逻辑表达式>
->
<表达式>
<逻辑运算符>
<表达式>
#
<逻辑运算符>
-> < #
<逻辑运算符>
-> > #
<逻辑运算符>
-> == #
<逻辑运算符>
-> != #
<后缀表达式>
->
<变量>
<后缀运算符>
#
<后缀运算符>
-> ++ #
<后缀运算符>
-> -- #
<条件语句>
-> if (
<逻辑表达式>
) {
<函数块>
}
<否则语句>
#
<否则语句>
-> else {
<函数块>
} #
<否则语句>
-> $ #
<函数返回>
-> return
<因式>
; #
View Code

Grammar.cpp:主程序

#include "initialize.h"int main() {    Init();    Scan();    Analyse();    getchar();    return 0;}

initialize.h:初始化

#ifndef __INIT__#define __INIT__#include "WA.h"#include "SA.h"#include "Macro_Struct.h"void InitKeyMap() {    keyMap.clear();    keyMap.push_back(make_pair("auto", AUTO));    keyMap.push_back(make_pair("break", BREAK));    keyMap.push_back(make_pair("case", CASE));    keyMap.push_back(make_pair("char", CHAR));    keyMap.push_back(make_pair("const", CONST));    keyMap.push_back(make_pair("continue", CONTINUE));    keyMap.push_back(make_pair("default", DEFAULT));    keyMap.push_back(make_pair("do", DO));    keyMap.push_back(make_pair("double", DOUBLE));    keyMap.push_back(make_pair("else", ELSE));    keyMap.push_back(make_pair("enum", ENUM));    keyMap.push_back(make_pair("extern", EXTERN));    keyMap.push_back(make_pair("float", FLOAT));    keyMap.push_back(make_pair("for", FOR));    keyMap.push_back(make_pair("goto", GOTO));    keyMap.push_back(make_pair("if", IF));    keyMap.push_back(make_pair("int", INT));    keyMap.push_back(make_pair("long", LONG));    keyMap.push_back(make_pair("register", REGISTER));    keyMap.push_back(make_pair("return", RETURN));    keyMap.push_back(make_pair("short", SHORT));    keyMap.push_back(make_pair("signed", SIGNED));    keyMap.push_back(make_pair("sizeof", SIZEOF));    keyMap.push_back(make_pair("static", STATIC));    keyMap.push_back(make_pair("struct", STRUCT));    keyMap.push_back(make_pair("switch", SWITCH));    keyMap.push_back(make_pair("typedef", TYPEDEF));    keyMap.push_back(make_pair("union", UNION));    keyMap.push_back(make_pair("unsigned", UNSIGNED));    keyMap.push_back(make_pair("void", VOID));    keyMap.push_back(make_pair("volatile", VOLATILE));    keyMap.push_back(make_pair("while", WHILE));    keyMap.push_back(make_pair("describe", DESCRIBE));    keyMap.push_back(make_pair("type", TYPE));    //keyMap.push_back(make_pair("string", STRING));    keyMap.push_back(make_pair("digit", DIGIT));}void InitOperMap() {    operMap.clear();    operMap.push_back(make_pair("!", NOT));    operMap.push_back(make_pair("&", BYTE_AND));    operMap.push_back(make_pair("~", COMPLEMENT));    operMap.push_back(make_pair("^", BYTE_XOR));    operMap.push_back(make_pair("*", MUL));    operMap.push_back(make_pair("/", DIV));    operMap.push_back(make_pair("%", MOD));    operMap.push_back(make_pair("+", ADD));    operMap.push_back(make_pair("-", SUB));    operMap.push_back(make_pair("<", LES_THAN));    operMap.push_back(make_pair(">", GRT_THAN));    operMap.push_back(make_pair("=", ASG));    operMap.push_back(make_pair("->", ARROW));    operMap.push_back(make_pair("++", SELF_ADD));    operMap.push_back(make_pair("--", SELF_SUB));    operMap.push_back(make_pair("<<", LEFT_MOVE));    operMap.push_back(make_pair(">>", RIGHT_MOVE));    operMap.push_back(make_pair("<=", LES_EQUAL));    operMap.push_back(make_pair(">=", GRT_EQUAL));    operMap.push_back(make_pair("==", EQUAL));    operMap.push_back(make_pair("!=", NOT_EQUAL));    operMap.push_back(make_pair("&&", AND));    operMap.push_back(make_pair("||", OR));    operMap.push_back(make_pair("+=", COMPLETE_ADD));    operMap.push_back(make_pair("-=", COMPLETE_SUB));    operMap.push_back(make_pair("*=", COMPLETE_MUL));    operMap.push_back(make_pair("/=", COMPLETE_DIV));    operMap.push_back(make_pair("^=", COMPLETE_BYTE_XOR));    operMap.push_back(make_pair("&=", COMPLETE_BYTE_AND));    operMap.push_back(make_pair("~=", COMPLETE_COMPLEMENT));    operMap.push_back(make_pair("%=", COMPLETE_MOD));    operMap.push_back(make_pair("|", BYTE_OR));}void InitLimitMap() {    limitMap.clear();    limitMap.push_back(make_pair("(", LEFT_BRA));    limitMap.push_back(make_pair(")", RIGHT_BRA));    limitMap.push_back(make_pair("[", LEFT_INDEX));    limitMap.push_back(make_pair("]", RIGHT_INDEX));    limitMap.push_back(make_pair("{
", L_BOUNDER)); limitMap.push_back(make_pair("}", R_BOUNDER)); limitMap.push_back(make_pair(".", POINTER)); limitMap.push_back(make_pair("#", JING)); limitMap.push_back(make_pair("_", UNDER_LINE)); limitMap.push_back(make_pair(",", COMMA)); limitMap.push_back(make_pair(";", SEMI)); limitMap.push_back(make_pair("'", SIN_QUE)); limitMap.push_back(make_pair("\"", DOU_QUE));}void ShowExprList() { for (int i = 0; i < ExprNum; i++) { printf("%s -> ", Signature[Expr[i][0]].first); for (int j = 2; j <= Expr[i][1]; j++) { printf("%s ", Signature[Expr[i][j]].first); } printf("\n"); }}void DFS_NullPossibility(int x) { //printf("%s\n",Signature[x].first); if (visited[x]) { return; } visited[x] = true; for (int i = 0; i < ExprNum; i++) { if (Expr[i][0] != x) { continue; } bool ret = true; for (int j = 2; j <= Expr[i][1]; j++) { DFS_NullPossibility(Expr[i][j]); ret &= canBeNull[Expr[i][j]]; } if (ret) { visited[x] = true; canBeNull[x] = true; return; } }}void ReadExpr() { Signature.clear(); ifstream fin("Grammar.txt"); char str[50][50]; int Length = 0; while (fin >> str[Length]) { if (strcmp(str[Length], "#") == 0) { for (int i = 0; i < Length; i++) { if (strcmp(str[i], "->") == 0) { Expr[ExprNum][i] = Length - 1; continue; } int signID = FindSignature(str[i]); if (signID == -1) { int tempLen = strlen(str[i]); if (str[i][0] == '<' && str[i][tempLen - 1] == '>') { pair
tempPair; tempPair.first = new char [tempLen + 1]; memcpy(tempPair.first, str[i], tempLen); tempPair.first[tempLen] = '\0'; tempPair.second = Scalable; Signature.push_back(tempPair); } else { pair
tempPair; tempPair.first = new char [tempLen + 1]; memcpy(tempPair.first, str[i], tempLen); tempPair.first[tempLen] = '\0'; tempPair.second = unScalsble; Signature.push_back(tempPair); } signID = Signature.size() - 1; } Expr[ExprNum][i] = signID; } Length = 0; ExprNum++; } else { Length++; } } fin.close(); memset(canBeNull, false, sizeof(canBeNull)); for (int i = 0; i < Signature.size(); i++) { if (strcmp(Signature[i].first, "$") == 0) { canBeNull[i] = true; } } memset(visited, false, sizeof(visited)); for (int i = 0; i < Signature.size(); i++) { if (Signature[i].second == Scalable) { DFS_NullPossibility(i); } } //ShowExprList();}void DFS_FirstSet(int x) { if (visited[x] || Signature[x].second == unScalsble) { return; } visited[x] = true; for (int i = 0; i < ExprNum; i++) { if (Expr[i][0] != x) { continue; } for (int j = 2; j <= Expr[i][1]; j++) { if (Signature[Expr[i][j]].second == unScalsble) { First[x][Expr[i][j]] = true; } else { DFS_FirstSet(Expr[i][j]); for (int k = 0; k < Signature.size(); k++) { if (First[Expr[i][j]][k]) { First[x][k] = true; } } } if (!canBeNull[Expr[i][j]]) { break; } } }}void GetFirstSet() { memset(First, false, sizeof(First)); memset(visited, false, sizeof(visited)); for (int i = 0; i < Signature.size(); i++) { if (Signature[i].second == unScalsble) { continue; } DFS_FirstSet(i); }}void GetFollowSet() {}void GetSelectSet() { memset(Select, false, sizeof(Select)); for (int i = 0; i < ExprNum; i++) { for (int j = 2; j <= Expr[i][1]; j++) { if (Signature[Expr[i][j]].second == unScalsble) { Select[i][Expr[i][j]] = true; } else { for (int k = 0; k < Signature.size(); k++) { if (First[Expr[i][j]][k]) { Select[i][k] = true; } } } if (!canBeNull[Expr[i][j]]) { break; } } if (!canBeNull[Expr[i][0]]) { Select[i][FindSignature("$")] = false; } }}void ShowShiftList() { for (int i = 0; i < Signature.size(); i++) { for (int j = 0; j < Signature.size(); j++) { if (ShiftList[i][j][0][0] <= 1 || i == j) { continue; } printf("%3d %30s -> %30s\n", ShiftList[i][j][0][0], Signature[i].first, Signature[j].first); for (int k = 1; k <= ShiftList[i][j][0][0]; k++) { printf("---------->"); for (int h = 1; h <= ShiftList[i][j][k][0]; h++) { printf("%s ", Signature[ShiftList[i][j][k][h]].first); } printf("\n"); } } }}void GetShiftList() { memset(ShiftList, 0, sizeof(ShiftList)); for (int i = 0; i < ExprNum; i++) { for (int j = 0; j < Signature.size(); j++) { if (!Select[i][j]) { continue; } /*if (Signature[j].second == Scalable) { printf("OMG\n"); }*/ ShiftList[Expr[i][0]][j][0][0]++; for (int k = 1; k <= Expr[i][1]; k++) { ShiftList[Expr[i][0]][j][ShiftList[Expr[i][0]][j][0][0]][k - 1] = Expr[i][k]; } ShiftList[Expr[i][0]][j][ShiftList[Expr[i][0]][j][0][0]][0]--; } } //ShowShiftList();}void Init() { InitKeyMap(); InitOperMap(); InitLimitMap(); tokenList.clear(); errorList.clear(); ReadExpr(); GetFirstSet(); GetFollowSet(); GetSelectSet(); GetShiftList();}#endif
View Code

WA.h:词法分析

#ifndef __WA__#define __WA__#include "stdafx.h"#include "Macro_Struct.h"vector
> keyMap;vector
> operMap;vector
> limitMap;vector
tokenList;vector
errorList;int SeekKey(char * word) { for (int i = 0; i < keyMap.size(); i++) { if (strcmp(word, keyMap[i].first) == 0) { return keyMap[i].second; } } return IDENTIFER;}void InsertToken(char * content, char * describe, int type, int line) { Token tempToken; strcpy_s(tempToken.content, content); strcpy_s(tempToken.describe, describe); tempToken.type = type; tempToken.line = line; tokenList.push_back(tempToken);}void InsertError(char * content, char * describe, int type, int line) { Error tempError; strcpy_s(tempError.content, content); strcpy_s(tempError.describe, describe); tempError.type = type; tempError.line = line; errorList.push_back(tempError); printf("Line %d:%s\n", line, describe);}void preProcess(char * word, int line) { regex INCLUDE_REGEX("#include\\s*<[\\w\\.]+>\\s*"); regex DEFINE_REGEX("#define\\s+\\w+\\s+\\w+\\s*"); if (regex_match(word, INCLUDE_REGEX)) { return; } if (regex_match(word, DEFINE_REGEX)) { return; } InsertError(word, PRE_PROCESS_ERROR, PRE_PROCESS_ERROR_NUM, line);}void Scan() { char ch; char array[30];//单词长度上限是30 char * word; int i; int line = 1;//行数 FILE * infile; errno_t err = fopen_s(&infile, "input.txt", "r"); ch = fgetc(infile); while (ch != EOF) { i = 0; //以字母或者下划线开头,处理关键字或者标识符 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_') { while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_') { array[i++] = ch; ch = fgetc(infile); } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; int seekTemp = SeekKey(word); if (seekTemp != IDENTIFER) { InsertToken(word, KEY_DESC, seekTemp, line); } else { InsertToken(word, IDENTIFER_DESC, seekTemp, line); } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //以数字开头,处理数字 else if (ch >= '0' && ch <= '9') { int flag = 0; int flag2 = 0; //处理整数 while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } //处理float if (ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if (ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if (ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; if (flag == 1) { InsertError(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line); } else if (flag == 2) { InsertError(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line); } else { if (flag2 == 0) { InsertToken(word, CONSTANT_DESC, INT_VAL, line); } else { InsertToken(word, CONSTANT_DESC, FLOAT_VAL, line); } } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //以"/"开头 else if (ch == '/') { ch = fgetc(infile); //处理运算符"/=" if (ch == '=') { InsertToken("/=", OPE_DESC, COMPLETE_DIV, line); } //处理"/**/"型注释 else if (ch == '*') { ch = fgetc(infile); while (1) { while (ch != '*') { if (ch == '\n') { line++; } ch = fgetc(infile); if (ch == EOF) { InsertError(_NULL, NOTE_ERROR, NOTE_ERROR_NUM, line); return; } } ch = fgetc(infile); if (ch == '/') { break; } if (ch == EOF) { InsertError(_NULL, NOTE_ERROR, NOTE_ERROR_NUM, line); return; } } InsertToken(_NULL, NOTE_DESC, NOTE1, line); } //处理"//"型注释 else if (ch == '/') { while (ch != '\n') { ch = fgetc(infile); if (ch == EOF) { InsertToken(_NULL, NOTE_DESC, NOTE2, line); return; } } line++; InsertToken(_NULL, NOTE_DESC, NOTE2, line); if (ch == EOF) { return; } } //处理除号 else { InsertToken("/", OPE_DESC, DIV, line); } } //处理常量字符串 else if (ch == '"') { InsertToken("\"", CLE_OPE_DESC, DOU_QUE, line); ch = fgetc(infile); i = 0; while (ch != '"') { array[i++] = ch; if (ch == '\n') { line++; } ch = fgetc(infile); if (ch == EOF) { InsertError(_NULL, STRING_ERROR, STRING_ERROR_NUM, line); return; } } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; InsertToken(word, CONSTANT_DESC, STRING_VAL, line); InsertToken("\"", CLE_OPE_DESC, DOU_QUE, line); } //处理常量字符 else if (ch == '\'') { InsertToken("\'", CLE_OPE_DESC, SIN_QUE, line); ch = fgetc(infile); i = 0; while (ch != '\'') { array[i++] = ch; if (ch == '\n') { line++; } ch = fgetc(infile); if (ch == EOF) { InsertError(_NULL, CHARCONST_ERROR, CHARCONST_ERROR_NUM, line); return; } } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; InsertToken(word, CONSTANT_DESC, CHAR_VAL, line); InsertToken("\'", CLE_OPE_DESC, SIN_QUE, line); } else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { if (ch == '\n') { line++; } } else { if (ch == EOF) { return; } //处理头文件和宏常量(预处理) else if (ch == '#') { while (ch != '\n' && ch != EOF) { array[i++] = ch; ch = fgetc(infile); } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; preProcess(word, line); fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //处理-开头的运算符 else if (ch == '-') { array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { int flag = 0; int flag2 = 0; //处理整数 while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } //处理float if (ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if (ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if (ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } word = new char[i + 1]; memcpy(word, array, i); word[i] = '\0'; if (flag == 1) { InsertError(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line); } else if (flag == 2) { InsertError(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line); } else { if (flag2 == 0) { InsertToken(word, CONSTANT_DESC, INT_VAL, line); } else { InsertToken(word, CONSTANT_DESC, FLOAT_VAL, line); } } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } else if (ch == '>') { InsertToken("->", OPE_DESC, ARROW, line); } else if (ch == '-') { InsertToken("--", OPE_DESC, SELF_SUB, line); } else if (ch == '=') { InsertToken("--", OPE_DESC, SELF_SUB, line); } else { InsertToken("-", OPE_DESC, SUB, line); fseek(infile, -1L, SEEK_CUR); } } //处理+开头的运算符 else if (ch == '+') { ch = fgetc(infile); if (ch == '+') { InsertToken("++", OPE_DESC, SELF_ADD, line); } else if (ch == '=') { InsertToken("+=", OPE_DESC, COMPLETE_ADD, line); } else { InsertToken("+", OPE_DESC, ADD, line); fseek(infile, -1L, SEEK_CUR); } } //处理*开头的运算符 else if (ch == '*') { ch = fgetc(infile); if (ch == '=') { InsertToken("*=", OPE_DESC, COMPLETE_MUL, line); } else { InsertToken("*", OPE_DESC, MUL, line); fseek(infile, -1L, SEEK_CUR); } } //处理按^开头的运算符 else if (ch == '^') { ch = fgetc(infile); if (ch == '=') { InsertToken("^=", OPE_DESC, COMPLETE_BYTE_XOR, line); } else { InsertToken("^", OPE_DESC, BYTE_XOR, line); fseek(infile, -1L, SEEK_CUR); } } //处理%开头的运算符 else if (ch == '%') { ch = fgetc(infile); if (ch == '=') { InsertToken("%=", OPE_DESC, COMPLETE_MOD, line); } else { InsertToken("%", OPE_DESC, MOD, line); fseek(infile, -1L, SEEK_CUR); } } //处理&开头的运算符 else if (ch == '&') { ch = fgetc(infile); if (ch == '=') { InsertToken("&=", OPE_DESC, COMPLETE_BYTE_AND, line); } else if (ch == '&') { InsertToken("&&", OPE_DESC, AND, line); } else { InsertToken("&", OPE_DESC, BYTE_AND, line); fseek(infile, -1L, SEEK_CUR); } } //处理~开头的运算符 else if (ch == '~') { ch = fgetc(infile); if (ch == '=') { InsertToken("~=", OPE_DESC, COMPLETE_COMPLEMENT, line); } else { InsertToken("~", OPE_DESC, COMPLEMENT, line); fseek(infile, -1L, SEEK_CUR); } } //处理!开头的运算符 else if (ch == '!') { ch = fgetc(infile); if (ch == '=') { InsertToken("!=", OPE_DESC, NOT_EQUAL, line); } else { InsertToken("!", OPE_DESC, NOT, line); fseek(infile, -1L, SEEK_CUR); } } //处理
<开头的运算符 else if (ch="=" '<') { ch="fgetc(infile);" inserttoken("<<", ope_desc, left_move, line); } '=") { InsertToken("<=", OPE_DESC, LES_EQUAL, line); } else { InsertToken("<", OPE_DESC, LES_THAN, line); fseek(infile, -1L, SEEK_CUR); } } //处理>开头的运算符 else if (ch == ">
') { ch = fgetc(infile); if (ch == '>') { InsertToken(">>", OPE_DESC, RIGHT_MOVE, line); } else if (ch == '=') { InsertToken(">=", OPE_DESC, GRT_EQUAL, line); } else { InsertToken(">", OPE_DESC, GRT_THAN, line); fseek(infile, -1L, SEEK_CUR); } } //处理|开头的运算符 else if (ch == '|') { ch = fgetc(infile); if (ch == '|') { InsertToken("||", OPE_DESC, OR, line); } else { InsertToken("|", OPE_DESC, BYTE_OR, line); fseek(infile, -1L, SEEK_CUR); } } else if (ch == '=') { ch = fgetc(infile); if (ch == '=') { InsertToken("==", OPE_DESC, EQUAL, line); } else { InsertToken("=", OPE_DESC, ASG, line); fseek(infile, -1L, SEEK_CUR); } } else if (ch == '(') { InsertToken("(", CLE_OPE_DESC, LEFT_BRA, line); } else if (ch == ')') { InsertToken(")", CLE_OPE_DESC, RIGHT_BRA, line); } else if (ch == '[') { InsertToken("[", CLE_OPE_DESC, LEFT_INDEX, line); } else if (ch == ']') { InsertToken("]", CLE_OPE_DESC, RIGHT_INDEX, line); } else if (ch == '{ ') { InsertToken("{ ", CLE_OPE_DESC, L_BOUNDER, line); } else if (ch == '}') { InsertToken("}", CLE_OPE_DESC, R_BOUNDER, line); } else if (ch == '.') { InsertToken(".", CLE_OPE_DESC, POINTER, line); } else if (ch == ',') { InsertToken(",", CLE_OPE_DESC, COMMA, line); } else if (ch == ';') { InsertToken(";", CLE_OPE_DESC, SEMI, line); } else { char temp[2]; temp[0] = ch; temp[1] = '\0'; InsertError(temp, CHAR_ERROR, CHAR_ERROR_NUM, line); } } ch = fgetc(infile); } fclose(infile);}#endif
View Code

SA.h:语法分析 

#ifndef __SA__#define __SA__#include "stdafx.h"#include "Macro_Struct.h"#include "initialize.h"#define unScalsble false#define Scalable truevector
> Signature;int CodeStack[5000], TryStack[5000], tokenId[5000];int Csize = 0, Tsize = 0;int Expr[100][100];int ExprNum = 0;bool First[100][100];bool visited[100];bool Follow[100][100];bool Select[100][100];int ShiftList[100][100][10][100];bool canBeNull[100];int ArrayFlag;int FindSignature(char * str) { for (int i = 0; i < Signature.size(); i++) { if (strcmp(str, Signature[i].first) == 0) { return i; } } return -1;}int Try(int top, int sn, int ptr) { if (ptr < 0 || Tsize <= top) { return -10; } int Expl = TryStack[top]; Tsize += (ShiftList[Expl][CodeStack[ptr]][sn][0] - 1); for (int i = 1; i <= ShiftList[Expl][CodeStack[ptr]][sn][0]; i++) { TryStack[Tsize - i] = ShiftList[Expl][CodeStack[ptr]][sn][i]; } while (Tsize > top) { if (ptr < 0) { if (canBeNull[TryStack[Tsize - 1]]) { Tsize--; continue; } else { printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[0]].line, tokenList[tokenId[0]].content, Signature[Expl].first); return -10; } } if (TryStack[Tsize - 1] == CodeStack[ptr]) { Tsize--; ptr--; continue; } if (Signature[TryStack[Tsize - 1]].second == unScalsble) { printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[ptr]].line, tokenList[tokenId[ptr]].content, Signature[Expl].first); return -10; } if (ShiftList[TryStack[Tsize - 1]][CodeStack[ptr]][0][0] == 0) { if (canBeNull[TryStack[Tsize - 1]]) { Tsize--; continue; } else { printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[ptr]].line, tokenList[tokenId[ptr]].content, Signature[Expl].first); return -10; } } bool Match = false; for (int i = 1; i <= ShiftList[TryStack[Tsize - 1]][CodeStack[ptr]][0][0]; i++) { int tempTs = Tsize; int tempTi = TryStack[Tsize - 1]; int ret = Try(Tsize - 1, i, ptr); if (ret != -10) { Match = true; ptr = ret; break; } else { Tsize = tempTs; TryStack[Tsize - 1] = tempTi; } } if (!Match) { printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[ptr]].line, tokenList[tokenId[ptr]].content, Signature[Expl].first); return -10; } } return ptr;}void Analyse() { for (int i = tokenList.size() - 1; i >= 0; i--) { if (tokenList[i].type == AUTO || tokenList[i].type == CONST || tokenList[i].type == UNSIGNED || tokenList[i].type == SIGNED || tokenList[i].type == STATIC || tokenList[i].type == VOLATILE) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("describe"); } else if (tokenList[i].type == INT_VAL) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("digit"); } else if (tokenList[i].type == CHAR || tokenList[i].type == DOUBLE || tokenList[i].type == FLOAT || tokenList[i].type == INT || tokenList[i].type == LONG || tokenList[i].type == SHORT || tokenList[i].type == VOID) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("type"); } else if (tokenList[i].type == STRING_VAL) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("string"); } else if (tokenList[i].type == DOU_QUE || tokenList[i].type == SIN_QUE || tokenList[i].type == NOTE1 || tokenList[i].type == NOTE2) { } else if (tokenList[i].type == IDENTIFER) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("id"); } else if (tokenList[i].type == FOR) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("for"); } else if (tokenList[i].type == IF) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("if"); } else if (tokenList[i].type == ELSE) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("else"); } else if (tokenList[i].type == RETURN) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("return"); } else { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature(tokenList[i].content); } if (tokenList[i].type != DOU_QUE && tokenList[i].type != SIN_QUE) { printf("%15s %15s %15d\n", Signature[CodeStack[Csize - 1]].first, tokenList[i].content, tokenList[i].type); } } ArrayFlag = -1; while (Csize) { if (ShiftList[0][CodeStack[Csize - 1]][0][0] == 0) { printf("Error:Line%2d %s\n", tokenList[tokenId[Csize - 1]].line, tokenList[tokenId[Csize - 1]].content); break; } bool Match = false; for (int i = 1; i <= ShiftList[0][CodeStack[Csize - 1]][0][0]; i++) { Tsize = 1; TryStack[0] = 0; int ret = Try(0, i, Csize - 1); if (ret != -10) { Match = true; Csize = ret + 1; break; } } if (!Match) { printf("Error:Line%2d %s\n", tokenList[tokenId[Csize - 1]].line, tokenList[tokenId[Csize - 1]].content); break; } } if (Csize == 0) { printf("Successful\n"); }}#endif
View Code

 Macro_Struct.h:宏定义以及结构体定义

#ifndef __MS__#define __MS__#define AUTO 1#define BREAK 2#define CASE 3#define CHAR 4#define CONST 5#define CONTINUE 6#define DEFAULT 7#define DO 8#define DOUBLE 9#define ELSE 10#define ENUM 11#define EXTERN 12#define FLOAT 13#define FOR 14#define GOTO 15#define IF 16#define INT 17#define LONG 18#define REGISTER 19#define RETURN 20#define SHORT 21#define SIGNED 22#define SIZEOF 23#define STATIC 24#define STRUCT 25#define SWITCH 26#define TYPEDEF 27#define UNION 28#define UNSIGNED 29#define VOID 30#define VOLATILE 31#define WHILE 32#define KEY_DESC "关键字"//标志符#define IDENTIFER 40#define IDENTIFER_DESC "标志符"//常量#define INT_VAL 51 //整形常量#define CHAR_VAL 52 //字符常量#define FLOAT_VAL 53 //浮点数常量#define STRING_VAL 54 //双精度浮点数常量#define MACRO_VAL 55 //宏常量#define CONSTANT_DESC "常量"//运算符#define NOT 61   // !#define BYTE_AND 62 //&#define COMPLEMENT 63 // ~#define BYTE_XOR  64 // ^#define MUL 65 // *#define DIV 66// /#define MOD 67 // %#define ADD 68 // +#define SUB 69 // -#define LES_THAN 70 // <#define GRT_THAN 71 // >#define ASG 72 // =#define ARROW 73 // ->#define SELF_ADD 74 // ++#define SELF_SUB 75 // --#define LEFT_MOVE 76 // <<#define RIGHT_MOVE 77 // >>#define LES_EQUAL 78 // <=#define GRT_EQUAL 79 // >=#define EQUAL 80 // ==#define NOT_EQUAL 81 // !=#define AND 82 // &&#define OR 83 // ||#define COMPLETE_ADD 84 // +=#define COMPLETE_SUB 85 // -=#define COMPLETE_MUL 86 // *=#define COMPLETE_DIV 87 // /=#define COMPLETE_BYTE_XOR 88 // ^=#define COMPLETE_BYTE_AND 89 // &=#define COMPLETE_COMPLEMENT 90 // ~=#define COMPLETE_MOD 91 //%=#define BYTE_OR 92 // |#define OPE_DESC "运算符"//限界符#define LEFT_BRA 100 // (#define RIGHT_BRA 101 // )#define LEFT_INDEX 102 // [#define RIGHT_INDEX 103 // ]#define L_BOUNDER 104 //  {
#define R_BOUNDER 105 // }#define POINTER 106 // .#define JING 107 // ##define UNDER_LINE 108 // _#define COMMA 109 // ,#define SEMI 110 // ;#define SIN_QUE 111 // '#define DOU_QUE 112 // "#define CLE_OPE_DESC "限界符"#define NOTE1 120 // "/**/"注释#define NOTE2 121 // "//"注释#define NOTE_DESC "注释"#define HEADER 130 //头文件#define HEADER_DESC "头文件"//错误类型#define FLOAT_ERROR "float表示错误"#define FLOAT_ERROR_NUM 1#define DOUBLE_ERROR "double表示错误"#define DOUBLE_ERROR_NUM 2#define NOTE_ERROR "注释没有结束符"#define NOTE_ERROR_NUM 3#define STRING_ERROR "字符串常量没有结束符"#define STRING_ERROR_NUM 4#define CHARCONST_ERROR "字符常量没有结束符"#define CHARCONST_ERROR_NUM 5#define CHAR_ERROR "非法字符"#define CHAR_ERROR_NUM 6#define LEFT_BRA_ERROR "'('没有对应项"#define LEFT_BRA_ERROR_NUM 7#define RIGHT_BRA_ERROR "')'没有对应项"#define RIGHT_BRA_ERROR_NUM 8#define LEFT_INDEX_ERROR "'['没有对应项"#define LEFT_INDEX_ERROR_NUM 9#define RIGHT_INDEX_ERROR "']'没有对应项"#define RIGHT_INDEX_ERROR_NUM 10#define L_BOUNDER_ERROR "'{'没有对应项"#define L_BOUNDER_ERROR_NUM 11#define R_BOUNDER_ERROR "'}'没有对应项"#define R_BOUNDER_ERROR_NUM 12#define PRE_PROCESS_ERROR "预处理错误" //头文件或者宏定义错误#define PRE_PROCESS_ERROR_NUM 13#define _NULL "无"#define DESCRIBE 4000#define TYPE 4001#define STRING 4002#define DIGIT 4003struct Token{ char content[30];//内容 char describe[30];//描述 int type;//种别码 int line;//所在行数};struct Error { char content[30];//错误内容 char describe[30];//错误描述 int type; int line;//所在行数};#endif
View Code

stdafx.h:头文件包含

#ifndef __STDAFX__#define __STDAFX__#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#endif

input.txt:要检查的程序

---------------2016.9.23更新---------------

  又改了好几天,这个程序终于告一段落了,最近几天在之前的基础上又修改了一些错误,增加了一些功能,主要包括以下几个点:

  1.把函数的声明和定义分开,在头文件中声明,在源文件中实现。

  2.修改了声明语句必须放在相应部分的头部的缺陷。

  3.修改了程序不认识true和false等缺陷。

  4.增加了对break和continue语句正确性的检查。

  5.增加了允许多维数组的语法规则。

  6.修改了return后必须有数值的缺陷。

  7.修改了程序不认识<=和>=的缺陷。

  8.增加了允许在for循环的小括号中定义变量的规则。

  9.增加了类类型的定义规则。

  10.增加了使用变量时允许使用.操作符以使用其成员的规则。

  11.增加了允许一个表达式在任何可以使用数字的地方作为数字出现,如数组下标,函数参数,逻辑表达式和逻辑表达式的一项等的规则。

  12.修改了预处理部分不计算在行数内的缺陷。

  13.增加了大错误出现位置的大致定位功能。

  14.增加了检查出错误后跳过一定长度继续检查的功能。

全部代码:

  头文件:

  Macro_Struct.h

#include"stdafx.h"#ifndef __MACRO__#define __MACRO__#define AUTO 1#define BREAK 2#define CASE 3#define CHAR 4#define CONST 5#define CONTINUE 6#define DEFAULT 7#define DO 8#define DOUBLE 9#define ELSE 10#define ENUM 11#define EXTERN 12#define FLOAT 13#define FOR 14#define GOTO 15#define IF 16#define INT 17#define LONG 18#define REGISTER 19#define RETURN 20#define SHORT 21#define SIGNED 22//#define SIZEOF 23#define STATIC 24#define STRUCT 25#define SWITCH 26#define TYPEDEF 27#define UNION 28#define UNSIGNED 29#define VOID 30#define VOLATILE 31#define WHILE 32#define BOOL 33#define TRUE 34#define FALSE 35#define KEY_DESC "关键字"//标志符#define IDENTIFER 40#define IDENTIFER_DESC "标志符"//常量#define INT_VAL 51 //整形常量#define CHAR_VAL 52 //字符常量#define FLOAT_VAL 53 //浮点数常量#define STRING_VAL 54 //双精度浮点数常量#define MACRO_VAL 55 //宏常量#define CONSTANT_DESC "常量"//运算符#define NOT 61   // !#define BYTE_AND 62 //&#define COMPLEMENT 63 // ~#define BYTE_XOR  64 // ^#define MUL 65 // *#define DIV 66// /#define MOD 67 // %#define ADD 68 // +#define SUB 69 // -#define LES_THAN 70 // <#define GRT_THAN 71 // >#define ASG 72 // =#define ARROW 73 // ->#define SELF_ADD 74 // ++#define SELF_SUB 75 // --#define LEFT_MOVE 76 // <<#define RIGHT_MOVE 77 // >>#define LES_EQUAL 78 // <=#define GRT_EQUAL 79 // >=#define EQUAL 80 // ==#define NOT_EQUAL 81 // !=#define AND 82 // &&#define OR 83 // ||#define COMPLETE_ADD 84 // +=#define COMPLETE_SUB 85 // -=#define COMPLETE_MUL 86 // *=#define COMPLETE_DIV 87 // /=#define COMPLETE_BYTE_XOR 88 // ^=#define COMPLETE_BYTE_AND 89 // &=#define COMPLETE_COMPLEMENT 90 // ~=#define COMPLETE_MOD 91 //%=#define BYTE_OR 92 // |#define OPE_DESC "运算符"//限界符#define LEFT_BRA 100 // (#define RIGHT_BRA 101 // )#define LEFT_INDEX 102 // [#define RIGHT_INDEX 103 // ]#define L_BOUNDER 104 //  {
#define R_BOUNDER 105 // }#define POINTER 106 // .#define JING 107 // ##define UNDER_LINE 108 // _#define COMMA 109 // ,#define SEMI 110 // ;#define SIN_QUE 111 // '#define DOU_QUE 112 // "#define CLE_OPE_DESC "限界符"#define NOTE1 120 // "/**/"注释#define NOTE2 121 // "//"注释#define NOTE_DESC "注释"#define HEADER 130 //头文件#define HEADER_DESC "头文件"//错误类型#define FLOAT_ERROR "float表示错误"#define FLOAT_ERROR_NUM 1#define DOUBLE_ERROR "double表示错误"#define DOUBLE_ERROR_NUM 2#define NOTE_ERROR "注释没有结束符"#define NOTE_ERROR_NUM 3#define STRING_ERROR "字符串常量没有结束符"#define STRING_ERROR_NUM 4#define CHARCONST_ERROR "字符常量没有结束符"#define CHARCONST_ERROR_NUM 5#define CHAR_ERROR "非法字符"#define CHAR_ERROR_NUM 6#define LEFT_BRA_ERROR "'('没有对应项"#define LEFT_BRA_ERROR_NUM 7#define RIGHT_BRA_ERROR "')'没有对应项"#define RIGHT_BRA_ERROR_NUM 8#define LEFT_INDEX_ERROR "'['没有对应项"#define LEFT_INDEX_ERROR_NUM 9#define RIGHT_INDEX_ERROR "']'没有对应项"#define RIGHT_INDEX_ERROR_NUM 10#define L_BOUNDER_ERROR "'{'没有对应项"#define L_BOUNDER_ERROR_NUM 11#define R_BOUNDER_ERROR "'}'没有对应项"#define R_BOUNDER_ERROR_NUM 12#define PRE_PROCESS_ERROR "预处理错误" //头文件或者宏定义错误#define PRE_PROCESS_ERROR_NUM 13#define _NULL "无"#define DESCRIBE 4000#define TYPE 4001#define STRING 4002#define DIGIT 4003#define unScalsble false#define Scalable true#define SHOWTRYDETAIL false#define MAXLENGTH 10000#define MAXSIGN 200struct Token { char content[300];//内容 char describe[300];//描述 int type;//种别码 int line;//所在行数};struct Error { char content[300];//错误内容 char describe[300];//错误描述 int type; int line;//所在行数};#endif
View Code

   initial.h

#ifndef __INITIAL__#define __INITIAL__#include "Macro_Struct.h"void InitKeyMap();void InitOperMap();void InitLimitMap();int FindSignature(char * str);void DFS_NullPossibility(int x);void ShowExprList();void ShowShiftList();void ReadExpr();void DFS_FirstSet(int x);void GetFirstSet();void GetSelectSet();void GetShiftList();void Init();#endif
View Code

  SA.h

#ifndef __SA__#define __SA__#include "Macro_Struct.h"#include "initial.h"void ShowTryStack(FILE * ofile);void ShowCodeStack(FILE * ofile, int ptr);bool SelfDefineType(int x);int SearchNext(int x);int Try(int top, int sn, int ptr);void Analyse();#endif
View Code

  WA.h

#ifndef __WA__#define __WA__#include "Macro_Struct.h"#include "initial.h"int SeekKey(char * word);void InsertToken(char * content, char * describe, int type, int line);void InsertError___(char * content, char * describe, int type, int line);void preProcess(char * word, int line);void ShowTokenList();void Scan();void Bracket();#endif
View Code

  stdafx.h

#ifndef __STDAFX__#define __STDAFX__#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#endif
View Code

  源文件:

  initial.cpp

#include "stdafx.h"#include "initial.h"vector
> keyMap;vector
> operMap;vector
> limitMap;vector
tokenList;vector
errorList;vector
> Signature;int Expr[MAXSIGN][100];int ExprNum = 0;bool First[MAXSIGN][MAXSIGN];bool visited[MAXSIGN];bool Follow[MAXSIGN][MAXSIGN];bool Select[MAXSIGN][MAXSIGN];int ShiftList[MAXSIGN][MAXSIGN][10][100];int LoopDepth[MAXLENGTH];int BracketMatch[MAXLENGTH];bool canBeNull[MAXSIGN];int cnt;void InitKeyMap() { keyMap.clear(); keyMap.push_back(make_pair("auto", AUTO)); keyMap.push_back(make_pair("break", BREAK)); keyMap.push_back(make_pair("case", CASE)); keyMap.push_back(make_pair("char", CHAR)); keyMap.push_back(make_pair("const", CONST)); keyMap.push_back(make_pair("continue", CONTINUE)); keyMap.push_back(make_pair("default", DEFAULT)); keyMap.push_back(make_pair("do", DO)); keyMap.push_back(make_pair("double", DOUBLE)); keyMap.push_back(make_pair("else", ELSE)); keyMap.push_back(make_pair("enum", ENUM)); keyMap.push_back(make_pair("extern", EXTERN)); keyMap.push_back(make_pair("float", FLOAT)); keyMap.push_back(make_pair("for", FOR)); keyMap.push_back(make_pair("goto", GOTO)); keyMap.push_back(make_pair("if", IF)); keyMap.push_back(make_pair("int", INT)); keyMap.push_back(make_pair("long", LONG)); keyMap.push_back(make_pair("register", REGISTER)); keyMap.push_back(make_pair("return", RETURN)); keyMap.push_back(make_pair("short", SHORT)); keyMap.push_back(make_pair("signed", SIGNED)); //keyMap.push_back(make_pair("sizeof", SIZEOF)); keyMap.push_back(make_pair("static", STATIC)); keyMap.push_back(make_pair("struct", STRUCT)); keyMap.push_back(make_pair("switch", SWITCH)); keyMap.push_back(make_pair("typedef", TYPEDEF)); keyMap.push_back(make_pair("union", UNION)); keyMap.push_back(make_pair("unsigned", UNSIGNED)); keyMap.push_back(make_pair("void", VOID)); keyMap.push_back(make_pair("volatile", VOLATILE)); keyMap.push_back(make_pair("while", WHILE)); keyMap.push_back(make_pair("bool", BOOL)); keyMap.push_back(make_pair("true", TRUE)); keyMap.push_back(make_pair("false", FALSE)); //keyMap.push_back(make_pair("describe", DESCRIBE)); //keyMap.push_back(make_pair("type", TYPE)); //keyMap.push_back(make_pair("string", STRING)); //keyMap.push_back(make_pair("digit", DIGIT));}void InitOperMap() { operMap.clear(); operMap.push_back(make_pair("!", NOT)); operMap.push_back(make_pair("&", BYTE_AND)); operMap.push_back(make_pair("~", COMPLEMENT)); operMap.push_back(make_pair("^", BYTE_XOR)); operMap.push_back(make_pair("*", MUL)); operMap.push_back(make_pair("/", DIV)); operMap.push_back(make_pair("%", MOD)); operMap.push_back(make_pair("+", ADD)); operMap.push_back(make_pair("-", SUB)); operMap.push_back(make_pair("<", LES_THAN)); operMap.push_back(make_pair(">", GRT_THAN)); operMap.push_back(make_pair("=", ASG)); operMap.push_back(make_pair("->", ARROW)); operMap.push_back(make_pair("++", SELF_ADD)); operMap.push_back(make_pair("--", SELF_SUB)); operMap.push_back(make_pair("<<", LEFT_MOVE)); operMap.push_back(make_pair(">>", RIGHT_MOVE)); operMap.push_back(make_pair("<=", LES_EQUAL)); operMap.push_back(make_pair(">=", GRT_EQUAL)); operMap.push_back(make_pair("==", EQUAL)); operMap.push_back(make_pair("!=", NOT_EQUAL)); operMap.push_back(make_pair("&&", AND)); operMap.push_back(make_pair("||", OR)); operMap.push_back(make_pair("+=", COMPLETE_ADD)); operMap.push_back(make_pair("-=", COMPLETE_SUB)); operMap.push_back(make_pair("*=", COMPLETE_MUL)); operMap.push_back(make_pair("/=", COMPLETE_DIV)); operMap.push_back(make_pair("^=", COMPLETE_BYTE_XOR)); operMap.push_back(make_pair("&=", COMPLETE_BYTE_AND)); operMap.push_back(make_pair("~=", COMPLETE_COMPLEMENT)); operMap.push_back(make_pair("%=", COMPLETE_MOD)); operMap.push_back(make_pair("|", BYTE_OR));}void InitLimitMap() { limitMap.clear(); limitMap.push_back(make_pair("(", LEFT_BRA)); limitMap.push_back(make_pair(")", RIGHT_BRA)); limitMap.push_back(make_pair("[", LEFT_INDEX)); limitMap.push_back(make_pair("]", RIGHT_INDEX)); limitMap.push_back(make_pair("{ ", L_BOUNDER)); limitMap.push_back(make_pair("}", R_BOUNDER)); limitMap.push_back(make_pair(".", POINTER)); limitMap.push_back(make_pair("#", JING)); limitMap.push_back(make_pair("_", UNDER_LINE)); limitMap.push_back(make_pair(",", COMMA)); limitMap.push_back(make_pair(";", SEMI)); limitMap.push_back(make_pair("'", SIN_QUE)); limitMap.push_back(make_pair("\"", DOU_QUE));}//计算符号所对应的数字int FindSignature(char * str) { for (int i = 0; i < Signature.size(); i++) { if (strcmp(str, Signature[i].first) == 0) { return i; } } return -1;}//数字x对应的符号能否为空void DFS_NullPossibility(int x) { //printf("%s\n",Signature[x].first); if (visited[x]) { return; } visited[x] = true; for (int i = 0; i < ExprNum; i++) { if (Expr[i][0] != x) { continue; } bool ret = true; for (int j = 2; j <= Expr[i][1]; j++) { DFS_NullPossibility(Expr[i][j]); ret &= canBeNull[Expr[i][j]]; } if (ret) { visited[x] = true; canBeNull[x] = true; return; } }}//输出产生式列表void ShowExprList() { for (int i = 0; i < ExprNum; i++) { printf("%s -> ", Signature[Expr[i][0]].first); for (int j = 2; j <= Expr[i][1]; j++) { printf("%s ", Signature[Expr[i][j]].first); } printf("\n"); }}//输出状态转移关系void ShowShiftList() { for (int i = 0; i < Signature.size(); i++) { for (int j = 0; j < Signature.size(); j++) { if (ShiftList[i][j][0][0] <= 1 || i == j) { continue; } printf("%3d %30s -> %30s\n", ShiftList[i][j][0][0], Signature[i].first, Signature[j].first); for (int k = 1; k <= ShiftList[i][j][0][0]; k++) { printf("---------->"); for (int h = 1; h <= ShiftList[i][j][k][0]; h++) { printf("%s ", Signature[ShiftList[i][j][k][h]].first); } printf("\n"); } } }}//读入语法产生式void ReadExpr() { Signature.clear(); ifstream fin("Grammar.txt"); char str[50][50]; int Length = 0; while (fin >> str[Length]) { //读入一行产生式 if (strcmp(str[Length], "#") == 0) { for (int i = 0; i < Length; i++) { if (strcmp(str[i], "->") == 0) { Expr[ExprNum][i] = Length - 1; continue; } //将产生式中新出现的符号添加至符号列表 int signID = FindSignature(str[i]); if (signID == -1) { int tempLen = strlen(str[i]); //添加非终结符 if (str[i][0] == '<' && str[i][tempLen - 1] == '>') { pair
tempPair; tempPair.first = new char [tempLen + 1]; memcpy(tempPair.first, str[i], tempLen); tempPair.first[tempLen] = '\0'; tempPair.second = Scalable; Signature.push_back(tempPair); } else { //添加终结符 pair
tempPair; tempPair.first = new char [tempLen + 1]; memcpy(tempPair.first, str[i], tempLen); tempPair.first[tempLen] = '\0'; tempPair.second = unScalsble; Signature.push_back(tempPair); } signID = Signature.size() - 1; } Expr[ExprNum][i] = signID; } Length = 0; ExprNum++; } else { Length++; } } fin.close(); //计算一个符号是否可以为空 memset(canBeNull, false, sizeof(canBeNull)); for (int i = 0; i < Signature.size(); i++) { if (strcmp(Signature[i].first, "$") == 0) { canBeNull[i] = true; } } memset(visited, false, sizeof(visited)); for (int i = 0; i < Signature.size(); i++) { if (Signature[i].second == Scalable) { DFS_NullPossibility(i); } } //加入符号未定义符号 pair
tempPair; tempPair.first = new char [6]; memcpy(tempPair.first, "undef", 5); tempPair.first[5] = '\0'; tempPair.second = unScalsble; Signature.push_back(tempPair); canBeNull[Signature.size() - 1] = false; //ShowExprList();}//求数字x对应的符号的First集void DFS_FirstSet(int x) { if (visited[x] || Signature[x].second == unScalsble) { return; } visited[x] = true; for (int i = 0; i < ExprNum; i++) { if (Expr[i][0] != x) { continue; } for (int j = 2; j <= Expr[i][1]; j++) { if (Signature[Expr[i][j]].second == unScalsble) { First[x][Expr[i][j]] = true; } else { DFS_FirstSet(Expr[i][j]); for (int k = 0; k < Signature.size(); k++) { if (First[Expr[i][j]][k]) { First[x][k] = true; } } } if (!canBeNull[Expr[i][j]]) { break; } } }}//求所有非终结符的First集void GetFirstSet() { memset(First, false, sizeof(First)); memset(visited, false, sizeof(visited)); for (int i = 0; i < Signature.size(); i++) { if (Signature[i].second == unScalsble) { continue; } DFS_FirstSet(i); }}//求所有表达式的Select集void GetSelectSet() { memset(Select, false, sizeof(Select)); for (int i = 0; i < ExprNum; i++) { for (int j = 2; j <= Expr[i][1]; j++) { if (Signature[Expr[i][j]].second == unScalsble) { Select[i][Expr[i][j]] = true; } else { for (int k = 0; k < Signature.size(); k++) { if (First[Expr[i][j]][k]) { Select[i][k] = true; } } } if (!canBeNull[Expr[i][j]]) { break; } } if (!canBeNull[Expr[i][0]]) { Select[i][FindSignature("$")] = false; } }}//求非终结符->终结符的状态转移关系void GetShiftList() { memset(ShiftList, 0, sizeof(ShiftList)); int i, j; for (i = 0; i < ExprNum; i++) { for (j = 0; j < Signature.size(); j++) { if (!Select[i][j]) { continue; } ShiftList[Expr[i][0]][j][0][0]++; for (int k = 1; k <= Expr[i][1]; k++) { ShiftList[Expr[i][0]][j][ShiftList[Expr[i][0]][j][0][0]][k - 1] = Expr[i][k]; } ShiftList[ Expr[i][0] ] [j] [ ShiftList[Expr[i][0]][j][0][0] ] [0]--; } } //ShowShiftList();}//初始化语法void Init() { InitKeyMap();//初始化关键字 InitOperMap();//初始化操作符 InitLimitMap();//初始化限界符 tokenList.clear(); errorList.clear(); memset(LoopDepth, 0, sizeof(LoopDepth)); memset(BracketMatch, 0, sizeof(BracketMatch)); ReadExpr();//读入语法产生式 GetFirstSet();//计算First集 GetSelectSet();//计算Select集 GetShiftList();//计算状态转移关系}
View Code

  WA.cpp

#include "stdafx.h"#include "WA.h"extern vector
> keyMap;extern vector
> operMap;extern vector
> limitMap;extern vector
tokenList;extern vector
errorList;extern int LoopDepth[MAXLENGTH];extern int BracketMatch[MAXLENGTH];int BracStack[MAXLENGTH];int Bsize;FILE * WAofile;errno_t WAerr = fopen_s(&WAofile, "WA.txt", "w");//求字符串对应的关键字int SeekKey(char * word) { for (int i = 0; i < keyMap.size(); i++) { if (strcmp(word, keyMap[i].first) == 0) { return keyMap[i].second; } } return IDENTIFER;}//加入一个tokenvoid InsertToken(char * content, char * describe, int type, int line) { Token tempToken; strcpy_s(tempToken.content, content); strcpy_s(tempToken.describe, describe); tempToken.type = type; tempToken.line = line; tokenList.push_back(tempToken);}//加入一个错误void InsertError___(char * content, char * describe, int type, int line) { Error tempError; strcpy_s(tempError.content, content); strcpy_s(tempError.describe, describe); tempError.type = type; tempError.line = line; errorList.push_back(tempError); printf("Error:Line %d:%s\n", line, describe);}//检查预处理语句void preProcess(char * word, int line) { regex INCLUDE_REGEX("#include\\s*<[a-zA-Z0-9_\\.]+>\\s*"); regex DEFINE_REGEX("#define\\s+\\w+\\s+\\w+\\s*"); if (regex_match(word, INCLUDE_REGEX)) { return; } if (regex_match(word, DEFINE_REGEX)) { return; } InsertError___(word, PRE_PROCESS_ERROR, PRE_PROCESS_ERROR_NUM, line);}//输出token列表void ShowTokenList() { fprintf_s(WAofile, "\n------------------------------------------------------------------------------\n"); fprintf_s(WAofile, "%20s %20s %20s\n", "单词", "描述", "行数"); for (int i = 0; i < tokenList.size(); i++) { fprintf_s(WAofile, "%20s %20s %20d\n", tokenList[i].content, tokenList[i].describe, tokenList[i].line); } fprintf_s(WAofile, "\n------------------------------------------------------------------------------\n");}//读入输入文件,分词void Scan() { char ch; char array[300];//单词长度上限是30 char word[300]; int i; int line = 1;//行数 FILE * infile; errno_t err = fopen_s(&infile, "input.txt", "r"); ch = fgetc(infile); while (ch != EOF) { i = 0; //以字母或者下划线开头,处理关键字或者标识符 if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_') { while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || ch == '_') { array[i++] = ch; ch = fgetc(infile); } memcpy(word, array, i); word[i] = '\0'; int seekTemp = SeekKey(word); if (seekTemp != IDENTIFER) { InsertToken(word, KEY_DESC, seekTemp, line); } else { InsertToken(word, IDENTIFER_DESC, seekTemp, line); } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //以数字开头,处理数字 else if (ch >= '0' && ch <= '9') { int flag = 0; int flag2 = 0; //处理整数 while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } //处理float if (ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if (ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if (ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } memcpy(word, array, i); word[i] = '\0'; if (flag == 1) { InsertError___(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line); } else if (flag == 2) { InsertError___(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line); } else { if (flag2 == 0) { InsertToken(word, CONSTANT_DESC, INT_VAL, line); } else { InsertToken(word, CONSTANT_DESC, FLOAT_VAL, line); } } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //以"/"开头 else if (ch == '/') { ch = fgetc(infile); //处理运算符"/=" if (ch == '=') { InsertToken("/=", OPE_DESC, COMPLETE_DIV, line); } //处理"/**/"型注释 else if (ch == '*') { ch = fgetc(infile); while (1) { while (ch != '*') { if (ch == '\n') { line++; } ch = fgetc(infile); if (ch == EOF) { InsertError___(_NULL, NOTE_ERROR, NOTE_ERROR_NUM, line); return; } } ch = fgetc(infile); if (ch == '/') { break; } if (ch == EOF) { InsertError___(_NULL, NOTE_ERROR, NOTE_ERROR_NUM, line); return; } } InsertToken(_NULL, NOTE_DESC, NOTE1, line); } //处理"//"型注释 else if (ch == '/') { while (ch != '\n') { ch = fgetc(infile); if (ch == EOF) { InsertToken(_NULL, NOTE_DESC, NOTE2, line); return; } } line++; InsertToken(_NULL, NOTE_DESC, NOTE2, line); if (ch == EOF) { return; } } //处理除号 else { InsertToken("/", OPE_DESC, DIV, line); } } //处理常量字符串 else if (ch == '"') { InsertToken("\"", CLE_OPE_DESC, DOU_QUE, line); ch = fgetc(infile); i = 0; while (ch != '"') { array[i++] = ch; if (ch == '\n') { line++; } if (ch == '\\') { array[i++] = ch; ch = fgetc(infile); array[i++] = ch; } ch = fgetc(infile); if (ch == EOF) { InsertError___(_NULL, STRING_ERROR, STRING_ERROR_NUM, line); break; } } memcpy(word, array, i); word[i] = '\0'; InsertToken(word, CONSTANT_DESC, STRING_VAL, line); InsertToken("\"", CLE_OPE_DESC, DOU_QUE, line); } //处理常量字符 else if (ch == '\'') { InsertToken("\'", CLE_OPE_DESC, SIN_QUE, line); ch = fgetc(infile); i = 0; while (ch != '\'') { array[i++] = ch; if (ch == '\n') { line++; } if (ch == '\\') { array[i++] = ch; ch = fgetc(infile); array[i++] = ch; } ch = fgetc(infile); if (ch == EOF) { InsertError___(_NULL, CHARCONST_ERROR, CHARCONST_ERROR_NUM, line); break; } } memcpy(word, array, i); word[i] = '\0'; InsertToken(word, CONSTANT_DESC, CHAR_VAL, line); InsertToken("\'", CLE_OPE_DESC, SIN_QUE, line); } else if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') { if (ch == '\n') { line++; } } else { if (ch == EOF) { return; } //处理头文件和宏常量(预处理) else if (ch == '#') { while (ch != '\n' && ch != EOF) { array[i++] = ch; ch = fgetc(infile); } line++; memcpy(word, array, i); word[i] = '\0'; preProcess(word, line); //fseek(infile, -1L, SEEK_CUR); //向后回退一位 } //处理-开头的运算符 else if (ch == '-') { array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { int flag = 0; int flag2 = 0; //处理整数 while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } //处理float if (ch == '.') { flag2 = 1; array[i++] = ch; ch = fgetc(infile); if (ch >= '0' && ch <= '9') { while (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } } else { flag = 1; } //处理Double if (ch == 'E' || ch == 'e') { array[i++] = ch; ch = fgetc(infile); if (ch == '+' || ch == '-') { array[i++] = ch; ch = fgetc(infile); } if (ch >= '0' && ch <= '9') { array[i++] = ch; ch = fgetc(infile); } else { flag = 2; } } } memcpy(word, array, i); word[i] = '\0'; if (flag == 1) { InsertError___(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line); } else if (flag == 2) { InsertError___(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line); } else { if (flag2 == 0) { InsertToken(word, CONSTANT_DESC, INT_VAL, line); } else { InsertToken(word, CONSTANT_DESC, FLOAT_VAL, line); } } fseek(infile, -1L, SEEK_CUR); //向后回退一位 } else if (ch == '>') { InsertToken("->", OPE_DESC, ARROW, line); } else if (ch == '-') { InsertToken("--", OPE_DESC, SELF_SUB, line); } else if (ch == '=') { InsertToken("--", OPE_DESC, SELF_SUB, line); } else { InsertToken("-", OPE_DESC, SUB, line); fseek(infile, -1L, SEEK_CUR); } } //处理+开头的运算符 else if (ch == '+') { ch = fgetc(infile); if (ch == '+') { InsertToken("++", OPE_DESC, SELF_ADD, line); } else if (ch == '=') { InsertToken("+=", OPE_DESC, COMPLETE_ADD, line); } else { InsertToken("+", OPE_DESC, ADD, line); fseek(infile, -1L, SEEK_CUR); } } //处理*开头的运算符 else if (ch == '*') { ch = fgetc(infile); if (ch == '=') { InsertToken("*=", OPE_DESC, COMPLETE_MUL, line); } else { InsertToken("*", OPE_DESC, MUL, line); fseek(infile, -1L, SEEK_CUR); } } //处理按^开头的运算符 else if (ch == '^') { ch = fgetc(infile); if (ch == '=') { InsertToken("^=", OPE_DESC, COMPLETE_BYTE_XOR, line); } else { InsertToken("^", OPE_DESC, BYTE_XOR, line); fseek(infile, -1L, SEEK_CUR); } } //处理%开头的运算符 else if (ch == '%') { ch = fgetc(infile); if (ch == '=') { InsertToken("%=", OPE_DESC, COMPLETE_MOD, line); } else { InsertToken("%", OPE_DESC, MOD, line); fseek(infile, -1L, SEEK_CUR); } } //处理&开头的运算符 else if (ch == '&') { ch = fgetc(infile); if (ch == '=') { InsertToken("&=", OPE_DESC, COMPLETE_BYTE_AND, line); } else if (ch == '&') { InsertToken("&&", OPE_DESC, AND, line); } else { InsertToken("&", OPE_DESC, BYTE_AND, line); fseek(infile, -1L, SEEK_CUR); } } //处理~开头的运算符 else if (ch == '~') { ch = fgetc(infile); if (ch == '=') { InsertToken("~=", OPE_DESC, COMPLETE_COMPLEMENT, line); } else { InsertToken("~", OPE_DESC, COMPLEMENT, line); fseek(infile, -1L, SEEK_CUR); } } //处理!开头的运算符 else if (ch == '!') { ch = fgetc(infile); if (ch == '=') { InsertToken("!=", OPE_DESC, NOT_EQUAL, line); } else { InsertToken("!", OPE_DESC, NOT, line); fseek(infile, -1L, SEEK_CUR); } } //处理
<开头的运算符 else if (ch="=" '<') { ch="fgetc(infile);" inserttoken("<<", ope_desc, left_move, line); } '=") { InsertToken("<=", OPE_DESC, LES_EQUAL, line); } else { InsertToken("<", OPE_DESC, LES_THAN, line); fseek(infile, -1L, SEEK_CUR); } } //处理>开头的运算符 else if (ch == ">
') { ch = fgetc(infile); if (ch == '>') { InsertToken(">>", OPE_DESC, RIGHT_MOVE, line); } else if (ch == '=') { InsertToken(">=", OPE_DESC, GRT_EQUAL, line); } else { InsertToken(">", OPE_DESC, GRT_THAN, line); fseek(infile, -1L, SEEK_CUR); } } //处理|开头的运算符 else if (ch == '|') { ch = fgetc(infile); if (ch == '|') { InsertToken("||", OPE_DESC, OR, line); } else { InsertToken("|", OPE_DESC, BYTE_OR, line); fseek(infile, -1L, SEEK_CUR); } } else if (ch == '=') { ch = fgetc(infile); if (ch == '=') { InsertToken("==", OPE_DESC, EQUAL, line); } else { InsertToken("=", OPE_DESC, ASG, line); fseek(infile, -1L, SEEK_CUR); } } else if (ch == '(') { InsertToken("(", CLE_OPE_DESC, LEFT_BRA, line); } else if (ch == ')') { InsertToken(")", CLE_OPE_DESC, RIGHT_BRA, line); } else if (ch == '[') { InsertToken("[", CLE_OPE_DESC, LEFT_INDEX, line); } else if (ch == ']') { InsertToken("]", CLE_OPE_DESC, RIGHT_INDEX, line); } else if (ch == '{ ') { InsertToken("{ ", CLE_OPE_DESC, L_BOUNDER, line); } else if (ch == '}') { InsertToken("}", CLE_OPE_DESC, R_BOUNDER, line); } else if (ch == '.') { InsertToken(".", CLE_OPE_DESC, POINTER, line); } else if (ch == ',') { InsertToken(",", CLE_OPE_DESC, COMMA, line); } else if (ch == ';') { InsertToken(";", CLE_OPE_DESC, SEMI, line); } else { char temp[2]; temp[0] = ch; temp[1] = '\0'; InsertError___(temp, CHAR_ERROR, CHAR_ERROR_NUM, line); } } ch = fgetc(infile); } fclose(infile); for (int i = 1; i < tokenList.size(); i++) { if (tokenList[i - 1].type == STRUCT && tokenList[i].type == IDENTIFER) { tokenList[i].type = TYPE; } } ShowTokenList();}//检查括号是否匹配void Bracket() { //大括号 Bsize = 0; for (int i = 0; i < tokenList.size(); i++) { if (strcmp(tokenList[i].content, "{ ") == 0) { BracStack[Bsize++] = i; } if (strcmp(tokenList[i].content, "}") == 0) { if (Bsize) { if (strcmp(tokenList[BracStack[Bsize - 1]].content, "{ ") == 0) { BracketMatch[BracStack[Bsize - 1]] = i; BracketMatch[i] = BracStack[Bsize - 1]; Bsize--; } else { BracStack[Bsize++] = i; } } else { BracStack[Bsize++] = i; } } } for (int i = 0; i < Bsize; i++) { if (strcmp(tokenList[BracStack[i]].content, "{ ") == 0) { printf("Error:Line %d:expect }\n", tokenList[BracStack[i]].line); } else { printf("Error:Line %d:unexpected }\n", tokenList[BracStack[i]].line); } } //中括号 Bsize = 0; for (int i = 0; i < tokenList.size(); i++) { if (strcmp(tokenList[i].content, "[") == 0) { BracStack[Bsize++] = i; } if (strcmp(tokenList[i].content, "]") == 0) { if (Bsize) { if (strcmp(tokenList[BracStack[Bsize - 1]].content, "[") == 0) { BracketMatch[BracStack[Bsize - 1]] = i; BracketMatch[i] = BracStack[Bsize - 1]; Bsize--; } else { BracStack[Bsize++] = i; } } else { BracStack[Bsize++] = i; } } } for (int i = 0; i < Bsize; i++) { if (strcmp(tokenList[BracStack[i]].content, "[") == 0) { printf("Error:Line %d:expect ]\n", tokenList[BracStack[i]].line); } else { printf("Error:Line %d:unexpected ]\n", tokenList[BracStack[i]].line); } } //小括号 Bsize = 0; for (int i = 0; i < tokenList.size(); i++) { if (strcmp(tokenList[i].content, "(") == 0) { BracStack[Bsize++] = i; } if (strcmp(tokenList[i].content, ")") == 0) { if (Bsize) { if (strcmp(tokenList[BracStack[Bsize - 1]].content, "(") == 0) { BracketMatch[BracStack[Bsize - 1]] = i; BracketMatch[i] = BracStack[Bsize - 1]; Bsize--; } else { BracStack[Bsize++] = i; } } else { BracStack[Bsize++] = i; } } } for (int i = 0; i < Bsize; i++) { if (strcmp(tokenList[BracStack[i]].content, "(") == 0) { printf("Error:Line %d:expect )\n", tokenList[BracStack[i]].line); } else { printf("Error:Line %d:unexpected )\n", tokenList[BracStack[i]].line); } } //计算每个token所在的循环深度 int l, r; for (int i = 0; i < tokenList.size(); i++) { if (strcmp(tokenList[i].content, "for") == 0 || strcmp(tokenList[i].content, "while") == 0) { l = tokenList.size(); for (int j = i + 1; j < tokenList.size(); j++) { if (strcmp(tokenList[j].content, "{ ") == 0) { l = j; break; } } r = (BracketMatch[l] == 0 ? tokenList.size() : BracketMatch[l]); for (int j = l; j <= r; j++) { LoopDepth[j]++; } } }}
View Code

  SA.cpp

#include "stdafx.h"#include "SA.h"extern vector
tokenList;extern vector
> Signature;int CodeStack[MAXLENGTH], TryStack[MAXLENGTH], tokenId[MAXLENGTH];int Csize = 0, Tsize = 0;extern int ShiftList[MAXSIGN][MAXSIGN][10][100];extern bool canBeNull[MAXSIGN];extern int LoopDepth[MAXLENGTH];extern int cnt;int keyWord;int ErrorCnt;FILE * ofile;errno_t err = fopen_s(&ofile, "detail.txt", "w");int tokenNeed, tokenFound, unMatchLine, unMatchPtr, tryLength;FILE * SAofile;errno_t SAerr = fopen_s(&SAofile, "SA.txt", "w");//输出匹配栈void ShowTryStack(FILE * ofile) { if (Tsize <= 0) { printf("OMG\n"); } fprintf_s(ofile, "\n-----------------------------------------------------------------------------------------------------------------\n"); fprintf_s(ofile, "%15s ", "TryStack:"); for (int i = Tsize - 1; i >= 0; i--) { fprintf_s(ofile, "%s ", Signature[TryStack[i]].first); } fprintf_s(ofile, "\n");}//输出程序栈void ShowCodeStack(FILE * ofile, int ptr) { fprintf_s(ofile, "%15s ", "CodeStack:"); for (int i = ptr; i >= 0; i--) { fprintf_s(ofile, "%s ", Signature[CodeStack[i]].first); } fprintf_s(ofile, "\n"); fprintf_s(ofile, "-----------------------------------------------------------------------------------------------------------------\n");}//标识符是否为自定义类型bool SelfDefineType(int x) { for (int i = 0; i < x; i++) if (strcmp(tokenList[i].content, tokenList[x].content) == 0 && tokenList[i].type == TYPE) { return true; } return false;}//匹配失败后重新开始位置int SearchNext(int x) { int Mor = 0; bool changed = false; for (int i = x; i >= 0; i--) { if (strcmp(Signature[CodeStack[i]].first, "{
") == 0) { Mor += 10000; changed = true; } if (strcmp(Signature[CodeStack[i]].first, "[") == 0) { Mor += 100; changed = true; } if (strcmp(Signature[CodeStack[i]].first, "(") == 0) { Mor += 1; changed = true; } if (strcmp(Signature[CodeStack[i]].first, "}") == 0) { Mor -= 10000; changed = true; } if (strcmp(Signature[CodeStack[i]].first, "]") == 0) { Mor -= 100; changed = true; } if (strcmp(Signature[CodeStack[i]].first, ")") == 0) { Mor -= 1; changed = true; } if (Mor == 0 && changed) { return i - 1; } } return -1;}//尝试展开非终结符int Try(int top, int sn, int ptr) { if (ptr < 0 || Tsize <= top) { return -10; } int Expl = TryStack[top]; Tsize += (ShiftList[Expl][CodeStack[ptr]][sn][0] - 1); for (int i = 1; i <= ShiftList[Expl][CodeStack[ptr]][sn][0]; i++) { TryStack[Tsize - i] = ShiftList[Expl][CodeStack[ptr]][sn][i]; } keyWord = Expl; while (Tsize > top) { //fprintf_s(ofile, "\n%d", ++cnt); //ShowTryStack(ofile); //ShowCodeStack(ofile, ptr); //若程序栈为空 if (ptr < 0) { if (canBeNull[TryStack[Tsize - 1]]) { Tsize--; continue; } else { if (SHOWTRYDETAIL) { printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[0]].line, Signature[keyWord].first, tokenList[tokenId[0]].content, Signature[TryStack[top]].first); } if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) { unMatchPtr = ptr; tryLength = Tsize; tokenNeed = TryStack[Tsize - 1]; tokenFound = -1; unMatchLine = tokenList[tokenId[0]].line; } return -10; } } //未定义符号 if (CodeStack[ptr] == Signature.size() - 1) { printf("Error %d:Line %d:undefined sign <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line); ptr--; continue; } //是否为break或continue语句 if (strcmp(Signature[CodeStack[ptr]].first, "break") == 0 || strcmp(Signature[CodeStack[ptr]].first, "continue") == 0) { if (LoopDepth[tokenId[ptr]] == 0) { printf("Error %d:Line %d:can\'t break or continue out of loop <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line); } ptr--; if (ptr >= 0) { if (strcmp(Signature[CodeStack[ptr]].first, ";") == 0) { ptr--; } else { printf("Error %d:Line %d:expect ; <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line); } } else { printf("Error %d:Line %d:expect ; <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line); } } //若两栈栈顶元素相同 if (TryStack[Tsize - 1] == CodeStack[ptr]) { Tsize--; ptr--; continue; } //若匹配栈栈顶为终结符 if (Signature[TryStack[Tsize - 1]].second == unScalsble) { if (SHOWTRYDETAIL) { printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[0]].line, Signature[keyWord].first, tokenList[tokenId[0]].content, Signature[TryStack[top]].first); } if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) { unMatchPtr = ptr; tryLength = Tsize; tokenNeed = TryStack[Tsize - 1]; tokenFound = CodeStack[ptr]; unMatchLine = tokenList[tokenId[ptr]].line; } return -10; } //若无法由匹配栈栈顶转移至程序栈栈顶 if (ShiftList[TryStack[Tsize - 1]][CodeStack[ptr]][0][0] == 0) { if (canBeNull[TryStack[Tsize - 1]]) { Tsize--; continue; } else { if (SHOWTRYDETAIL) { printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[0]].line, Signature[keyWord].first, tokenList[tokenId[0]].content, Signature[TryStack[top]].first); } if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) { unMatchPtr = ptr; tryLength = Tsize; tokenNeed = TryStack[Tsize - 1]; tokenFound = CodeStack[ptr]; unMatchLine = tokenList[tokenId[ptr]].line; } return -10; } } //将匹配站栈顶按状态转移关系展开 if (ShiftList[TryStack[Tsize - 1]][CodeStack[ptr]][0][0] == 1) { int temp = TryStack[Tsize - 1]; keyWord = temp; Tsize += (ShiftList[temp][CodeStack[ptr]][1][0] - 1); for (int i = 1; i <= ShiftList[temp][CodeStack[ptr]][1][0]; i++) { TryStack[Tsize - i] = ShiftList[temp][CodeStack[ptr]][1][i]; } } else { bool Match = false; int tempKeyWord = keyWord; int tempTs = Tsize; int tempTi = TryStack[Tsize - 1]; int tempPtr = ptr; int MINptr = ptr; for (int i = ShiftList[TryStack[tempTs - 1]][CodeStack[tempPtr]][0][0]; i >= 1; i--) { int ret = Try(Tsize - 1, i, tempPtr); if (ret != -10) { Match = true; if (MINptr > ret) { MINptr = ret; } } Tsize = tempTs; TryStack[Tsize - 1] = tempTi; } if (!Match) { if (SHOWTRYDETAIL) { printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[0]].line, Signature[keyWord].first, tokenList[tokenId[0]].content, Signature[TryStack[top]].first); } if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) { unMatchPtr = ptr; tryLength = Tsize; tokenNeed = TryStack[Tsize - 1]; tokenFound = CodeStack[ptr]; unMatchLine = tokenList[tokenId[ptr]].line; } return -10; } else { ptr = MINptr; Tsize--; } keyWord = tempKeyWord; } } return ptr;}//插入符号void InsertSign(int i) { if (tokenList[i].type == AUTO || tokenList[i].type == CONST || tokenList[i].type == UNSIGNED || tokenList[i].type == SIGNED || tokenList[i].type == STATIC || tokenList[i].type == VOLATILE) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("describe"); } else if (tokenList[i].type == INT_VAL || tokenList[i].type == FLOAT_VAL || tokenList[i].type == CHAR_VAL || tokenList[i].type == TRUE || tokenList[i].type == FALSE) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("digit"); } else if (tokenList[i].type == CHAR || tokenList[i].type == DOUBLE || tokenList[i].type == FLOAT || tokenList[i].type == INT || tokenList[i].type == LONG || tokenList[i].type == SHORT || tokenList[i].type == VOID || tokenList[i].type == BOOL || tokenList[i].type == TYPE || SelfDefineType(i)) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("type"); } else if (tokenList[i].type == STRING_VAL) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("string"); } else if (tokenList[i].type == DOU_QUE || tokenList[i].type == SIN_QUE || tokenList[i].type == NOTE1 || tokenList[i].type == NOTE2) { } else if (tokenList[i].type == IDENTIFER) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("id"); } else if (tokenList[i].type == FOR) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("for"); } else if (tokenList[i].type == IF) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("if"); } else if (tokenList[i].type == ELSE) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("else"); } else if (tokenList[i].type == RETURN) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("return"); } else if (tokenList[i].type == STRUCT) { tokenId[Csize] = i; CodeStack[Csize++] = FindSignature("struct"); } else { tokenId[Csize] = i; int temp = FindSignature(tokenList[i].content); if (temp != -1) { CodeStack[Csize++] = temp; } else { CodeStack[Csize++] = Signature.size() - 1; } } if (tokenList[i].type != DOU_QUE && tokenList[i].type != SIN_QUE) { fprintf_s(SAofile, "%5d %15s %15s %15d\n", Csize - 1, Signature[CodeStack[Csize - 1]].first, tokenList[i].content, tokenList[i].line); }}//语法检查void Analyse() { //将token列表转化为程序栈 fprintf_s(SAofile, " %5s %15s %15s %15s\n", "标号" , "符号", "单词", "行数"); for (int i = tokenList.size() - 1; i >= 0; i--) { InsertSign(i); } cnt = 0; //按语法产生式检查程序栈是否符合语法 while (Csize) { if (ShiftList[0][CodeStack[Csize - 1]][0][0] == 0) { printf("Error:Line %2d %s <--------\n", tokenList[tokenId[Csize - 1]].line, tokenList[tokenId[Csize - 1]].content); Csize = SearchNext(Csize - 1) + 1; continue; } bool Match = false; unMatchPtr = 0x7FFFFFFF; tryLength = 0x7FFFFFFF; for (int i = 1; i <= ShiftList[0][CodeStack[Csize - 1]][0][0]; i++) { Tsize = 1; TryStack[0] = 0; int ret = Try(0, i, Csize - 1); if (ret != -10) { Match = true; Csize = ret + 1; break; } } if (!Match) { printf("Error %d:Line %2d %s <--------\n", ++ErrorCnt, tokenList[tokenId[Csize - 1]].line, tokenList[tokenId[Csize - 1]].content); printf("Error:Line %d:%s needed,%s found.\n", unMatchLine, Signature[tokenNeed].first, (tokenFound == -1 ? ("NULL") : (Signature[tokenFound].first))); Csize = SearchNext(Csize - 1) + 1; } } printf("Finish\n"); fclose(ofile);}
View Code

  Grammar.cpp

#include "stdafx.h"#include "Macro_Struct.h"#include "initial.h"#include "WA.h"#include "SA.h"int main() {    Init();//初始化语法    Scan();//词法检查    Bracket();//检查括号是否匹配    Analyse();//语法检查    getchar();    return 0;}
View Code

  资源文件:

  Grammar.txt

<程序闭包>
->
<声明语句>
#
<程序闭包>
->
<函数定义>
#
<程序闭包>
->
<类定义>
#
<程序闭包>
-> $ #
<类定义>
-> struct type {
<声明语句闭包>
} ; #
<函数定义>
->
<修饰词闭包>
<类型>
<变量>
(
<参数声明>
) {
<函数块>
} #
<修饰词闭包>
->
<修饰词>
<修饰词闭包>
#
<修饰词闭包>
-> $ #
<修饰词>
-> describe #
<类型>
-> type
<取地址>
#
<取地址>
->
<星号闭包>
#
<星号闭包>
->
<星号>
<星号闭包>
#
<星号闭包>
-> $ #
<星号>
-> * #
<变量>
->
<标志符闭包>
<数组闭包>
#
<标志符闭包>
-> id
<数组闭包>
#
<标志符闭包>
-> id
<数组闭包>
.
<标志符闭包>
#
<标志符闭包>
-> id
<数组闭包>
.
<标志符闭包>
(
<参数列表>
) #
<数组闭包>
->
<数组下标>
<数组闭包>
#
<数组闭包>
-> $ #
<数组下标>
-> [
<表达式>
] #
<数组下标>
-> $ #
<因式>
-> (
<表达式>
) #
<因式>
->
<变量>
#
<因式>
->
<数字>
#
<数字>
-> digit #
<数字>
-> string #
<表达式>
->
<变量>
(
<参数列表>
) #
<表达式>
->
<因子>
<项>
#
<表达式>
->
<后缀表达式>
#
<表达式>
->
<前缀表达式>
#
<因子>
->
<因式>
<因式递归>
#
<因式递归>
-> *
<因式>
<因式递归>
#
<因式递归>
-> /
<因式>
<因式递归>
#
<因式递归>
-> $ #
<项>
-> +
<因子>
<项>
#
<项>
-> -
<因子>
<项>
#
<项>
-> $ #
<参数声明>
->
<声明>
<声明闭包>
#
<参数声明>
-> $ #
<声明>
->
<修饰词闭包>
<类型>
<变量>
<赋初值>
#
<赋初值>
-> =
<右值>
#
<赋初值>
-> $ #
<右值>
->
<表达式>
#
<右值>
-> {
<多个数据>
} #
<多个数据>
->
<数字>
<数字闭包>
#
<数字闭包>
-> ,
<数字>
<数字闭包>
#
<数字闭包>
-> $ #
<声明闭包>
-> ,
<声明>
<声明闭包>
#
<声明闭包>
-> $ #
<函数块>
->
<函数块闭包>
#
<声明语句闭包>
->
<声明语句>
<声明语句闭包>
#
<声明语句闭包>
-> $ #
<声明语句>
->
<声明>
; #
<函数块闭包>
->
<变量>
;
<函数块闭包>
#
<函数块闭包>
->
<声明语句>
<函数块闭包>
#
<函数块闭包>
->
<赋值函数>
<函数块闭包>
#
<函数块闭包>
->
<函数块闭包>
#
<函数块闭包>
->
<函数块闭包>
#
<函数块闭包>
->
<条件语句>
<函数块闭包>
#
<函数块闭包>
->
<函数返回>
<函数块闭包>
#
<函数块闭包>
->
<表达式>
;
<函数块闭包>
#
<函数块闭包>
-> $ #
<赋值函数>
->
<变量>
<赋值或函数调用>
#
<赋值或函数调用>
-> =
<右值>
; #
<赋值或函数调用>
-> (
<参数列表>
) ; #
<参数列表>
-> $ #
<参数列表>
->
<参数>
<参数闭包>
#
<参数闭包>
-> ,
<参数>
<参数闭包>
#
<参数闭包>
-> $ #
<参数>
->
<标志符闭包>
#
<参数>
->
<数字>
#
<参数>
->
<字符串>
#
<参数>
->
<表达式>
#
<字符串>
-> string #
-> for (
<赋值函数>
<逻辑表达式>
;
<后缀表达式>
) {
<函数块>
} #
-> for ( type
<赋值函数>
<逻辑表达式>
;
<后缀表达式>
) {
<函数块>
} #
-> while (
<逻辑表达式>
) {
<函数块>
} #
<逻辑表达式>
->
<表达式>
#
<逻辑表达式>
->
<表达式>
<逻辑运算符>
<逻辑表达式>
#
<逻辑运算符>
-> < #
<逻辑运算符>
-> > #
<逻辑运算符>
-> == #
<逻辑运算符>
-> != #
<逻辑运算符>
-> <= #
<逻辑运算符>
-> >= #
<逻辑运算符>
-> || #
<逻辑运算符>
-> && #
<后缀表达式>
->
<变量>
<后缀运算符>
#
<后缀运算符>
-> ++ #
<后缀运算符>
-> -- #
<前缀表达式>
->
<前缀运算符>
<变量>
#
<前缀运算符>
-> ++ #
<前缀运算符>
-> -- #
<前缀运算符>
-> ! #
<条件语句>
-> if (
<逻辑表达式>
) {
<函数块>
}
<否则语句>
#
<否则语句>
-> else {
<函数块闭包>
} #
<否则语句>
-> $ #
<函数返回>
-> return
<因式>
; #
<函数返回>
-> return ; #
<终结符>
-> break #
<终结符>
-> continue #
View Code

  input.txt

#define NOT 61   #define BYTE_AND 62 #define COMPLEMENT 63 #define BYTE_XOR  64#define MUL 65 #define DIV 66#define MOD 67 #define ADD 68 #define SUB 69 #define GRT_THAN 71#define ASG 72 #define ARROW 73 #define SELF_ADD 74 #define SELF_SUB 75 #define LEFT_MOVE 76#define RIGHT_MOVE 77#define LES_EQUAL 78 #define GRT_EQUAL 79 #define EQUAL 80 #define NOT_EQUAL 81 #define AND 82 #define OR 83 #define COMPLETE_ADD 84 #define COMPLETE_SUB 85 #define COMPLETE_MUL 86 #define COMPLETE_DIV 87 #define COMPLETE_BYTE_XOR 88 #define COMPLETE_BYTE_AND 89 #define COMPLETE_COMPLEMENT 90 #define COMPLETE_MOD 91#define BYTE_OR 92struct Token {    char content[300];    char describe[300];    int type;    int line;};struct Error {    char content[300];    char describe[300];    int type;    int line;};int Expr[100][100];int ExprNum = 0;bool First[100][100];bool visited[100];bool Follow[100][100];bool Select[100][100];int ShiftList[100][100][10][100];bool canBeNull[100];int ArrayFlag;int cnt;int FindSignature(char * str) {    for (i = 0; i < Signature.size(); i++) {        if (strcmp(str, Signature[i].first) == 0) {            return i;        }    }    return -1;}void ShowExprList() {    for (i = 0; i < ExprNum; i++) {        printf("%s -> ", Signature[Expr[i][0]].first);        for (j = 2; j < Expr[i][1]; j++) {            printf("%s ", Signature[Expr[i][j]].first);        }        printf("\n");    }}int DFS_NullPossibility(int x) {    if (visited[x] == 1) {        return 0;    }    visited[x] = 1;    for (i = 0; i < ExprNum; i++) {        if (Expr[i][0] != x) {        }        bool ret = 1;        for (j = 2; j < Expr[i][1]; j++) {            DFS_NullPossibility(Expr[i][j]);            ret = canBeNull[Expr[i][j]];        }        if (ret == 1) {            visited[x] = 1;            canBeNull[x] = 1;            return 0;        }    }}void ReadExpr() {    Signature.clear();    char str[50][50];    int Length = 0;    while (1 == 1) {        if (strcmp(str[Length], "#") == 0) {            for (i = 0; i < Length; i++) {                if (strcmp(str[i], "->") == 0) {                    Expr[ExprNum][i] = Length - 1;                }                int signID = FindSignature(str[i]);                if (signID == -1) {                    int tempLen = strlen(str[i]);                    signID = Signature.size() - 1;                }                Expr[ExprNum][i] = signID;            }            Length = 0;            ExprNum++;        } else {            Length++;        }    }    fin.close();    memset(canBeNull, false, sizeof(canBeNull));    for (i = 0; i < Signature.size(); i++) {        if (strcmp(Signature[i].first, "$") == 0) {            canBeNull[i] = 1;        }    }    memset(visited, false, sizeof(visited));    for (i = 0; i < Signature.size(); i++) {        if (Signature[i].second == Scalable) {            DFS_NullPossibility(i);        }    }    memcpy(tempPair.first, "undef", 5);    tempPair.first[5] = "\0";    tempPair.second = unScalsble;    Signature.push_back(tempPair);    canBeNull[Signature.size() - 1] = 0;}void DFS_FirstSet(int x) {    visited[x] = 1;    for (i = 0; i < ExprNum; i++) {        if (Expr[i][0] != x) {        }        for (j = 2; j < Expr[i][1]; j++) {            if (Signature[Expr[i][j]].second == unScalsble) {                First[x][Expr[i][j]] = 1;            } else {                DFS_FirstSet(Expr[i][j]);                for (k = 0; k < Signature.size(); k++) {                    if (First[Expr[i][j]][k] == 1) {                        First[x][k] = 1;                    }                }            }            if (canBeNull[Expr[i][j]] == 0) {            }        }    }}void GetFirstSet() {    memset(First, false, sizeof(First));    memset(visited, false, sizeof(visited));    for (int i = 0; i < Signature.size(); i++) {        if (Signature[i].second == unScalsble) {            continue;        }        DFS_FirstSet(i);    }}void GetSelectSet() {    memset(Select, false, sizeof(Select));    for (int i = 0; i < ExprNum; i++) {        for (int j = 2; j <= Expr[i][1]; j++) {            if (Signature[Expr[i][j]].second == unScalsble) {                Select[i][Expr[i][j]] = true;            } else {                for (int k = 0; k < Signature.size(); k++) {                    if (First[Expr[i][j]][k]) {                        Select[i][k] = true;                    }                }            }            if (!canBeNull[Expr[i][j]]) {                break;            }        }        if (!canBeNull[Expr[i][0]]) {            Select[i][FindSignature("$")] = false;        }    }}void ShowShiftList() {    for (int i = 0; i < Signature.size(); i++) {        for (int j = 0; j < Signature.size(); j++) {            if (ShiftList[i][j][0][0] <= 1 || i == j) {                continue;            }            printf("%3d %30s -> %30s\n", ShiftList[i][j][0][0], Signature[i].first, Signature[j].first);            for (int k = 1; k <= ShiftList[i][j][0][0]; k++) {                printf("---------->");                for (int h = 1; h <= ShiftList[i][j][k][0]; h++) {                    printf("%s ", Signature[ShiftList[i][j][k][h]].first);                }                printf("\n");            }        }    }}void GetShiftList() {    memset(ShiftList, 0, sizeof(ShiftList));    for (int i = 0; i < ExprNum; i++) {        for (int j = 0; j < Signature.size(); j++) {            if (!Select[i][j]) {                continue;            }            ShiftList[Expr[i][0]][j][0][0]++;            for (int k = 1; k <= Expr[i][1]; k++) {                ShiftList[Expr[i][0]][j][ShiftList[Expr[i][0]][j][0][0]][k - 1] = Expr[i][k];            }            ShiftList[Expr[i][0]][j][ShiftList[Expr[i][0]][j][0][0]][0]--;        }    }    //ShowShiftList();}void Init() {    InitKeyMap();    InitOperMap();    InitLimitMap();    tokenList.clear();    errorList.clear();    ReadExpr();    GetFirstSet();    GetSelectSet();    GetShiftList();}int SeekKey(char * word) {    for (int i = 0; i < keyMap.size(); i++) {        if (strcmp(word, keyMap[i].first) == 0) {            return keyMap[i].second;        }    }    return IDENTIFER;}void InsertToken(char * content, char * describe, int type, int line) {    Token tempToken;    strcpy_s(tempToken.content, content);    strcpy_s(tempToken.describe, describe);    tempToken.type = type;    tempToken.line = line;    tokenList.push_back(tempToken);}void InsertToken(char * content, char * describe, int type, int line) {    Token tempToken;    strcpy_s(tempToken.content, content);    strcpy_s(tempToken.describe, describe);    tempToken.type = type;    tempToken.line = line;    tokenList.push_back(tempToken);}void InsertError___(char * content, char * describe, int type, int line) {    Error tempError;    strcpy_s(tempError.content, content);    strcpy_s(tempError.describe, describe);    tempError.type = type;    tempError.line = line;    errorList.push_back(tempError);    printf("Line %d:%s\n", line, describe);}
View Code

 

转载于:https://www.cnblogs.com/dramstadt/p/5865624.html

你可能感兴趣的文章
MySQL binlog数据库同步技术总结
查看>>
算法设计--查找无序数组中第K大的数字
查看>>
GCC的gcc和g++区别
查看>>
CENTOS 7 和 JDK 添加中文字体
查看>>
tomcat并发优化
查看>>
welcome2
查看>>
ubuntu ssh 与 Samba安装
查看>>
C++,Windows/MFC_中L和_T()之区别
查看>>
Java NIO:FileChannel数据传输
查看>>
bzoj 2956: 模积和
查看>>
netcore编程之后面对不习惯的xshell黑屏部署,是时候使用jenkins自动化发布工具了...
查看>>
Construction machine sale effected by high price
查看>>
内存分配问题
查看>>
The area 积分
查看>>
SOCKET
查看>>
U-Boot 目录结构和编译过程
查看>>
Kafka学习之(三)Centos下给PHP开启Kafka扩展(rdkafka)
查看>>
Java通过Socket传输文件以及判断文件传输完成的方法
查看>>
java单测时的等待模块awaitility
查看>>
元素水平垂直居中(transform,margin,table-cell,jQuery)
查看>>