小标
2018-09-18
来源 :
阅读 1918
评论 0
摘要:本文主要向大家介绍了C/C++知识点之一个简单的C语言语法检查器的实现,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
本文主要向大家介绍了C/C++知识点之一个简单的C语言语法检查器的实现,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
目前还存在的问题:
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 <因式> ; #
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<char *, bool> 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<char *, bool> 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<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 = 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);
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[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 true
vector<pair<char *, bool>> 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) {
tokenI
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号