一个简单的C语言语法检查器的实现
我自己的实现方法的核心过程:首先用一个非终结符代表所有要检查的程序代码,然后根据文法将这个整体的符号不断展开,以拼凑成按检查的程序的顺序排列的终结符序列,能成功说明语法正确,否则有错误。
关键词:分词;First集;Select集;
目前还存在的问题:
1.因为同一个非终结符->终结符的转化可能有多种解释,所以目前我的非终结符展开这里是用递归写的,因此不能定位具体错在哪里。
2.int a={1,2};int a[2]={1,'b'};这种该出错的地方不会出错。这个比较致命,但目前还没想好怎么解决。
代码部分借鉴了这里,我直接用了他的分词的scnner函数和宏定义的部分。他的程序总共2000+行,我改了一下,总共只用1000行就实现了他的功能,其中500行是抄的他的分词......并且修改了他的程序里的一些错误。
Grammar.txt:文法的定义
<程序闭包> -> <声明语句闭包> #
<程序闭包> -> <函数定义> #
<程序闭包> -> $ #
<函数定义> -> <修饰词闭包> <类型> <变量> ( <参数声明> ) { <函数块> } #
<修饰词闭包> -> <修饰词> <修饰词闭包> #
<修饰词闭包> -> $ #
<修饰词> -> describe #
<类型> -> type <取地址> #
<取地址> -> <星号闭包> #
<星号闭包> -> <星号> <星号闭包> #
<星号闭包> -> $ #
<星号> -> * #
<变量> -> <标志符> <数组下标> #
<标志符> -> id #
<数组下标> -> [ <因式> ] #
<数组下标> -> $ #
<因式> -> ( <表达式> ) #
<因式> -> <变量> #
<因式> -> <数字> #
<数字> -> digit #
<数字> -> string #
<表达式> -> <因子> <项> #
<因子> -> <因式> <因式递归> #
<因式递归> -> * <因式> <因式递归> #
<因式递归> -> / <因式> <因式递归> #
<因式递归> -> $ #
<项> -> + <因子> <项> #
<项> -> - <因子> <项> #
<项> -> $ #
<参数声明> -> <声明> <声明闭包> #
<参数声明> -> $ #
<声明> -> <修饰词闭包> <类型> <变量> <赋初值> #
<赋初值> -> = <右值> #
<赋初值> -> $ #
<右值> -> <表达式> #
<右值> -> { <多个数据> } #
<多个数据> -> <数字> <数字闭包> #
<数字闭包> -> , <数字> <数字闭包> #
<数字闭包> -> $ #
<声明闭包> -> , <声明> <声明闭包> #
<声明闭包> -> $ #
<函数块> -> <声明语句闭包> <函数块闭包> #
<声明语句闭包> -> <声明语句> <声明语句闭包> #
<声明语句闭包> -> $ #
<声明语句> -> <声明> ; #
<函数块闭包> -> <赋值函数> <函数块闭包> #
<函数块闭包> -> <for循环> <函数块闭包> #
<函数块闭包> -> <条件语句> <函数块闭包> #
<函数块闭包> -> <函数返回> <函数块闭包> #
<函数块闭包> -> $ #
<赋值函数> -> <变量> <赋值或函数调用> #
<赋值或函数调用> -> = <右值> ; #
<赋值或函数调用> -> ( <参数列表> ) ; #
<参数列表> -> <参数> <参数闭包> #
<参数闭包> -> , <参数> <参数闭包> #
<参数闭包> -> $ #
<参数> -> <标志符> #
<参数> -> <数字> #
<参数> -> <字符串> #
<字符串> -> string #
<for循环> -> for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } #
<逻辑表达式> -> <表达式> <逻辑运算符> <表达式> #
<逻辑运算符> -> < #
<逻辑运算符> -> > #
<逻辑运算符> -> == #
<逻辑运算符> -> != #
<后缀表达式> -> <变量> <后缀运算符> #
<后缀运算符> -> ++ #
<后缀运算符> -> -- #
<条件语句> -> if ( <逻辑表达式> ) { <函数块> } <否则语句> #
<否则语句> -> else { <函数块> } #
<否则语句> -> $ #
<函数返回> -> return <因式> ; #
Grammar.cpp:主程序
#include "initialize.h"
int main() {
Init();
Scan();
Analyse();
getchar();
return ;
}
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 = ; i < ExprNum; i++) {
printf("%s -> ", Signature[Expr[i][]].first);
for (int j = ; j <= Expr[i][]; 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 = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
continue;
}
bool ret = true;
for (int j = ; j <= Expr[i][]; 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[][];
int Length = ;
while (fin >> str[Length]) {
if (strcmp(str[Length], "#") == ) {
for (int i = ; i < Length; i++) {
if (strcmp(str[i], "->") == ) {
Expr[ExprNum][i] = Length - ;
continue;
}
int signID = FindSignature(str[i]);
if (signID == -) {
int tempLen = strlen(str[i]);
if (str[i][] == '<' && str[i][tempLen - ] == '>') {
pair<char *, bool> tempPair;
tempPair.first = new char [tempLen + ];
memcpy(tempPair.first, str[i], tempLen);
tempPair.first[tempLen] = '\0';
tempPair.second = Scalable;
Signature.push_back(tempPair);
} else {
pair<char *, bool> tempPair;
tempPair.first = new char [tempLen + ];
memcpy(tempPair.first, str[i], tempLen);
tempPair.first[tempLen] = '\0';
tempPair.second = unScalsble;
Signature.push_back(tempPair);
}
signID = Signature.size() - ;
}
Expr[ExprNum][i] = signID;
}
Length = ;
ExprNum++;
} else {
Length++;
}
}
fin.close();
memset(canBeNull, false, sizeof(canBeNull));
for (int i = ; i < Signature.size(); i++) {
if (strcmp(Signature[i].first, "$") == ) {
canBeNull[i] = true;
}
}
memset(visited, false, sizeof(visited));
for (int i = ; 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 = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
continue;
}
for (int j = ; j <= Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
First[x][Expr[i][j]] = true;
} else {
DFS_FirstSet(Expr[i][j]);
for (int k = ; 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 = ; 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 = ; i < ExprNum; i++) {
for (int j = ; j <= Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
Select[i][Expr[i][j]] = true;
} else {
for (int k = ; k < Signature.size(); k++) {
if (First[Expr[i][j]][k]) {
Select[i][k] = true;
}
}
}
if (!canBeNull[Expr[i][j]]) {
break;
}
}
if (!canBeNull[Expr[i][]]) {
Select[i][FindSignature("$")] = false;
}
}
}
void ShowShiftList() {
for (int i = ; i < Signature.size(); i++) {
for (int j = ; j < Signature.size(); j++) {
if (ShiftList[i][j][][] <= || i == j) {
continue;
}
printf("%3d %30s -> %30s\n", ShiftList[i][j][][], Signature[i].first, Signature[j].first);
for (int k = ; k <= ShiftList[i][j][][]; k++) {
printf("---------->");
for (int h = ; h <= ShiftList[i][j][k][]; h++) {
printf("%s ", Signature[ShiftList[i][j][k][h]].first);
}
printf("\n");
}
}
}
}
void GetShiftList() {
memset(ShiftList, , sizeof(ShiftList));
for (int i = ; i < ExprNum; i++) {
for (int j = ; j < Signature.size(); j++) {
if (!Select[i][j]) {
continue;
}
/*if (Signature[j].second == Scalable) {
printf("OMG\n");
}*/
ShiftList[Expr[i][]][j][][]++;
for (int k = ; k <= Expr[i][]; k++) {
ShiftList[Expr[i][]][j][ShiftList[Expr[i][]][j][][]][k - ] = Expr[i][k];
}
ShiftList[Expr[i][]][j][ShiftList[Expr[i][]][j][][]][]--;
}
}
//ShowShiftList();
}
void Init() {
InitKeyMap();
InitOperMap();
InitLimitMap();
tokenList.clear();
errorList.clear();
ReadExpr();
GetFirstSet();
GetFollowSet();
GetSelectSet();
GetShiftList();
}
#endif
WA.h:词法分析
#ifndef __WA__
#define __WA__
#include "stdafx.h"
#include "Macro_Struct.h" vector<pair<const char *, int>> keyMap;
vector<pair<const char *, int>> operMap;
vector<pair<const char *, int>> limitMap;
vector<Token> tokenList;
vector<Error> errorList; int SeekKey(char * word) {
for (int i = ; i < keyMap.size(); i++) {
if (strcmp(word, keyMap[i].first) == ) {
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
char * word;
int i;
int line = ;//行数
FILE * infile;
errno_t err = fopen_s(&infile, "input.txt", "r");
ch = fgetc(infile);
while (ch != EOF) {
i = ;
//以字母或者下划线开头,处理关键字或者标识符
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_') {
while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '' && ch <= '') || ch == '_') {
array[i++] = ch;
ch = fgetc(infile);
}
word = new char[i + ];
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 >= '' && ch <= '') {
int flag = ;
int flag2 = ;
//处理整数
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
//处理float
if (ch == '.') {
flag2 = ;
array[i++] = ch;
ch = fgetc(infile);
if (ch >= '' && ch <= '') {
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
} else {
flag = ;
}
//处理Double
if (ch == 'E' || ch == 'e') {
array[i++] = ch;
ch = fgetc(infile);
if (ch == '+' || ch == '-') {
array[i++] = ch;
ch = fgetc(infile);
}
if (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
} else {
flag = ;
}
}
}
word = new char[i + ];
memcpy(word, array, i);
word[i] = '\0';
if (flag == ) {
InsertError(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line);
} else if (flag == ) {
InsertError(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line);
} else {
if (flag2 == ) {
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 () {
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 = ;
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 + ];
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 = ;
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 + ];
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 + ];
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 >= '' && ch <= '') {
int flag = ;
int flag2 = ;
//处理整数
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
//处理float
if (ch == '.') {
flag2 = ;
array[i++] = ch;
ch = fgetc(infile);
if (ch >= '' && ch <= '') {
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
} else {
flag = ;
}
//处理Double
if (ch == 'E' || ch == 'e') {
array[i++] = ch;
ch = fgetc(infile);
if (ch == '+' || ch == '-') {
array[i++] = ch;
ch = fgetc(infile);
}
if (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
} else {
flag = ;
}
}
}
word = new char[i + ];
memcpy(word, array, i);
word[i] = '\0';
if (flag == ) {
InsertError(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line);
} else if (flag == ) {
InsertError(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line);
} else {
if (flag2 == ) {
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);
if (ch == '<') {
InsertToken("<<", OPE_DESC, LEFT_MOVE, line);
} else if (ch == '=') {
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[];
temp[] = ch;
temp[] = '\0';
InsertError(temp, CHAR_ERROR, CHAR_ERROR_NUM, line);
}
}
ch = fgetc(infile);
}
fclose(infile);
} #endif
SA.h:语法分析
#ifndef __SA__
#define __SA__
#include "stdafx.h"
#include "Macro_Struct.h"
#include "initialize.h"
#define unScalsble false
#define Scalable true
vector<pair<char *, bool>> Signature;
int CodeStack[], TryStack[], tokenId[];
int Csize = , Tsize = ;
int Expr[][];
int ExprNum = ;
bool First[][];
bool visited[];
bool Follow[][];
bool Select[][];
int ShiftList[][][][];
bool canBeNull[];
int ArrayFlag;
int FindSignature(char * str) {
for (int i = ; i < Signature.size(); i++) {
if (strcmp(str, Signature[i].first) == ) {
return i;
}
}
return -;
}
int Try(int top, int sn, int ptr) {
if (ptr < || Tsize <= top) {
return -;
}
int Expl = TryStack[top];
Tsize += (ShiftList[Expl][CodeStack[ptr]][sn][] - );
for (int i = ; i <= ShiftList[Expl][CodeStack[ptr]][sn][]; i++) {
TryStack[Tsize - i] = ShiftList[Expl][CodeStack[ptr]][sn][i];
}
while (Tsize > top) {
if (ptr < ) {
if (canBeNull[TryStack[Tsize - ]]) {
Tsize--;
continue;
} else {
printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[]].line, tokenList[tokenId[]].content, Signature[Expl].first);
return -;
}
}
if (TryStack[Tsize - ] == CodeStack[ptr]) {
Tsize--;
ptr--;
continue;
}
if (Signature[TryStack[Tsize - ]].second == unScalsble) {
printf("Line%2d:%s can\' t explain as %s \n", tokenList[tokenId[ptr]].line, tokenList[tokenId[ptr]].content, Signature[Expl].first);
return -;
}
if (ShiftList[TryStack[Tsize - ]][CodeStack[ptr]][][] == ) {
if (canBeNull[TryStack[Tsize - ]]) {
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 -;
}
}
bool Match = false;
for (int i = ; i <= ShiftList[TryStack[Tsize - ]][CodeStack[ptr]][][]; i++) {
int tempTs = Tsize;
int tempTi = TryStack[Tsize - ];
int ret = Try(Tsize - , i, ptr);
if (ret != -) {
Match = true;
ptr = ret;
break;
} else {
Tsize = tempTs;
TryStack[Tsize - ] = 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 -;
}
}
return ptr;
}
void Analyse() {
for (int i = tokenList.size() - ; i >= ; 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 - ]].first, tokenList[i].content, tokenList[i].type);
}
}
ArrayFlag = -;
while (Csize) {
if (ShiftList[][CodeStack[Csize - ]][][] == ) {
printf("Error:Line%2d %s\n", tokenList[tokenId[Csize - ]].line, tokenList[tokenId[Csize - ]].content);
break;
}
bool Match = false;
for (int i = ; i <= ShiftList[][CodeStack[Csize - ]][][]; i++) {
Tsize = ;
TryStack[] = ;
int ret = Try(, i, Csize - );
if (ret != -) {
Match = true;
Csize = ret + ;
break;
}
}
if (!Match) {
printf("Error:Line%2d %s\n", tokenList[tokenId[Csize - ]].line, tokenList[tokenId[Csize - ]].content);
break;
}
}
if (Csize == ) {
printf("Successful\n");
}
}
#endif
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 4003 struct Token
{
char content[];//内容
char describe[];//描述
int type;//种别码
int line;//所在行数
}; struct Error {
char content[];//错误内容
char describe[];//错误描述
int type;
int line;//所在行数
}; #endif
stdafx.h:头文件包含
#ifndef __STDAFX__
#define __STDAFX__ #include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iomanip>
#include <stack>
#include <regex>
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 200 struct Token {
char content[];//内容
char describe[];//描述
int type;//种别码
int line;//所在行数
}; struct Error {
char content[];//错误内容
char describe[];//错误描述
int type;
int line;//所在行数
};
#endif
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
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
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
stdafx.h
#ifndef __STDAFX__
#define __STDAFX__ #include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>
#include <iomanip>
#include <stack>
#include <regex>
#include <map>
#include <windows.h>
#include <process.h>
using namespace std; #endif
源文件:
initial.cpp
#include "stdafx.h"
#include "initial.h"
vector<pair<const char *, int>> keyMap;
vector<pair<const char *, int>> operMap;
vector<pair<const char *, int>> limitMap;
vector<Token> tokenList;
vector<Error> errorList; vector<pair<char *, bool>> Signature;
int Expr[MAXSIGN][];
int ExprNum = ;
bool First[MAXSIGN][MAXSIGN];
bool visited[MAXSIGN];
bool Follow[MAXSIGN][MAXSIGN];
bool Select[MAXSIGN][MAXSIGN];
int ShiftList[MAXSIGN][MAXSIGN][][];
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 = ; i < Signature.size(); i++) {
if (strcmp(str, Signature[i].first) == ) {
return i;
}
}
return -;
}
//数字x对应的符号能否为空
void DFS_NullPossibility(int x) {
//printf("%s\n",Signature[x].first);
if (visited[x]) {
return;
}
visited[x] = true;
for (int i = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
continue;
}
bool ret = true;
for (int j = ; j <= Expr[i][]; 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 = ; i < ExprNum; i++) {
printf("%s -> ", Signature[Expr[i][]].first);
for (int j = ; j <= Expr[i][]; j++) {
printf("%s ", Signature[Expr[i][j]].first);
}
printf("\n");
}
}
//输出状态转移关系
void ShowShiftList() {
for (int i = ; i < Signature.size(); i++) {
for (int j = ; j < Signature.size(); j++) {
if (ShiftList[i][j][][] <= || i == j) {
continue;
}
printf("%3d %30s -> %30s\n", ShiftList[i][j][][], Signature[i].first, Signature[j].first);
for (int k = ; k <= ShiftList[i][j][][]; k++) {
printf("---------->");
for (int h = ; h <= ShiftList[i][j][k][]; h++) {
printf("%s ", Signature[ShiftList[i][j][k][h]].first);
}
printf("\n");
}
}
}
}
//读入语法产生式
void ReadExpr() {
Signature.clear();
ifstream fin("Grammar.txt");
char str[][];
int Length = ;
while (fin >> str[Length]) {
//读入一行产生式
if (strcmp(str[Length], "#") == ) {
for (int i = ; i < Length; i++) {
if (strcmp(str[i], "->") == ) {
Expr[ExprNum][i] = Length - ;
continue;
}
//将产生式中新出现的符号添加至符号列表
int signID = FindSignature(str[i]);
if (signID == -) {
int tempLen = strlen(str[i]);
//添加非终结符
if (str[i][] == '<' && str[i][tempLen - ] == '>') {
pair<char *, bool> tempPair;
tempPair.first = new char [tempLen + ];
memcpy(tempPair.first, str[i], tempLen);
tempPair.first[tempLen] = '\0';
tempPair.second = Scalable;
Signature.push_back(tempPair);
} else {//添加终结符
pair<char *, bool> tempPair;
tempPair.first = new char [tempLen + ];
memcpy(tempPair.first, str[i], tempLen);
tempPair.first[tempLen] = '\0';
tempPair.second = unScalsble;
Signature.push_back(tempPair);
}
signID = Signature.size() - ;
}
Expr[ExprNum][i] = signID;
}
Length = ;
ExprNum++;
} else {
Length++;
}
}
fin.close();
//计算一个符号是否可以为空
memset(canBeNull, false, sizeof(canBeNull));
for (int i = ; i < Signature.size(); i++) {
if (strcmp(Signature[i].first, "$") == ) {
canBeNull[i] = true;
}
}
memset(visited, false, sizeof(visited));
for (int i = ; i < Signature.size(); i++) {
if (Signature[i].second == Scalable) {
DFS_NullPossibility(i);
}
}
//加入符号未定义符号
pair<char *, bool> tempPair;
tempPair.first = new char [];
memcpy(tempPair.first, "undef", );
tempPair.first[] = '\0';
tempPair.second = unScalsble;
Signature.push_back(tempPair);
canBeNull[Signature.size() - ] = false;
//ShowExprList();
}
//求数字x对应的符号的First集
void DFS_FirstSet(int x) {
if (visited[x] || Signature[x].second == unScalsble) {
return;
}
visited[x] = true;
for (int i = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
continue;
}
for (int j = ; j <= Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
First[x][Expr[i][j]] = true;
} else {
DFS_FirstSet(Expr[i][j]);
for (int k = ; 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 = ; i < Signature.size(); i++) {
if (Signature[i].second == unScalsble) {
continue;
}
DFS_FirstSet(i);
}
}
//求所有表达式的Select集
void GetSelectSet() {
memset(Select, false, sizeof(Select));
for (int i = ; i < ExprNum; i++) {
for (int j = ; j <= Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
Select[i][Expr[i][j]] = true;
} else {
for (int k = ; k < Signature.size(); k++) {
if (First[Expr[i][j]][k]) {
Select[i][k] = true;
}
}
}
if (!canBeNull[Expr[i][j]]) {
break;
}
}
if (!canBeNull[Expr[i][]]) {
Select[i][FindSignature("$")] = false;
}
}
}
//求非终结符->终结符的状态转移关系
void GetShiftList() {
memset(ShiftList, , sizeof(ShiftList));
int i, j;
for (i = ; i < ExprNum; i++) {
for (j = ; j < Signature.size(); j++) {
if (!Select[i][j]) {
continue;
}
ShiftList[Expr[i][]][j][][]++;
for (int k = ; k <= Expr[i][]; k++) {
ShiftList[Expr[i][]][j][ShiftList[Expr[i][]][j][][]][k - ] = Expr[i][k];
}
ShiftList[ Expr[i][] ] [j] [ ShiftList[Expr[i][]][j][][] ] []--;
}
}
//ShowShiftList();
}
//初始化语法
void Init() {
InitKeyMap();//初始化关键字
InitOperMap();//初始化操作符
InitLimitMap();//初始化限界符
tokenList.clear();
errorList.clear();
memset(LoopDepth, , sizeof(LoopDepth));
memset(BracketMatch, , sizeof(BracketMatch));
ReadExpr();//读入语法产生式
GetFirstSet();//计算First集
GetSelectSet();//计算Select集
GetShiftList();//计算状态转移关系
}
WA.cpp
#include "stdafx.h"
#include "WA.h"
extern vector<pair<const char *, int>> keyMap;
extern vector<pair<const char *, int>> operMap;
extern vector<pair<const char *, int>> limitMap;
extern vector<Token> tokenList;
extern vector<Error> 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 = ; i < keyMap.size(); i++) {
if (strcmp(word, keyMap[i].first) == ) {
return keyMap[i].second;
}
}
return IDENTIFER;
}
//加入一个token
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("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 = ; 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[];//单词长度上限是30
char word[];
int i;
int line = ;//行数
FILE * infile;
errno_t err = fopen_s(&infile, "input.txt", "r");
ch = fgetc(infile);
while (ch != EOF) {
i = ;
//以字母或者下划线开头,处理关键字或者标识符
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || ch == '_') {
while ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '' && ch <= '') || 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 >= '' && ch <= '') {
int flag = ;
int flag2 = ;
//处理整数
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
//处理float
if (ch == '.') {
flag2 = ;
array[i++] = ch;
ch = fgetc(infile);
if (ch >= '' && ch <= '') {
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
} else {
flag = ;
}
//处理Double
if (ch == 'E' || ch == 'e') {
array[i++] = ch;
ch = fgetc(infile);
if (ch == '+' || ch == '-') {
array[i++] = ch;
ch = fgetc(infile);
}
if (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
} else {
flag = ;
}
}
}
memcpy(word, array, i);
word[i] = '\0';
if (flag == ) {
InsertError___(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line);
} else if (flag == ) {
InsertError___(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line);
} else {
if (flag2 == ) {
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 () {
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 = ;
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 = ;
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 >= '' && ch <= '') {
int flag = ;
int flag2 = ;
//处理整数
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
//处理float
if (ch == '.') {
flag2 = ;
array[i++] = ch;
ch = fgetc(infile);
if (ch >= '' && ch <= '') {
while (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
}
} else {
flag = ;
}
//处理Double
if (ch == 'E' || ch == 'e') {
array[i++] = ch;
ch = fgetc(infile);
if (ch == '+' || ch == '-') {
array[i++] = ch;
ch = fgetc(infile);
}
if (ch >= '' && ch <= '') {
array[i++] = ch;
ch = fgetc(infile);
} else {
flag = ;
}
}
}
memcpy(word, array, i);
word[i] = '\0';
if (flag == ) {
InsertError___(word, FLOAT_ERROR, FLOAT_ERROR_NUM, line);
} else if (flag == ) {
InsertError___(word, DOUBLE_ERROR, DOUBLE_ERROR_NUM, line);
} else {
if (flag2 == ) {
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);
if (ch == '<') {
InsertToken("<<", OPE_DESC, LEFT_MOVE, line);
} else if (ch == '=') {
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[];
temp[] = ch;
temp[] = '\0';
InsertError___(temp, CHAR_ERROR, CHAR_ERROR_NUM, line);
}
}
ch = fgetc(infile);
}
fclose(infile);
for (int i = ; i < tokenList.size(); i++) {
if (tokenList[i - ].type == STRUCT && tokenList[i].type == IDENTIFER) {
tokenList[i].type = TYPE;
}
}
ShowTokenList();
}
//检查括号是否匹配
void Bracket() {
//大括号
Bsize = ;
for (int i = ; i < tokenList.size(); i++) {
if (strcmp(tokenList[i].content, "{") == ) {
BracStack[Bsize++] = i;
}
if (strcmp(tokenList[i].content, "}") == ) {
if (Bsize) {
if (strcmp(tokenList[BracStack[Bsize - ]].content, "{") == ) {
BracketMatch[BracStack[Bsize - ]] = i;
BracketMatch[i] = BracStack[Bsize - ];
Bsize--;
} else {
BracStack[Bsize++] = i;
}
} else {
BracStack[Bsize++] = i;
}
}
}
for (int i = ; i < Bsize; i++) {
if (strcmp(tokenList[BracStack[i]].content, "{") == ) {
printf("Error:Line %d:expect }\n", tokenList[BracStack[i]].line);
} else {
printf("Error:Line %d:unexpected }\n", tokenList[BracStack[i]].line);
}
}
//中括号
Bsize = ;
for (int i = ; i < tokenList.size(); i++) {
if (strcmp(tokenList[i].content, "[") == ) {
BracStack[Bsize++] = i;
}
if (strcmp(tokenList[i].content, "]") == ) {
if (Bsize) {
if (strcmp(tokenList[BracStack[Bsize - ]].content, "[") == ) {
BracketMatch[BracStack[Bsize - ]] = i;
BracketMatch[i] = BracStack[Bsize - ];
Bsize--;
} else {
BracStack[Bsize++] = i;
}
} else {
BracStack[Bsize++] = i;
}
}
}
for (int i = ; i < Bsize; i++) {
if (strcmp(tokenList[BracStack[i]].content, "[") == ) {
printf("Error:Line %d:expect ]\n", tokenList[BracStack[i]].line);
} else {
printf("Error:Line %d:unexpected ]\n", tokenList[BracStack[i]].line);
}
}
//小括号
Bsize = ;
for (int i = ; i < tokenList.size(); i++) {
if (strcmp(tokenList[i].content, "(") == ) {
BracStack[Bsize++] = i;
}
if (strcmp(tokenList[i].content, ")") == ) {
if (Bsize) {
if (strcmp(tokenList[BracStack[Bsize - ]].content, "(") == ) {
BracketMatch[BracStack[Bsize - ]] = i;
BracketMatch[i] = BracStack[Bsize - ];
Bsize--;
} else {
BracStack[Bsize++] = i;
}
} else {
BracStack[Bsize++] = i;
}
}
}
for (int i = ; i < Bsize; i++) {
if (strcmp(tokenList[BracStack[i]].content, "(") == ) {
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 = ; i < tokenList.size(); i++) {
if (strcmp(tokenList[i].content, "for") == || strcmp(tokenList[i].content, "while") == ) {
l = tokenList.size();
for (int j = i + ; j < tokenList.size(); j++) {
if (strcmp(tokenList[j].content, "{") == ) {
l = j;
break;
}
}
r = (BracketMatch[l] == ? tokenList.size() : BracketMatch[l]);
for (int j = l; j <= r; j++) {
LoopDepth[j]++;
}
}
}
}
SA.cpp
#include "stdafx.h"
#include "SA.h" extern vector<Token> tokenList;
extern vector<pair<char *, bool>> Signature;
int CodeStack[MAXLENGTH], TryStack[MAXLENGTH], tokenId[MAXLENGTH];
int Csize = , Tsize = ;
extern int ShiftList[MAXSIGN][MAXSIGN][][];
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 <= ) {
printf("OMG\n");
}
fprintf_s(ofile, "\n-----------------------------------------------------------------------------------------------------------------\n");
fprintf_s(ofile, "%15s ", "TryStack:");
for (int i = Tsize - ; i >= ; 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 >= ; i--) {
fprintf_s(ofile, "%s ", Signature[CodeStack[i]].first);
}
fprintf_s(ofile, "\n");
fprintf_s(ofile, "-----------------------------------------------------------------------------------------------------------------\n");
}
//标识符是否为自定义类型
bool SelfDefineType(int x) {
for (int i = ; i < x; i++)
if (strcmp(tokenList[i].content, tokenList[x].content) == && tokenList[i].type == TYPE) {
return true;
}
return false;
}
//匹配失败后重新开始位置
int SearchNext(int x) {
int Mor = ;
bool changed = false;
for (int i = x; i >= ; i--) {
if (strcmp(Signature[CodeStack[i]].first, "{") == ) {
Mor += ;
changed = true;
}
if (strcmp(Signature[CodeStack[i]].first, "[") == ) {
Mor += ;
changed = true;
}
if (strcmp(Signature[CodeStack[i]].first, "(") == ) {
Mor += ;
changed = true;
}
if (strcmp(Signature[CodeStack[i]].first, "}") == ) {
Mor -= ;
changed = true;
}
if (strcmp(Signature[CodeStack[i]].first, "]") == ) {
Mor -= ;
changed = true;
}
if (strcmp(Signature[CodeStack[i]].first, ")") == ) {
Mor -= ;
changed = true;
}
if (Mor == && changed) {
return i - ;
}
}
return -;
}
//尝试展开非终结符
int Try(int top, int sn, int ptr) {
if (ptr < || Tsize <= top) {
return -;
}
int Expl = TryStack[top];
Tsize += (ShiftList[Expl][CodeStack[ptr]][sn][] - );
for (int i = ; i <= ShiftList[Expl][CodeStack[ptr]][sn][]; 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 < ) {
if (canBeNull[TryStack[Tsize - ]]) {
Tsize--;
continue;
} else {
if (SHOWTRYDETAIL) {
printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[]].line, Signature[keyWord].first, tokenList[tokenId[]].content, Signature[TryStack[top]].first);
}
if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) {
unMatchPtr = ptr;
tryLength = Tsize;
tokenNeed = TryStack[Tsize - ];
tokenFound = -;
unMatchLine = tokenList[tokenId[]].line;
}
return -;
}
}
//未定义符号
if (CodeStack[ptr] == Signature.size() - ) {
printf("Error %d:Line %d:undefined sign <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line);
ptr--;
continue;
}
//是否为break或continue语句
if (strcmp(Signature[CodeStack[ptr]].first, "break") == || strcmp(Signature[CodeStack[ptr]].first, "continue") == ) {
if (LoopDepth[tokenId[ptr]] == ) {
printf("Error %d:Line %d:can\'t break or continue out of loop <--------\n", ++ErrorCnt, tokenList[tokenId[ptr]].line);
}
ptr--;
if (ptr >= ) {
if (strcmp(Signature[CodeStack[ptr]].first, ";") == ) {
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 - ] == CodeStack[ptr]) {
Tsize--;
ptr--;
continue;
}
//若匹配栈栈顶为终结符
if (Signature[TryStack[Tsize - ]].second == unScalsble) {
if (SHOWTRYDETAIL) {
printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[]].line, Signature[keyWord].first, tokenList[tokenId[]].content, Signature[TryStack[top]].first);
}
if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) {
unMatchPtr = ptr;
tryLength = Tsize;
tokenNeed = TryStack[Tsize - ];
tokenFound = CodeStack[ptr];
unMatchLine = tokenList[tokenId[ptr]].line;
}
return -;
}
//若无法由匹配栈栈顶转移至程序栈栈顶
if (ShiftList[TryStack[Tsize - ]][CodeStack[ptr]][][] == ) {
if (canBeNull[TryStack[Tsize - ]]) {
Tsize--;
continue;
} else {
if (SHOWTRYDETAIL) {
printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[]].line, Signature[keyWord].first, tokenList[tokenId[]].content, Signature[TryStack[top]].first);
}
if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) {
unMatchPtr = ptr;
tryLength = Tsize;
tokenNeed = TryStack[Tsize - ];
tokenFound = CodeStack[ptr];
unMatchLine = tokenList[tokenId[ptr]].line;
}
return -;
}
}
//将匹配站栈顶按状态转移关系展开
if (ShiftList[TryStack[Tsize - ]][CodeStack[ptr]][][] == ) {
int temp = TryStack[Tsize - ];
keyWord = temp;
Tsize += (ShiftList[temp][CodeStack[ptr]][][] - );
for (int i = ; i <= ShiftList[temp][CodeStack[ptr]][][]; i++) {
TryStack[Tsize - i] = ShiftList[temp][CodeStack[ptr]][][i];
}
} else {
bool Match = false;
int tempKeyWord = keyWord;
int tempTs = Tsize;
int tempTi = TryStack[Tsize - ];
int tempPtr = ptr;
int MINptr = ptr;
for (int i = ShiftList[TryStack[tempTs - ]][CodeStack[tempPtr]][][]; i >= ; i--) {
int ret = Try(Tsize - , i, tempPtr);
if (ret != -) {
Match = true;
if (MINptr > ret) {
MINptr = ret;
}
}
Tsize = tempTs;
TryStack[Tsize - ] = tempTi;
}
if (!Match) {
if (SHOWTRYDETAIL) {
printf("Line %2d:%s:%s can\' t explain as %s \n", tokenList[tokenId[]].line, Signature[keyWord].first, tokenList[tokenId[]].content, Signature[TryStack[top]].first);
}
if ((unMatchPtr > ptr) || ((unMatchPtr == ptr) && (Tsize > tryLength))) {
unMatchPtr = ptr;
tryLength = Tsize;
tokenNeed = TryStack[Tsize - ];
tokenFound = CodeStack[ptr];
unMatchLine = tokenList[tokenId[ptr]].line;
}
return -;
} 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 != -) {
CodeStack[Csize++] = temp;
} else {
CodeStack[Csize++] = Signature.size() - ;
}
}
if (tokenList[i].type != DOU_QUE && tokenList[i].type != SIN_QUE) {
fprintf_s(SAofile, "%5d %15s %15s %15d\n", Csize - , Signature[CodeStack[Csize - ]].first, tokenList[i].content, tokenList[i].line);
}
}
//语法检查
void Analyse() {
//将token列表转化为程序栈
fprintf_s(SAofile, " %5s %15s %15s %15s\n", "标号" , "符号", "单词", "行数");
for (int i = tokenList.size() - ; i >= ; i--) {
InsertSign(i);
}
cnt = ;
//按语法产生式检查程序栈是否符合语法
while (Csize) {
if (ShiftList[][CodeStack[Csize - ]][][] == ) {
printf("Error:Line %2d %s <--------\n", tokenList[tokenId[Csize - ]].line, tokenList[tokenId[Csize - ]].content);
Csize = SearchNext(Csize - ) + ;
continue;
}
bool Match = false;
unMatchPtr = 0x7FFFFFFF;
tryLength = 0x7FFFFFFF;
for (int i = ; i <= ShiftList[][CodeStack[Csize - ]][][]; i++) {
Tsize = ;
TryStack[] = ;
int ret = Try(, i, Csize - );
if (ret != -) {
Match = true;
Csize = ret + ;
break;
}
}
if (!Match) {
printf("Error %d:Line %2d %s <--------\n", ++ErrorCnt, tokenList[tokenId[Csize - ]].line, tokenList[tokenId[Csize - ]].content);
printf("Error:Line %d:%s needed,%s found.\n", unMatchLine, Signature[tokenNeed].first, (tokenFound == - ? ("NULL") : (Signature[tokenFound].first)));
Csize = SearchNext(Csize - ) + ;
}
}
printf("Finish\n");
fclose(ofile);
}
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 ;
}
资源文件:
Grammar.txt
<程序闭包> -> <声明语句> #
<程序闭包> -> <函数定义> #
<程序闭包> -> <类定义> #
<程序闭包> -> $ #
<类定义> -> struct type { <声明语句闭包> } ; #
<函数定义> -> <修饰词闭包> <类型> <变量> ( <参数声明> ) { <函数块> } #
<修饰词闭包> -> <修饰词> <修饰词闭包> #
<修饰词闭包> -> $ #
<修饰词> -> describe #
<类型> -> type <取地址> #
<取地址> -> <星号闭包> #
<星号闭包> -> <星号> <星号闭包> #
<星号闭包> -> $ #
<星号> -> * #
<变量> -> <标志符闭包> <数组闭包> #
<标志符闭包> -> id <数组闭包> #
<标志符闭包> -> id <数组闭包> . <标志符闭包> #
<标志符闭包> -> id <数组闭包> . <标志符闭包> ( <参数列表> ) #
<数组闭包> -> <数组下标> <数组闭包> #
<数组闭包> -> $ #
<数组下标> -> [ <表达式> ] #
<数组下标> -> $ #
<因式> -> ( <表达式> ) #
<因式> -> <变量> #
<因式> -> <数字> #
<数字> -> digit #
<数字> -> string #
<表达式> -> <变量> ( <参数列表> ) #
<表达式> -> <因子> <项> #
<表达式> -> <后缀表达式> #
<表达式> -> <前缀表达式> #
<因子> -> <因式> <因式递归> #
<因式递归> -> * <因式> <因式递归> #
<因式递归> -> / <因式> <因式递归> #
<因式递归> -> $ #
<项> -> + <因子> <项> #
<项> -> - <因子> <项> #
<项> -> $ #
<参数声明> -> <声明> <声明闭包> #
<参数声明> -> $ #
<声明> -> <修饰词闭包> <类型> <变量> <赋初值> #
<赋初值> -> = <右值> #
<赋初值> -> $ #
<右值> -> <表达式> #
<右值> -> { <多个数据> } #
<多个数据> -> <数字> <数字闭包> #
<数字闭包> -> , <数字> <数字闭包> #
<数字闭包> -> $ #
<声明闭包> -> , <声明> <声明闭包> #
<声明闭包> -> $ #
<函数块> -> <函数块闭包> #
<声明语句闭包> -> <声明语句> <声明语句闭包> #
<声明语句闭包> -> $ #
<声明语句> -> <声明> ; #
<函数块闭包> -> <变量> ; <函数块闭包> #
<函数块闭包> -> <声明语句> <函数块闭包> #
<函数块闭包> -> <赋值函数> <函数块闭包> #
<函数块闭包> -> <for循环> <函数块闭包> #
<函数块闭包> -> <while循环> <函数块闭包> #
<函数块闭包> -> <条件语句> <函数块闭包> #
<函数块闭包> -> <函数返回> <函数块闭包> #
<函数块闭包> -> <表达式> ; <函数块闭包> #
<函数块闭包> -> $ #
<赋值函数> -> <变量> <赋值或函数调用> #
<赋值或函数调用> -> = <右值> ; #
<赋值或函数调用> -> ( <参数列表> ) ; #
<参数列表> -> $ #
<参数列表> -> <参数> <参数闭包> #
<参数闭包> -> , <参数> <参数闭包> #
<参数闭包> -> $ #
<参数> -> <标志符闭包> #
<参数> -> <数字> #
<参数> -> <字符串> #
<参数> -> <表达式> #
<字符串> -> string #
<for循环> -> for ( <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } #
<for循环> -> for ( type <赋值函数> <逻辑表达式> ; <后缀表达式> ) { <函数块> } #
<while循环> -> while ( <逻辑表达式> ) { <函数块> } #
<逻辑表达式> -> <表达式> #
<逻辑表达式> -> <表达式> <逻辑运算符> <逻辑表达式> #
<逻辑运算符> -> < #
<逻辑运算符> -> > #
<逻辑运算符> -> == #
<逻辑运算符> -> != #
<逻辑运算符> -> <= #
<逻辑运算符> -> >= #
<逻辑运算符> -> || #
<逻辑运算符> -> && #
<后缀表达式> -> <变量> <后缀运算符> #
<后缀运算符> -> ++ #
<后缀运算符> -> -- #
<前缀表达式> -> <前缀运算符> <变量> #
<前缀运算符> -> ++ #
<前缀运算符> -> -- #
<前缀运算符> -> ! #
<条件语句> -> if ( <逻辑表达式> ) { <函数块> } <否则语句> #
<否则语句> -> else { <函数块闭包> } #
<否则语句> -> $ #
<函数返回> -> return <因式> ; #
<函数返回> -> return ; #
<终结符> -> break #
<终结符> -> continue #
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 92
struct Token {
char content[];
char describe[];
int type;
int line;
};
struct Error {
char content[];
char describe[];
int type;
int line;
};
int Expr[][];
int ExprNum = ;
bool First[][];
bool visited[];
bool Follow[][];
bool Select[][];
int ShiftList[][][][];
bool canBeNull[];
int ArrayFlag;
int cnt;
int FindSignature(char * str) {
for (i = ; i < Signature.size(); i++) {
if (strcmp(str, Signature[i].first) == ) {
return i;
}
}
return -;
}
void ShowExprList() {
for (i = ; i < ExprNum; i++) {
printf("%s -> ", Signature[Expr[i][]].first);
for (j = ; j < Expr[i][]; j++) {
printf("%s ", Signature[Expr[i][j]].first);
}
printf("\n");
}
}
int DFS_NullPossibility(int x) {
if (visited[x] == ) {
return ;
}
visited[x] = ;
for (i = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
}
bool ret = ;
for (j = ; j < Expr[i][]; j++) {
DFS_NullPossibility(Expr[i][j]);
ret = canBeNull[Expr[i][j]];
}
if (ret == ) {
visited[x] = ;
canBeNull[x] = ;
return ;
}
}
}
void ReadExpr() {
Signature.clear();
char str[][];
int Length = ;
while ( == ) {
if (strcmp(str[Length], "#") == ) {
for (i = ; i < Length; i++) {
if (strcmp(str[i], "->") == ) {
Expr[ExprNum][i] = Length - ;
}
int signID = FindSignature(str[i]);
if (signID == -) {
int tempLen = strlen(str[i]);
signID = Signature.size() - ;
}
Expr[ExprNum][i] = signID;
}
Length = ;
ExprNum++;
} else {
Length++;
}
}
fin.close();
memset(canBeNull, false, sizeof(canBeNull));
for (i = ; i < Signature.size(); i++) {
if (strcmp(Signature[i].first, "$") == ) {
canBeNull[i] = ;
}
}
memset(visited, false, sizeof(visited));
for (i = ; i < Signature.size(); i++) {
if (Signature[i].second == Scalable) {
DFS_NullPossibility(i);
}
}
memcpy(tempPair.first, "undef", );
tempPair.first[] = "\0";
tempPair.second = unScalsble;
Signature.push_back(tempPair);
canBeNull[Signature.size() - ] = ;
}
void DFS_FirstSet(int x) {
visited[x] = ;
for (i = ; i < ExprNum; i++) {
if (Expr[i][] != x) {
}
for (j = ; j < Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
First[x][Expr[i][j]] = ;
} else {
DFS_FirstSet(Expr[i][j]);
for (k = ; k < Signature.size(); k++) {
if (First[Expr[i][j]][k] == ) {
First[x][k] = ;
}
}
}
if (canBeNull[Expr[i][j]] == ) {
}
}
}
}
void GetFirstSet() {
memset(First, false, sizeof(First));
memset(visited, false, sizeof(visited));
for (int i = ; i < Signature.size(); i++) {
if (Signature[i].second == unScalsble) {
continue;
}
DFS_FirstSet(i);
}
}
void GetSelectSet() {
memset(Select, false, sizeof(Select));
for (int i = ; i < ExprNum; i++) {
for (int j = ; j <= Expr[i][]; j++) {
if (Signature[Expr[i][j]].second == unScalsble) {
Select[i][Expr[i][j]] = true;
} else {
for (int k = ; k < Signature.size(); k++) {
if (First[Expr[i][j]][k]) {
Select[i][k] = true;
}
}
}
if (!canBeNull[Expr[i][j]]) {
break;
}
}
if (!canBeNull[Expr[i][]]) {
Select[i][FindSignature("$")] = false;
}
}
}
void ShowShiftList() {
for (int i = ; i < Signature.size(); i++) {
for (int j = ; j < Signature.size(); j++) {
if (ShiftList[i][j][][] <= || i == j) {
continue;
}
printf("%3d %30s -> %30s\n", ShiftList[i][j][][], Signature[i].first, Signature[j].first);
for (int k = ; k <= ShiftList[i][j][][]; k++) {
printf("---------->");
for (int h = ; h <= ShiftList[i][j][k][]; h++) {
printf("%s ", Signature[ShiftList[i][j][k][h]].first);
}
printf("\n");
}
}
}
}
void GetShiftList() {
memset(ShiftList, , sizeof(ShiftList));
for (int i = ; i < ExprNum; i++) {
for (int j = ; j < Signature.size(); j++) {
if (!Select[i][j]) {
continue;
}
ShiftList[Expr[i][]][j][][]++;
for (int k = ; k <= Expr[i][]; k++) {
ShiftList[Expr[i][]][j][ShiftList[Expr[i][]][j][][]][k - ] = Expr[i][k];
}
ShiftList[Expr[i][]][j][ShiftList[Expr[i][]][j][][]][]--;
}
}
//ShowShiftList();
}
void Init() {
InitKeyMap();
InitOperMap();
InitLimitMap();
tokenList.clear();
errorList.clear();
ReadExpr();
GetFirstSet();
GetSelectSet();
GetShiftList();
}
int SeekKey(char * word) {
for (int i = ; i < keyMap.size(); i++) {
if (strcmp(word, keyMap[i].first) == ) {
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);
}
一个简单的C语言语法检查器的实现的更多相关文章
- 一个简单的AMD模块加载器
一个简单的AMD模块加载器 参考 https://github.com/JsAaron/NodeJs-Demo/tree/master/require PS Aaron大大的比我的完整 PS 这不是一 ...
- 一个简单的基于 DirectShow 的播放器 2(对话框类)
上篇文章分析了一个封装DirectShow各种接口的封装类(CDXGraph):一个简单的基于 DirectShow 的播放器 1(封装类) 本文继续上篇文章,分析一下调用这个封装类(CDXGrap ...
- 一个简单的基于 DirectShow 的播放器 1(封装类)
DirectShow最主要的功能就是播放视频,在这里介绍一个简单的基于DirectShow的播放器的例子,是用MFC做的,今后有机会可以基于该播放器开发更复杂的播放器软件. 注:该例子取自于<D ...
- 利用OD破解一个简单的C语言程序
最近在学习汇编(看的是王爽老师的<汇编语言(第三版)>),然后想尝试使用OD(Ollydbg)软件破解一个简单的C语言程序练练手. 环境: C语言编译环境:VC++6.0 系统:在Wind ...
- (二)如何利用C# Roslyn编译器写一个简单的代码提示/错误检查?
上一篇我们讲了如何建立一个简单的Roslyn分析项目如分析检查我们的代码. 今天我们主要介绍各个项目中具体的作用以及可视化分析工具. 还是这种截图,可以看到解决方案下一共有三个项目. Analyzer ...
- 一个简单的C语言程序(详解)
C Primer Plus之一个简单的C语言程序(详解) #include <stdio.h> int main(void) //一个简单的 C程序 { int num; //定义一个名为 ...
- 如何利用C# Roslyn编译器写一个简单的代码提示/错误检查?
OK, 废话不多说,这些天在写C#代码时突然对于IDE提示有了一些想法,之前也有了解过,不过并没有深入. 先看个截图: 一段再简单不过的代码了,大家注意看到 count 字段下面的绿色波浪线了吗,我们 ...
- cJSON: 一个用c写的一个简单好用的JSON解析器
转自:http://blog.csdn.net/chenzhongjing/article/details/9188347 下载地址: http://sourceforge.net/projects/ ...
- 利用windows.h头文件写一个简单的C语言倒计时
今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...
随机推荐
- Mac系统下使用VirtualBox虚拟机安装win7--第五步 共享文件夹设置
1.启动virtualbox--选中win7虚拟机--点击设置--点击共享文件夹--点击右侧按钮添加共享文件夹
- JQ 练习题
1.留言板 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- Java集合源码学习(五)几种常用集合类的比较
这篇笔记对几个常用的集合实现,从效率,线程安全和应用场景进行综合比较. >>ArrayList.LinkedList与Vector的对比 (1)相同和不同都实现了List接口,使用类似.V ...
- 微信支付:“当前页面的URL未注册”
最近在尝试着写微信支付方面的内容,今天下午的时候遇到了一个问题,也就是当前页面没有进行注册的问题. 在写好后台代码之后我在微信后台配置了测试授权目录和支付白名单,如下图所示,但是无论我如何进行测试总是 ...
- Async/Await 最佳实践
其实好久以前就看过这个文章,以及类似的很多篇文章.最近在和一个新同事的交流中发现原来对async的死锁理解不是很透彻,正好最近时间比较充裕就再当一回搬运工. 本文假定你对.NET Framework ...
- wp8 入门到精通 测量代码执行时间
Stopwatch time = new Stopwatch(); byte[] target = new byte[size]; for (int j = 0; j < size; j++) ...
- Effective C++ 之 Item 1: 视C++为一个语言联邦
Effective C++ Chapter 1. 让自己习惯C++(Accustoming Yourself to C++) Item 1. 视C++为一个语言联邦(View C++ as a fed ...
- OpenMesh 之向量操作
OpenMesh 提供了许多可供使用的向量操作函数,使用特别方便. 计算距离: 从官方文档可以看到OpenMesh提供了5个函数,分别为 Scalar length() const // ...
- C泊车管理系统
// // main.c // 泊车管理系统 // // Created by 丁小未 on 13-7-14. // Copyright (c) 2013年 dingxiaowei. All ...
- Java学习笔记(四)——流程控制语句
一.条件语句 1.if条件语句 (1)语法: if(条件) { 条件成立时的代码 } (2)执行过程 2.if else语句 if(条件) { 条件成立时的代码 } else { 不成立的代码 } 3 ...