void trieInsert(trieNodePointer root, char *token, char *inputFilePath) { trieNodePointer currentNode = root; for (int i = 0; i < strlen(token); i++) { if (currentNode->children[parseChar(token[i])] == NULL) { currentNode->children[parseChar(token[i])] = createNewTrieNode(); currentNode = currentNode->children[parseChar(token[i])]; } else { currentNode = currentNode->children[parseChar(token[i])]; } if (i == (strlen(token) - 1)) { if (currentNode->token == NULL) { currentNode->token = (char *)malloc(strlen(token)+1); strcpy(currentNode->token, token); } if (currentNode->files == NULL) { currentNode->files = createNewFileNode(inputFilePath); } else { bool newNode = true; fileNodePointer tempFiles = currentNode->files; while (tempFiles->next != NULL) { if (strcmp(tempFiles->fileName, inputFilePath) == 0) { tempFiles->count++; newNode = false; break; } tempFiles = tempFiles->next; } if (strcmp(tempFiles->fileName, inputFilePath) == 0) { tempFiles->count++; } else if (newNode == true) { tempFiles->next = createNewFileNode(inputFilePath); } } } } }
int insert(char str[]){ int i, n = strlen(str); TrieNode temp = trieRoot; for(i=0;i<n;i++){ int nextChar = remap(str[i]); if(temp->children[nextChar] == NULL) temp->children[nextChar] = createNewTrieNode(); temp = temp->children[nextChar]; } if(temp->value == UNDEF) temp->value = ++totalVariables; // printf("%s has been inserted in trie at the scope %d and has the index %d.\n", str, currentScope, temp->value); return temp->value; }
int main(){ freopen("lexer_output.txt", "r", stdin); trieRoot = createNewTrieNode(); if(trieRoot == NULL){ perror("Could not create root node!!\n"); return 0; } envTop = NULL; currentScope = totalVariables = 0; addScope(); token t; while(scanf("%d%d", &t.iden, &t.line) != EOF){ fgets(t.value, 1000, stdin); int len = strlen(t.value); t.value[len-1] = '\0'; if(t.value[0] == '-') t.value[0] = '\0'; t.line++; lexemeStream[stream_size++] = t; } // int zz; // for(zz=0;zz<stream_size;zz++) // printf("%d ", lexemeStream[zz].iden); printf("\n"); int i, n = stream_size, lastLineOfDeclaration = -1, lastDataTypeOfDeclaration = -1; int lastDataTypeOfAssignment = -1, lastLineOfAssignment = -1; funcName[0] = '!'; funcName[1] = '\0'; int insideMain = 0, diff = 0; funcParameterCount = 0; for(i=0;i<n;i++){ if(lexemeStream[i].iden == MAIN) insideMain = 1; if(i == 2){ if(lexemeStream[i].iden != MAIN){ assert(lexemeStream[i].iden == FUNC); strcpy(funcName, lexemeStream[i+1].value); } i++; continue; } //check for recursive function calls if(lexemeStream[i].iden == FUNC && !insideMain){ printf("Semantic error: Recursive function calls not allowed.\n"); continue; } if(lexemeStream[i].iden == LSQ){ diff++; continue; } if(lexemeStream[i].iden == RSQ){ diff--; continue; } //store function parameter list if(isDataType(lexemeStream[i].iden) && diff > 0 && !insideMain){ funcParameterType[funcParameterCount++] = lexemeStream[i].iden; } //for function calls inside main, check whether correct function name is used //then check for correct number and types of parameters if(insideMain && i > 0 && lexemeStream[i].iden == IDEN && lexemeStream[i-1].iden == FUNC){ if(strcmp(funcName, lexemeStream[i].value) > 0) printf("Function named %s in line %d not declared.\n", lexemeStream[i].value, lexemeStream[i].line); int j, argumentCount = 0, wrongType = 0; for(j=i+1;j < stream_size && lexemeStream[j].iden != RSQ;j++){ if(lexemeStream[j].iden != IDEN) continue; if(argumentCount < funcParameterCount && getDataType(lexemeStream[j]) != funcParameterType[argumentCount]) wrongType = lexemeStream[j].line; argumentCount++; } if(argumentCount != funcParameterCount) printf("Incorrect number of function arguments in line %d.\n", lexemeStream[j].line); if(wrongType > 0) printf("Type mismatch in function parameters in line %d.\n", wrongType); i = j; continue; } if(lexemeStream[i].iden == LAD){ addScope(); continue; } if(lexemeStream[i].iden == RAD){ deleteScope(); continue; } if(isDataType(lexemeStream[i].iden)){ lastLineOfDeclaration = lexemeStream[i].line; lastDataTypeOfDeclaration = lexemeStream[i].iden; // printf("setting lastlineOfDeclaration = %d because of %d.\n", lastLineOfDeclaration, lexemeStream[i].iden); continue; } if(lexemeStream[i].iden == ASSIGN){ //line number of assignment operator lastLineOfAssignment = lexemeStream[i].line; continue; } if(lexemeStream[i].iden == IDEN){ insert(lexemeStream[i].value); //check if variable is being declared or referenced if(lastLineOfDeclaration == lexemeStream[i].line){ //declared declareVariable(lexemeStream[i], lastDataTypeOfDeclaration); continue; } //referenced referenceVariable(lexemeStream[i]); if(lexemeStream[i].line != lastLineOfAssignment){ lastDataTypeOfAssignment = getDataType(lexemeStream[i]); continue; } if(lexemeStream[i].line == lastLineOfAssignment){ int dataType = getDataType(lexemeStream[i]); if(dataType != lastDataTypeOfAssignment){ printf("Semantic error in line %d: Type mismatch between LHS and RHS in line %d.\n", lexemeStream[i].line, lastLineOfAssignment); } continue; } } } // int c = 0, cc = 0; // EnvStackNode temp = envTop; // while(temp != NULL){ // c++; // EnvListNode ev = temp->ev; // while(ev != NULL){ // cc++; // ev = ev->next; // } // temp = temp->next; // } // printf("Total active scopes : %d and active variables = %d.\n", c, cc); // printf("\ncheck variable stack of size = %d :\n", z); // for(int i=0;i<z;i++){ // int idx = vvv[i]; // if(variableStack[idx] == NULL){ // printf("empty stack at idx = %d\n", idx); // continue; // } // printf("idx = %d has the value = %s\n", idx, variableStack[idx]->node.name); // } return 0; }