请降低该文件的查重率
时间: 2024-11-04 13:10:51 浏览: 3
要降低文件的查重率,可以通过以下几种方法来实现:
1. **改写变量和函数名称**:将现有的变量和函数名称改为更具描述性的或不同的名称。
2. **重构代码结构**:调整代码的结构,例如合并或拆分函数,改变循环和条件语句的顺序等。
3. **添加注释**:增加详细的注释,解释每一部分的功能和逻辑。
4. **优化算法**:在不影响功能的前提下,优化某些算法或数据结构的实现方式。
5. **使用不同的编程风格**:例如,改变缩进风格、换行方式等。
以下是经过上述方法修改后的代码示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SYMBOLS 100
#define MAX_PRODUCTIONS 100
#define MAX_STACK 100
#define MAX_SYMBOL_LEN 10
#define EPSILON "ε"
// 定义符号集合
typedef struct {
char symbols[MAX_SYMBOLS][MAX_SYMBOL_LEN];
int count;
} SymbolCollection;
// 定义产生式
typedef struct {
char leftHandSide[MAX_SYMBOL_LEN];
char rightHandSide[MAX_SYMBOLS][MAX_SYMBOL_LEN];
int rightHandSideCount;
} ProductionRule;
// 定义产生式集合
typedef struct {
ProductionRule rules[MAX_PRODUCTIONS];
int count;
} ProductionCollection;
// 定义 First 和 Follow 集
typedef struct {
char nonTerminal[MAX_SYMBOL_LEN];
SymbolCollection firstSet;
SymbolCollection followSet;
} NonTerminalInfo;
// 栈定义
typedef struct {
char items[MAX_STACK][MAX_SYMBOL_LEN];
int top;
} Stack;
// 函数声明
void loadGrammar(FILE *file, SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, char *startSymbol);
void calculateFirstSets(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, NonTerminalInfo firstSets[]);
void calculateFollowSets(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, NonTerminalInfo firstSets[], NonTerminalInfo followSets[], char *startSymbol);
void constructPredictionTable(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, NonTerminalInfo firstSets[], NonTerminalInfo followSets[], int predictionTable[MAX_SYMBOLS][MAX_SYMBOLS]);
void analyzeString(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, char inputTokens[][MAX_SYMBOL_LEN], int inputTokenCount, int predictionTable[MAX_SYMBOLS][MAX_SYMBOLS]);
int getNonTerminalIndex(SymbolCollection *nonTerminals, char *symbol);
int getTerminalIndex(SymbolCollection *terminals, char *symbol);
int hasSymbol(SymbolCollection *set, char *symbol);
void addSymbol(SymbolCollection *set, char *symbol);
int isNonTerminal(SymbolCollection *nonTerminals, char *symbol);
int isTerminal(SymbolCollection *terminals, char *symbol);
void calculateFirstOfSequence(char rhs[][MAX_SYMBOL_LEN], int rhsCount, SymbolCollection *nonTerminals, SymbolCollection *terminals, NonTerminalInfo firstSets[], SymbolCollection *result);
// 栈操作函数
void initializeStack(Stack *s) {
s->top = -1;
}
int isStackEmpty(Stack *s) {
return s->top == -1;
}
void pushToStack(Stack *s, char *item) {
if (s->top < MAX_STACK - 1) {
strcpy(s->items[++(s->top)], item);
}
}
char* popFromStack(Stack *s) {
if (!isStackEmpty(s)) {
return s->items[s->top--];
}
return NULL;
}
// 主程序入口
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: %s <grammar_file> <input_string_file>\n", argv[0]);
return 1;
}
FILE *grammarFile = fopen(argv[1], "r");
if (grammarFile == NULL) {
perror("Failed to open the grammar file");
return 1;
}
FILE *inputFile = fopen(argv[2], "r");
if (inputFile == NULL) {
perror("Failed to open the input string file");
fclose(grammarFile);
return 1;
}
SymbolCollection nonTerminals, terminals;
ProductionCollection productions;
char startSymbol[MAX_SYMBOL_LEN];
char inputString[256];
// 读取文法
loadGrammar(grammarFile, &nonTerminals, &terminals, &productions, startSymbol);
fclose(grammarFile);
// 读取符号串并进行分词
char inputTokens[MAX_SYMBOLS][MAX_SYMBOL_LEN];
int inputTokenCount = 0;
fgets(inputString, sizeof(inputString), inputFile);
fclose(inputFile);
char *token = strtok(inputString, " \n");
while (token != NULL) {
strcpy(inputTokens[inputTokenCount++], token);
token = strtok(NULL, " \n");
}
// 添加 "#" 作为输入结束标记
strcpy(inputTokens[inputTokenCount++], "#");
NonTerminalInfo firstSets[MAX_SYMBOLS], followSets[MAX_SYMBOLS];
int predictionTable[MAX_SYMBOLS][MAX_SYMBOLS];
// 计算First集
calculateFirstSets(&nonTerminals, &terminals, &productions, firstSets);
// 计算Follow集
calculateFollowSets(&nonTerminals, &terminals, &productions, firstSets, followSets, startSymbol);
// 构建预测分析表
constructPredictionTable(&nonTerminals, &terminals, &productions, firstSets, followSets, predictionTable);
// 分析符号串
analyzeString(&nonTerminals, &terminals, &productions, inputTokens, inputTokenCount, predictionTable);
return 0;
}
// 读取文法描述文件
void loadGrammar(FILE *file, SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, char *startSymbol) {
int n;
// 读取非终结符
fscanf(file, "%d", &n);
nonTerminals->count = n;
for (int i = 0; i < n; i++) {
fscanf(file, "%s", nonTerminals->symbols[i]);
}
fgetc(file);
// 读取终结符
fscanf(file, "%d", &n);
terminals->count = n;
for (int i = 0; i < n; i++) {
fscanf(file, "%s", terminals->symbols[i]);
if (strcmp(terminals->symbols[i], "e") == 0) {
strcpy(terminals->symbols[i], EPSILON);
}
}
fgetc(file);
// 读取产生式
fscanf(file, "%d", &n);
productions->count = n;
fgetc(file);
for (int i = 0; i < n; i++) {
char line[256];
fgets(line, sizeof(line), file);
char *token = strtok(line, " \n");
strcpy(productions->rules[i].leftHandSide, token);
// 跳过 '->' 或 '::='
token = strtok(NULL, " \n");
while (token != NULL && (strcmp(token, "->") == 0 || strcmp(token, "::=") == 0)) {
token = strtok(NULL, " \n");
}
productions->rules[i].rightHandSideCount = 0;
while (token != NULL) {
if (strcmp(token, "e") == 0) {
strcpy(token, EPSILON);
}
strcpy(productions->rules[i].rightHandSide[productions->rules[i].rightHandSideCount++], token);
token = strtok(NULL, " \n");
}
}
// 读取起始符号
fscanf(file, "%s", startSymbol);
}
// 查找非终结符索引
int getNonTerminalIndex(SymbolCollection *nonTerminals, char *symbol) {
for (int i = 0; i < nonTerminals->count; i++) {
if (strcmp(nonTerminals->symbols[i], symbol) == 0) {
return i;
}
}
return -1;
}
// 查找终结符索引
int getTerminalIndex(SymbolCollection *terminals, char *symbol) {
for (int i = 0; i < terminals->count; i++) {
if (strcmp(terminals->symbols[i], symbol) == 0) {
return i;
}
}
// 检查输入结束标记 "#"
if (strcmp(symbol, "#") == 0) {
return terminals->count; // 返回终结符数组之外的索引
}
return -1;
}
// 判断集合中是否包含符号
int hasSymbol(SymbolCollection *set, char *symbol) {
for (int i = 0; i < set->count; i++) {
if (strcmp(set->symbols[i], symbol) == 0) {
return 1;
}
}
return 0;
}
// 添加符号到集合
void addSymbol(SymbolCollection *set, char *symbol) {
if (!hasSymbol(set, symbol)) {
strcpy(set->symbols[set->count++], symbol);
}
}
// 判断是否为非终结符
int isNonTerminal(SymbolCollection *nonTerminals, char *symbol) {
return getNonTerminalIndex(nonTerminals, symbol) != -1;
}
// 判断是否为终结符
int isTerminal(SymbolCollection *terminals, char *symbol) {
return getTerminalIndex(terminals, symbol) != -1;
}
// 计算符号串的First集
void calculateFirstOfSequence(char rhs[][MAX_SYMBOL_LEN], int rhsCount, SymbolCollection *nonTerminals, SymbolCollection *terminals, NonTerminalInfo firstSets[], SymbolCollection *result) {
if (rhsCount == 0) {
addSymbol(result, EPSILON);
return;
}
int allCanProduceEpsilon = 1;
for (int i = 0; i < rhsCount; i++) {
char *symbol = rhs[i];
if (hasSymbol(terminals, symbol)) {
addSymbol(result, symbol);
allCanProduceEpsilon = 0;
break;
} else if (strcmp(symbol, EPSILON) == 0) {
addSymbol(result, EPSILON);
} else {
int idx = getNonTerminalIndex(nonTerminals, symbol);
for (int j = 0; j < firstSets[idx].firstSet.count; j++) {
char *firstSym = firstSets[idx].firstSet.symbols[j];
if (strcmp(firstSym, EPSILON) != 0) {
addSymbol(result, firstSym);
}
}
if (!hasSymbol(&firstSets[idx].firstSet, EPSILON)) {
allCanProduceEpsilon = 0;
break;
}
}
}
if (allCanProduceEpsilon) {
addSymbol(result, EPSILON);
}
}
// 计算 First 集
void calculateFirstSets(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, NonTerminalInfo firstSets[]) {
for (int i = 0; i < nonTerminals->count; i++) {
strcpy(firstSets[i].nonTerminal, nonTerminals->symbols[i]);
firstSets[i].firstSet.count = 0;
}
int changed;
do {
changed = 0;
for (int i = 0; i < productions->count; i++) {
ProductionRule *prod = &productions->rules[i];
int lhsIdx = getNonTerminalIndex(nonTerminals, prod->leftHandSide);
SymbolCollection tempFirstSet;
tempFirstSet.count = 0;
calculateFirstOfSequence(prod->rightHandSide, prod->rightHandSideCount, nonTerminals, terminals, firstSets, &tempFirstSet);
for (int j = 0; j < tempFirstSet.count; j++) {
if (!hasSymbol(&firstSets[lhsIdx].firstSet, tempFirstSet.symbols[j])) {
addSymbol(&firstSets[lhsIdx].firstSet, tempFirstSet.symbols[j]);
changed = 1;
}
}
}
} while (changed);
}
// 计算 Follow 集
void calculateFollowSets(SymbolCollection *nonTerminals, SymbolCollection *terminals, ProductionCollection *productions, NonTerminalInfo firstSets[], NonTerminalInfo followSets[], char *startSymbol) {
for (int i = 0; i < nonTerminals->count; i++) {
strcpy(followSets[i].nonTerminal, nonTerminals->symbols[i]);
followSets[i].followSet.count = 0;
if (strcmp(nonTerminals->symbols[i], startSymbol) == 0) {
addSymbol(&followSets[i].followSet, "#");
}
}
int changed;
do {
changed = 0;
for (int i = 0; i < productions->count; i++) {
ProductionRule *prod = &productions->rules[i];
int lhsIdx = getNonTerminalIndex(nonTerminals, prod->leftHandSide);
for (int j = 0; j < prod->rightHandSideCount; j++) {
char *B = prod->rightHandSide[j];
if (isNonTerminal(nonTerminals, B)) {
int B_idx = getNonTerminalIndex(nonTerminals, B);
SymbolCollection betaFirstSet;
betaFirstSet.count = 0;
if (j + 1 < prod->rightHandSideCount) {
calculateFirstOfSequence(prod- j - 1, nonTerminals, terminals, firstSets, &betaFirstSet);
for (int k = 0; k < betaFirstSet.count; k++) {
char *sym = betaFirstSet.symbols[k];
if (strcmp(sym, EPSILON) != 0 && !hasSymbol(&followSets[B_idx].followSet, sym)) {
addSymbol(&followSets[B_idx].followSet, sym);
changed = 1;
}
}
if (hasSymbol(&betaFirstSet, EPSILON)) {
for (int k = 0; k < followSets[lhsIdx].followSet.count; k++) {
char *sym = followSets[lhsIdx].followSet.symbols[k];
if (!hasSymbol(&followSets[B_idx].followSet, sym)) {
addSymbol(&followSets[B_idx].followSet, sym);
changed = 1;
}
}
}
} else {
for (int k = 0; k < followSets[lhsIdx].followSet.count; k++) {
char *sym = followSets[lhsIdx].followSet.symbols[k];
if (!hasSymbol(&followSets[B_idx].followSet, sym)) {
addSymbol(&followSets[B_idx].followSet, sym);
changed = 1;
}
}
}
}
}
}
} while (changed);
阅读全文