Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Mark Klingberg
- Summer 2013
- This program is a PL/0 compiler. PL/0 is a made up language similar to Pascal.
- This compiler takes a file containing PL/0 language as input, converts it into tokens, and
- then runs it on a PL/0 machine. The PL/0 machine is a simple stack machine.
- View the read me file for further details.
- */
- ////readMe.txt
- //This program is a tiny PL/0 compiler. It takes PL/0 code as input and if the code is
- //syntactically correct it will display a message saying so as well any read or write commands
- //to the terminal. It prints the tokens to a file named lexerOutput.txt. It prints
- //the intermediate code to a file named parcerOutput.txt. It prints the virtual machine execution
- //trace to a file named output.txt. If you wish to print the any of the files above you can use
- //-l, -a, and -v to print them out respectively. Follow the instructions below for compile and run the
- //program on Eustis:
- //
- // 1. compile the program by typing: gcc main.c -o name
- // 2. run the program by typing: ./name name_of_input_file
- // 3. If you wish to see any of the output files run the program by typing:
- // ./name name_of_input_file -l -a -v
- //
- //The order you type in the compiler directives is the order the files will print in. The name of the
- //input file must always the second entry in the list.
- ////test0.txt
- //var x,w;
- //begin
- // x:=4;
- //if 5 > x then
- // x := x + 1
- //else
- // x := x + 2;
- //end.
- ////test1.txt
- //const n = 13;
- //var i,h;
- //procedure sub;
- // const k = 7;
- // var j,h;
- // begin
- // j:=n;
- // i:=1;
- // h:=k;
- // end;
- // begin
- // i:=3; h:=0;
- // call sub;
- // end.
- ////test2.txt
- //const m = 7, n = 85;
- //var i,x,y,z,q,r;
- //procedure mult;
- // var a, b;
- // begin
- // a := x; b := y; z := 0;
- // while b > 0 do
- // begin
- // if odd x then z := z+a;
- // a := 2*a;
- // b := b/2;
- // end
- // end;
- //
- //begin
- // x := m;
- // y := n;
- // call mult;
- //end.
- ////test3.txt
- //var x,result;
- //procedure fact;
- // begin
- // if x > 1 then
- // begin
- // result := result * x;
- // x := x - 1;
- // call fact;
- // end;
- // end;
- //
- //begin
- // result := 1;
- // x := 10;
- // call fact;
- // write result;
- //end.
- ////error1.txt
- //var x;
- //begin
- // x := 5;
- //end
- ////error2.txt
- //const = 1;
- //var x;
- //begin
- // x = 5;
- //end
- ////error3.txt
- //const z 1;
- //var x;
- //begin
- // x = 5;
- //end
- ////error4.txt
- //const z =;
- //var x;
- //begin
- // x = 5;
- //end
- ////error5.txt
- //const z = 3
- //var x;
- //begin
- // x = 5;
- //end
- ////error6.txt
- //begin
- // x = 5;
- //end
- ////error7.txt
- //const x = 1;
- //begin
- // x = 5;
- //end
- ////error8.txt
- //var y;
- //begin
- // y 5;
- //end
- //error9.txt
- //const n = 13;
- //var i,h;
- //procedure sub;
- // const k = 7;
- // var j,h;
- // begin
- // j:=n;
- // i:=1;
- // h:=k;
- // end;
- // begin
- // i:=3; h:=0;
- // call ;
- // end.
- ////error10.txt
- //const n = 13;
- //var i,h;
- //procedure sub;
- // const k = 7;
- // var j,h;
- // begin
- // j:=n;
- // i:=1;
- // h:=k;
- // end;
- // begin
- // i:=3; h:=0;
- // call h;
- // end.
- ////error11.txt
- //var x,w;
- //begin
- // x:=4;
- //if 5 > x
- // x := x + 1
- //else
- // x := x + 2;
- //end.
- ////error12.txt
- //const m = 7, n = 85;
- //var i,x,y,z,q,r;
- //procedure mult;
- // var a, b;
- // begin
- // a := x; b := y; z := 0;
- // while b > 0
- // begin
- // if odd x then z := z+a;
- // a := 2*a;
- // b := b/2;
- // end
- // end;
- //
- //begin
- // x := m;
- // y := n;
- // call mult;
- //end.
- ////error13.txt
- //var x,result;
- //procedure fact;
- // begin
- // if x > 1 then
- // begin
- // result := result * x;
- // x := x - 1;
- // call fact;
- // end;
- // end;
- //
- //begin
- // result := 1;
- // read x;
- // call fact;
- // write fact;
- //end.
- ////error14.txt
- //var x,w;
- //begin
- // x:=4;
- //if 5 := x then
- // x := x + 1
- //else
- // x := x + 2;
- //end.
- ////error15.txt
- //var x,w;
- //begin
- // x:=4;
- //if 5 > x then
- // x := (x + 1 * 2
- //else
- // x := x + 2;
- //end.
- ////error16.txt
- //var x,w;
- //begin
- // x:= * + 1;
- //end.
- ////error17.txt
- //var x,result;
- //procedure fact;
- // begin
- // if x > 1 then
- // begin
- // result := result * x;
- // x := x - 1;
- // call fact;
- // end;
- // end;
- //
- //begin
- // result := 1;
- // read ;
- // call fact;
- // write result;
- //end.
- ////error18.txt
- //var x;
- //begin
- // x := 5;
- //.
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #define MAX_IDENTIFER_LENGTH 11
- #define MAX_NUMBER_LENGTH 5
- #define MAX_SYMBOL_TABLE_SIZE 1000
- #define MAX_CODE_TABLE_SIZE 1000
- #define CONSTANT 1
- #define VARIABLE 2
- #define PROCEDURE 3
- #define MAX_NAME_SIZE 11
- #define TRUE 1
- #define FALSE 0
- #define RESERVED_STACK_SIZE 4
- #define OP_LENGTH 3
- #define MAX_STACK_HEIGHT 2000
- #define MAX_CODE_LENGTH 500
- #define MAX_LEXI_LEVELS 3
- typedef enum{
- LIT = 1,
- OPR,
- LOD,
- STO,
- CAL,
- INC,
- JMP,
- JPC,
- SIOw,
- SIOr
- } ISA;
- typedef enum{
- RET = 0,
- NEG,
- ADD,
- SUB,
- MUL,
- DIV,
- ODD,
- MOD,
- EQL,
- NEQ,
- LSS,
- LEQ,
- GTR,
- GEQ
- } OPERATIONS;
- typedef enum{
- nulsym = 1,
- identsym,
- numbersym,
- plussym,
- minussym,
- multsym,
- slashsym,
- oddsym,
- eqlsym,
- neqsym,
- lessym,
- leqsym,
- gtrsym,
- geqsym,
- lparentsym,
- rparentsym,
- commasym,
- semicolonsym,
- periodsym,
- becomessym,
- beginsym,
- endsym,
- ifsym,
- thensym,
- whilesym,
- dosym,
- callsym,
- constsym,
- varsym,
- procsym,
- writesym,
- readsym,
- elsesym
- } token_type;
- typedef enum {
- ERR_PER_EXP,
- ERR_IDENT_MISSING,
- ERR_EQUAL_MISSING,
- ERR_NUMBER_MISSING,
- ERR_SEMI_COMMA_MISSING,
- ERR_UNDECL_IDENT,
- ERR_ASSIGN_NOT_ALLOWED,
- ERR_ASSIGN_EXPECT,
- ERR_IDENT_EXPECTED,
- ERR_BAD_CALL,
- ERR_THEN_EXPECTED,
- ERR_DO_EXPECTED,
- ERR_EXPRESS_ERROR,
- ERR_REL_EXPECTED,
- ERR_PAREN_EXPECTED,
- ERR_BAD_SYMBOL,
- ERR_ID_EXPECT_AFTER_READWRITE,
- ERR_END_EXPECTED,
- ERR_REPEAT
- } error_type;
- typedef struct lexemeList{
- int token;
- int number; //use if token == 3;
- char name[100]; //use if token == 2;
- struct lexemeList* next;
- }lexemeList;
- typedef struct node{
- char procName[MAX_NAME_SIZE + 1];
- struct node* next;
- } node;
- typedef struct{
- int kind; // const = 1, var = 2, proc = 3
- char name[MAX_NAME_SIZE + 1]; // name up to 11 chars
- int val; // number (ASCII value)
- int level; // L level
- int addr; // M address
- node* head; // Used to check to see if a variable/constant can be accessed
- } symbol;
- typedef struct{
- int op;
- int l;
- int m;
- }code;
- typedef struct instruction{
- int line; //line number
- int op; //opcode
- int l; //L
- int m; //M
- }instruction;
- int lexerMain(char** argv);
- int parcerMain();
- int virtualMachineMain();
- void runLexicalAnalyzer(char** argv);
- void getIDorRWtoken(FILE* ifp);
- int checkForReservedWord(char* word);
- void getNumber(FILE* ifp);
- void getSymbol(FILE* ifp);
- void printLexemeList();
- void initialTokenPrint();
- void initialSymbolPrint();
- void getsym(FILE* ifp);
- void getname(FILE* ifp);
- void getvalue(FILE* ifp);
- void enter(int offset);
- void error(int e);
- void gen(int OP, int L, int M);
- void PROGRAM(FILE* ifp);
- void BLOCK(FILE* ifp);
- void STATEMENT(FILE* ifp);
- void CONDITION(FILE* ifp);
- void EXPRESSION(FILE* ifp);
- void addFirstNode();
- void printParcerOutput();
- void printOutput();
- void initializeTables();
- void printCodeTable();
- int checkVariableAccess(int i);
- int RELATION(int token);
- void TERM();
- void FACTOR();
- void storeToMemory(FILE* ifp);
- void printAssembly(FILE* ofp);
- void runVM(FILE* ofp);
- void fetch();
- void execute(FILE* ofp);
- void initializeVM(FILE* ofp);
- void initialPrint(FILE* ofp);
- void ALUop();
- int base(int l);
- void print(FILE* ofp);
- void printStack(FILE* ofp);
- void checkRepeat();
- void testPrint();
- node* generateLinkedList();
- lexemeList* head = NULL;
- lexemeList* tail = NULL;
- lexemeList* tailTrailer = NULL;
- char c; //current charactering being read
- node* Head;
- symbol symbol_table[MAX_SYMBOL_TABLE_SIZE];
- code code_table[MAX_CODE_TABLE_SIZE];
- int TOKEN;
- int Kind;
- char Name[MAX_NAME_SIZE + 1];
- int Value;
- int Level;
- int TableIndex;
- int CodeIndex;
- char CurrentProcedure[MAX_NAME_SIZE + 1];
- int Stack[MAX_STACK_HEIGHT];
- int SP;
- int BP;
- int PC;
- instruction IR;
- int memory[MAX_CODE_LENGTH][4]; //[Line, IR.op, IR.l, IR.m]
- int totalLinesOfCode;
- //used for printing, stores the length of each activation record
- int ARLengthStroage[1000];
- int ARLengthStroagePointer;
- //used to exit the fetch execute cycle
- int numOfCal;//number of function calls
- int numOfOpr;//number of returns
- int main(int argc, char** argv){
- int i;
- lexerMain(argv);
- parcerMain();
- // testPrint();
- virtualMachineMain();
- for(i=1; i<argc; i++){
- if(strcmp(argv[i], "-l") == 0){
- //print the list of lexems (lexer output)
- initialTokenPrint();
- initialSymbolPrint();
- }
- else if(strcmp(argv[i], "-a") == 0){
- //print the generated assembly code (parcer output)
- printParcerOutput();
- }
- else if(strcmp(argv[i], "-v") == 0){
- //print the VM output ot the console
- printOutput();
- }
- }
- return 0;
- }
- int lexerMain(char** argv){
- runLexicalAnalyzer(argv);
- printLexemeList();
- return 0;
- }
- void runLexicalAnalyzer(char** argv){
- FILE* ifp;
- ifp = fopen(argv[1], "r");
- if(ifp == NULL){
- printf("failed to open input file.\n");
- exit(-1);
- }
- tail = malloc(sizeof(lexemeList));
- head = tail;
- c = fgetc(ifp);
- while(c != EOF){
- if(isalpha(c) != 0){
- //c is part of an identifier or reserved word
- getIDorRWtoken(ifp);
- }
- else if(isdigit(c) != 0){
- //c is part of a number, or bad identifier
- getNumber(ifp);
- }
- else{
- //c is a special symbol, invisible character, comment, or error
- getSymbol(ifp);
- }
- }
- tailTrailer->next = NULL;
- free(tailTrailer->next);
- }
- void getIDorRWtoken(FILE* ifp){
- int numberFoundFlag=0, counter=0, RWflag=0, i;
- char buffer[100];
- for(i=0; i<100; i++)
- buffer[i] = '\0';
- buffer[counter] = c;
- c = fgetc(ifp);
- while((isalpha(c) != 0) || (isdigit(c) != 0)){
- if (isdigit(c) != 0)
- numberFoundFlag = 1;
- counter++;
- buffer[counter] = c;
- c = fgetc(ifp);
- }
- if(numberFoundFlag == 0){
- //no nubers in word, check reserved word list.
- RWflag = checkForReservedWord(buffer);
- }
- if(RWflag == 0){
- //identifier found.
- tail->token = identsym;
- strncpy(tail->name, buffer, MAX_IDENTIFER_LENGTH);
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- if(counter>=MAX_IDENTIFER_LENGTH)
- printf("Warning: Identifier length too long.\n");
- }
- }
- int checkForReservedWord(char* buffer){
- //if (flag == 1) reserved word found, else must be an identifier.
- int flag = 0;
- if(strncmp(buffer, "const", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = constsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "var", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = varsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "procedure", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = procsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "call", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = callsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "begin", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = beginsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "end", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = endsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "if", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = ifsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "then", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = thensym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "else", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = elsesym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "while", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = whilesym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "do", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = dosym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "read", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = readsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "write", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = writesym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- else if(strncmp(buffer, "odd", MAX_IDENTIFER_LENGTH) == 0){
- tail->token = oddsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- flag = 1;
- }
- return flag;
- }
- void getNumber(FILE* ifp){
- int counter = 0, tempNumber, i, badIdentifierFlag = 0;
- char buffer[100];
- for(i=0; i<100; i++)
- buffer[i] = '\0';
- buffer[counter] = c;
- c = fgetc(ifp);
- while(isdigit(c) != 0){
- counter++;
- buffer[counter] = c;
- c = fgetc(ifp);
- if(isalpha(c) != 0){
- badIdentifierFlag = 1;
- }
- }
- if(isalpha(c) != 0){
- badIdentifierFlag = 1;
- }
- if(badIdentifierFlag == 0){
- tempNumber = atoi(buffer);
- tail->token = numbersym;
- tail->number = tempNumber;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- if(counter>=MAX_NUMBER_LENGTH)
- printf("Warning: Number length too long.\n");
- }
- else{
- while((isalpha(c) != 0) || (isdigit(c) != 0)){
- counter++;
- buffer[counter] = c;
- c = fgetc(ifp);
- }
- tail->token = identsym;
- strncpy(tail->name, buffer, MAX_IDENTIFER_LENGTH);
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- }
- }
- void getSymbol(FILE* ifp){
- int commentFlag = 0;
- if(c == '+'){
- tail->token = plussym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '-'){
- tail->token = minussym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '*'){
- tail->token = multsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '/'){
- c = fgetc(ifp);
- //comment check
- if(c == '*'){
- while(commentFlag == 0){
- c = fgetc(ifp);
- if(c == '*'){
- c = fgetc(ifp);
- if(c == '/')
- commentFlag = 1;
- }
- }
- c = fgetc(ifp);
- }
- else{
- //its a divides symbol
- tail->token = slashsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- }
- }
- else if(c == '('){
- tail->token = lparentsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == ')'){
- tail->token = rparentsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '='){
- tail->token = eqlsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == ','){
- tail->token = commasym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '.'){
- tail->token = periodsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '<'){
- //could be <, <=, or <>.
- c = fgetc(ifp);
- if(c == '='){
- tail->token = leqsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == '>'){
- tail->token = neqsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else{
- tail->token = lessym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- }
- }
- else if(c == '>'){
- //could be > or >=.
- c = fgetc(ifp);
- if(c == '='){
- tail->token = geqsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else{
- tail->token = gtrsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- }
- }
- else if(c == ';'){
- tail->token = semicolonsym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- else if(c == ':'){
- c = fgetc(ifp);
- if(c == '='){
- tail->token = becomessym;
- tail->next = malloc(sizeof(lexemeList));
- tailTrailer = tail;
- tail = tail->next;
- c = fgetc(ifp);
- }
- // else
- // printf("Error: Expected '=' after ':'.\n");
- }
- else if(c == ' '){
- //space. skip and move on.
- c = fgetc(ifp);
- }
- else if(c == '\t'){
- //tab. skip and move on.
- c = fgetc(ifp);
- }
- else if((c == '\n') | (c == 0xd)){
- //newline. skip and move on.
- c = fgetc(ifp);
- }
- else{
- //error, unknown symbol.
- // printf("0x%x \t Error: Unknown symbol\n", c);
- c = fgetc(ifp);
- }
- }
- void printLexemeList(){
- FILE* ofp;
- ofp = fopen("lexerOutput.txt", "w");
- if (ofp == NULL){
- printf("failed to open lexerOutput.txt.\n");
- exit(-1);
- }
- while(head != NULL){
- fprintf(ofp, "%d ", head->token);
- if(head->token == 2){
- fprintf(ofp, "%s ", head->name);
- }
- else if(head->token == 3){
- fprintf(ofp, "%d ", head->number);
- }
- head = head->next;
- }
- printf("\n");
- fclose(ofp);
- }
- int parcerMain(){
- initializeTables();
- FILE* ifp;
- ifp = fopen("lexerOutput.txt", "r");
- if(ifp == NULL){
- printf("Failed to open lexerOutput.txt #2.\n");
- exit(0);
- }
- PROGRAM(ifp);
- printCodeTable();
- printf("Program is syntactically correct.\n\n");
- fclose(ifp);
- return 0;
- }
- void initialTokenPrint(){
- char temp;
- FILE* ifp;
- ifp = fopen("lexerOutput.txt", "r");
- if(ifp == NULL){
- printf("failed to open lexerOutput.txt #3.\n");
- exit(-1);
- }
- while((temp = fgetc(ifp))!= EOF){
- printf("%c", temp);
- }
- printf("\n\n");
- fclose(ifp);
- }
- void initialSymbolPrint(){
- int token;
- int num;
- char buffer[MAX_NAME_SIZE +1];
- FILE* ifp;
- ifp = fopen("lexerOutput.txt", "r");
- if(ifp == NULL){
- printf("failed to open lexerOutput.txt #4.\n");
- exit(-1);
- }
- while(fscanf(ifp, "%d", &token) != EOF){
- switch(token){
- case 1: printf("nulsym ");
- break;
- case 2: printf("identsym ");
- fscanf(ifp, "%s", buffer);
- printf("%s ", buffer);
- break;
- case 3: printf("numbersym ");
- fscanf(ifp, "%d", &num);
- printf("%d ", num);
- break;
- case 4: printf("plussym ");
- break;
- case 5: printf("minussym ");
- break;
- case 6: printf("multsym ");
- break;
- case 7: printf("slashsym ");
- break;
- case 8: printf("oddsym ");
- break;
- case 9: printf("eqlsym ");
- break;
- case 10: printf("neqsym ");
- break;
- case 11: printf("lessym ");
- break;
- case 12: printf("leqsym ");
- break;
- case 13: printf("gtrsym ");
- break;
- case 14: printf("geqsym ");
- break;
- case 15: printf("lparentsym ");
- break;
- case 16: printf("rparentsym ");
- break;
- case 17: printf("commasym ");
- break;
- case 18: printf("semicolonsym ");
- break;
- case 19: printf("periodsym ");
- break;
- case 20: printf("becomessym ");
- break;
- case 21: printf("beginsym ");
- break;
- case 22: printf("endsym ");
- break;
- case 23: printf("ifsym ");
- break;
- case 24: printf("thensym ");
- break;
- case 25: printf("whilesym ");
- break;
- case 26: printf("dosym ");
- break;
- case 27: printf("callsym ");
- break;
- case 28: printf("constsym ");
- break;
- case 29: printf("varsym ");
- break;
- case 30: printf("procsym ");
- break;
- case 31: printf("writesym ");
- break;
- case 32: printf("readsym ");
- break;
- case 33: printf("elsesym ");
- break;
- }
- }
- printf("\n\n");
- fclose(ifp);
- }
- void initializeTables(){
- int i, j;
- Head = NULL;
- addFirstNode();
- strcpy(Head->procName, "Main");
- for(i=0; i<MAX_SYMBOL_TABLE_SIZE; i++){
- symbol_table[i].kind = 0;
- for(j=0; j<MAX_NAME_SIZE+1; j++)
- symbol_table[i].name[j] = '\0';
- symbol_table[i].val = 0;
- symbol_table[i].level = 0;
- symbol_table[i].addr = 0;
- symbol_table[i].head = NULL;
- }
- for(i=0; i< MAX_CODE_TABLE_SIZE; i++){
- code_table[i].op = 0;
- code_table[i].l = 0;
- code_table[i].m = 0;
- }
- TOKEN = 0;
- Kind = 0;
- for(i=0; i<MAX_NAME_SIZE+1; i++){
- Name[i] = '\0';
- }
- Value = 0;
- Level = 0;
- TableIndex = 0;
- CodeIndex = 0;
- strcpy(CurrentProcedure, "Main");
- }
- void getsym(FILE* ifp){
- fscanf(ifp, "%d", &TOKEN);
- }
- void getname(FILE* ifp){
- fscanf(ifp, "%s", Name);
- }
- void getvalue(FILE* ifp){
- fscanf(ifp, "%d", &Value);
- }
- void enter(int offset){
- int i;
- symbol_table[TableIndex].kind = Kind;
- if(Kind == CONSTANT){
- strcpy(symbol_table[TableIndex].name, Name);
- symbol_table[TableIndex].val = Value;
- symbol_table[TableIndex].head = Head;
- }
- else if(Kind == VARIABLE){
- strcpy(symbol_table[TableIndex].name, Name);
- symbol_table[TableIndex].level = Level;
- symbol_table[TableIndex].addr = offset;
- symbol_table[TableIndex].head = generateLinkedList();
- }
- else if(Kind == PROCEDURE){
- strcpy(symbol_table[TableIndex].name, Name);
- symbol_table[TableIndex].level = Level;
- symbol_table[TableIndex].addr = CodeIndex;
- }
- for(i=0; i<MAX_NAME_SIZE+1; i++){
- Name[i] = '\0';
- }
- TableIndex++;
- }
- void error(int e){
- switch(e){
- case ERR_PER_EXP:
- printf("Period expected.\n");
- break;
- case ERR_IDENT_MISSING:
- printf("const, var, procedure must be followed by identifier.\n");
- break;
- case ERR_EQUAL_MISSING:
- printf("Identifier must be followed by =.\n");
- break;
- case ERR_NUMBER_MISSING:
- printf("= must be followed by a number.\n");
- break;
- case ERR_SEMI_COMMA_MISSING:
- printf("Semicolon or comma missing.\n");
- break;
- case ERR_UNDECL_IDENT:
- printf("Undeclared identifier.\n");
- break;
- case ERR_ASSIGN_NOT_ALLOWED:
- printf("Assignment to constant or procedure is not allowed.\n");
- break;
- case ERR_ASSIGN_EXPECT:
- printf("Assignment operator expected.\n");
- break;
- case ERR_IDENT_EXPECTED:
- printf("Call must be followed by an identifier.\n");
- break;
- case ERR_BAD_CALL:
- printf("Call of a constant or variable is meaningless.\n");
- break;
- case ERR_THEN_EXPECTED:
- printf("then expected.\n");
- break;
- case ERR_DO_EXPECTED:
- printf("Do expected.\n");
- break;
- case ERR_EXPRESS_ERROR:
- printf("Expression must not contain a procedure identifier.\n");
- break;
- case ERR_REL_EXPECTED:
- printf("Relational operator expected.\n");
- break;
- case ERR_PAREN_EXPECTED:
- printf("Right parenthesis missing.\n");
- break;
- case ERR_BAD_SYMBOL:
- printf("The preceding factor cannot begin with this symbol.\n");
- break;
- case ERR_ID_EXPECT_AFTER_READWRITE:
- printf("Identifier expected after using read or write.\n");
- break;
- case ERR_END_EXPECTED:
- printf("End expected.\n");
- break;
- case ERR_REPEAT:
- printf("Variable name has already been used within the same level or procedure name has already been used.\n");
- break;
- default:
- printf("Unknown Error.\n");
- break;
- }
- exit(1);
- }
- void gen(int OP, int L, int M){
- code_table[CodeIndex].op = OP;
- code_table[CodeIndex].l = L;
- code_table[CodeIndex].m = M;
- CodeIndex++;
- }
- void addFirstNode(){
- int i;
- node* temp = Head;
- Head = malloc(sizeof(node));
- for(i=0; i<MAX_NAME_SIZE+1; i++)
- Head->procName[i] = '\0';
- Head->next = temp;
- }
- void deleteFirstNode(){
- Head = Head->next;
- }
- int position(){
- int i;
- for(i=MAX_SYMBOL_TABLE_SIZE-1; i>=0; i--){
- if(strcmp(Name, symbol_table[i].name)==0){
- if(symbol_table[i].kind == VARIABLE){
- if(Level >= symbol_table[i].level)
- if(checkVariableAccess(i) == TRUE)
- return i;
- }
- else{
- return i;
- }
- }
- }
- return i;
- }
- int checkVariableAccess(int i){
- int incrementCurrHead = Level - symbol_table[i].level;
- node* tempSymTabHead = symbol_table[i].head;
- node* tempCurrHead = Head;
- for( ; incrementCurrHead>0; incrementCurrHead--){
- tempCurrHead = tempCurrHead->next;
- }
- if(strcmp(tempSymTabHead->procName, tempCurrHead->procName)==0)
- return TRUE;
- else
- return FALSE;
- }
- void PROGRAM(FILE* ifp){
- getsym(ifp);
- //Initial Jump
- gen(JMP, 0, 0); //Place holder change M later
- BLOCK(ifp);
- if (TOKEN != periodsym)
- error(ERR_PER_EXP);
- //Final return
- gen(OPR, 0, RET);
- }
- void BLOCK(FILE* ifp){
- int i, offset;
- offset = RESERVED_STACK_SIZE;
- if (TOKEN == constsym){
- Kind = CONSTANT;
- do{
- getsym(ifp);
- if (TOKEN != identsym)
- error(ERR_IDENT_MISSING);
- getname(ifp);
- getsym(ifp);
- if (TOKEN != eqlsym)
- error(ERR_EQUAL_MISSING);
- getsym(ifp);
- if (TOKEN != numbersym)
- error(ERR_NUMBER_MISSING);
- getvalue(ifp);
- checkRepeat();
- enter(offset);
- getsym(ifp);
- }while(TOKEN == commasym);
- if(TOKEN != semicolonsym)
- error(ERR_SEMI_COMMA_MISSING);
- getsym(ifp);
- }
- if (TOKEN == varsym){
- Kind = VARIABLE;
- do{
- getsym(ifp);
- if (TOKEN != identsym)
- error(ERR_IDENT_MISSING);
- getname(ifp);
- checkRepeat();
- enter(offset);
- offset++;
- getsym(ifp);
- }while(TOKEN == commasym);
- if (TOKEN != semicolonsym)
- error(ERR_SEMI_COMMA_MISSING);
- getsym(ifp);
- }
- while (TOKEN == procsym){
- Kind = PROCEDURE;
- getsym(ifp);
- if (TOKEN != identsym)
- error(ERR_IDENT_MISSING);
- getname(ifp);
- for(i=0; i<MAX_NAME_SIZE+1; i++){
- CurrentProcedure[i] = '\0';
- }
- addFirstNode();
- strcpy(CurrentProcedure, Name);
- for(i=0; i<MAX_NAME_SIZE+1; i++){
- Head->procName[i] = '\0';
- }
- strcpy(Head->procName, Name);
- getsym(ifp);
- if (TOKEN != semicolonsym)
- error(ERR_SEMI_COMMA_MISSING);
- checkRepeat();
- enter(offset);
- //Jumps
- gen(JMP, 0, 0); //Place holder change M later.
- getsym(ifp);
- Level++;
- BLOCK(ifp);
- Level--;
- deleteFirstNode();
- if (TOKEN != semicolonsym)
- error(ERR_SEMI_COMMA_MISSING);
- getsym(ifp);
- //Return
- gen(OPR, 0, RET);
- }
- //Change M in jumps
- for(i=CodeIndex; i>=0; i--){
- if((code_table[i].op == JMP)&&(code_table[i].m==0)){
- code_table[i].m = CodeIndex;
- break;
- }
- }
- //Increments
- gen(INC, 0, offset); //Offset == Number of Variables + 4.
- STATEMENT(ifp);
- }
- void STATEMENT(FILE* ifp){
- int i, cx;
- if (TOKEN == identsym){
- //Stores
- getname(ifp);
- i = position();
- if (i==-1)
- error(ERR_UNDECL_IDENT);
- else if (symbol_table[i].kind!=VARIABLE) {
- error(ERR_ASSIGN_NOT_ALLOWED);
- i=-1;
- }
- getsym(ifp);
- if (TOKEN != becomessym)
- error(ERR_ASSIGN_EXPECT);
- getsym(ifp);
- EXPRESSION(ifp);
- //Stores
- if (i != -1)
- gen(STO, Level-symbol_table[i].level, symbol_table[i].addr);
- }
- else if (TOKEN == callsym){
- getsym(ifp);
- if (TOKEN != identsym)
- error(ERR_IDENT_EXPECTED);
- //Calls
- getname(ifp);
- i=position();
- if (i==-1)
- error(ERR_UNDECL_IDENT);
- else if (symbol_table[i].kind == PROCEDURE)
- gen(CAL, Level-symbol_table[i].level, symbol_table[i].addr);
- else
- error(ERR_BAD_CALL);
- getsym(ifp);
- }
- else if (TOKEN == beginsym){
- getsym(ifp);
- STATEMENT(ifp);
- while(TOKEN == semicolonsym){
- getsym(ifp);
- STATEMENT(ifp);
- }
- if (TOKEN != endsym)
- error(ERR_END_EXPECTED);
- getsym(ifp);
- }
- else if (TOKEN == ifsym){
- getsym(ifp);
- CONDITION(ifp);
- gen(JPC, 0, 0); //Place holder instruction. Change M later.
- if (TOKEN != thensym)
- error(ERR_THEN_EXPECTED);
- getsym(ifp);
- STATEMENT(ifp);
- gen(JMP, 0, 0); //Place holder instruction. Change M later.
- // change M for JPC.
- for(i=CodeIndex; i>=0; i--){
- if((code_table[i].op == JPC)&&(code_table[i].m==0)){
- code_table[i].m = CodeIndex;
- break;
- }
- }
- if (TOKEN == elsesym){
- getsym(ifp);
- STATEMENT(ifp);
- }
- for(i=CodeIndex; i>=0; i--){
- if((code_table[i].op == JMP)&&(code_table[i].m==0)){
- code_table[i].m = CodeIndex;
- break;
- }
- }
- }
- else if (TOKEN == whilesym){
- getsym(ifp);
- cx = CodeIndex;
- CONDITION(ifp);
- gen(JPC, 0, 0); //Place holder instruction. Change M later.
- if (TOKEN != dosym)
- error(ERR_DO_EXPECTED);
- getsym(ifp);
- STATEMENT(ifp);
- gen(JMP, 0, cx); //Place holder instruction. Change M later.
- for(i=CodeIndex; i>=0; i--){
- if((code_table[i].op == JPC)&&(code_table[i].m==0)){
- code_table[i].m = CodeIndex;
- break;
- }
- }
- }
- else if (TOKEN == writesym){
- getsym(ifp);
- if (TOKEN != identsym)
- error(ERR_ID_EXPECT_AFTER_READWRITE);
- getname(ifp);
- i = position();
- if (i==-1)
- error(ERR_UNDECL_IDENT);
- if (symbol_table[i].kind==CONSTANT)
- gen(LIT, 0, symbol_table[i].val);
- else if (symbol_table[i].kind==VARIABLE)
- gen(LOD, Level-symbol_table[i].level, symbol_table[i].addr);
- else
- error(ERR_EXPRESS_ERROR);
- gen(SIOw, 0, 1);
- getsym(ifp);
- }
- else if (TOKEN == readsym){
- gen(SIOr, 0, 2);
- getsym(ifp);
- if(TOKEN != identsym)
- error(ERR_ID_EXPECT_AFTER_READWRITE);
- getname(ifp);
- i = position();
- if (i==-1)
- error(ERR_UNDECL_IDENT);
- else if (symbol_table[i].kind!=VARIABLE) {
- error(ERR_ASSIGN_NOT_ALLOWED);
- i=-1;
- }
- //Stores
- if (i != -1)
- gen(STO, Level-symbol_table[i].level, symbol_table[i].addr);
- getsym(ifp);
- }
- else {
- //empty set
- }
- }
- void CONDITION(FILE* ifp){
- int m;
- if (TOKEN == oddsym){
- getsym(ifp);
- EXPRESSION(ifp);
- gen(OPR, 0, ODD);
- }
- else{
- EXPRESSION(ifp);
- m = (RELATION(TOKEN));
- if(m == FALSE)
- error(ERR_REL_EXPECTED);
- getsym(ifp);
- EXPRESSION(ifp);
- gen(OPR, 0, m);
- }
- }
- int RELATION(int token){
- if (token == eqlsym)
- return EQL;
- else if (token == neqsym)
- return NEQ;
- else if (token == lessym)
- return LSS;
- else if (token == leqsym)
- return LEQ;
- else if (token == gtrsym)
- return GTR;
- else if (token == geqsym)
- return GEQ;
- else
- return FALSE;
- }
- void EXPRESSION(FILE* ifp){
- int m=0;
- if ((TOKEN == plussym) || (TOKEN == minussym))
- getsym(ifp);
- if (TOKEN == minussym)
- m = NEG;
- TERM(ifp);
- if (m == NEG)
- gen(OPR, 0, NEG);
- while ((TOKEN == plussym) || (TOKEN == minussym)){
- if (TOKEN == plussym)
- m = ADD;
- else
- m = SUB;
- getsym(ifp);
- TERM(ifp);
- gen(OPR, 0, m);
- }
- }
- void TERM(FILE* ifp){
- int m;
- FACTOR(ifp);
- while ((TOKEN == multsym) || (TOKEN == slashsym)){
- if(TOKEN == multsym)
- m = MUL;
- else
- m = DIV;
- getsym(ifp);
- FACTOR(ifp);
- gen(OPR, 0, m);
- }
- }
- void FACTOR(FILE* ifp){
- int i;
- if (TOKEN == identsym){
- //Loads
- getname(ifp);
- i = position();
- if (i==-1)
- error(ERR_UNDECL_IDENT);
- if (symbol_table[i].kind==CONSTANT)
- gen(LIT, 0, symbol_table[i].val);
- else if (symbol_table[i].kind==VARIABLE)
- gen(LOD, Level-symbol_table[i].level, symbol_table[i].addr);
- else
- error(ERR_EXPRESS_ERROR);
- getsym(ifp);
- }
- else if (TOKEN == numbersym){
- //Load immeadiate
- getvalue(ifp);
- gen(LIT, 0, Value);
- getsym(ifp);
- }
- else if (TOKEN == lparentsym){
- getsym(ifp);
- EXPRESSION(ifp);
- if (TOKEN != rparentsym)
- error(ERR_PAREN_EXPECTED);
- getsym(ifp);
- }
- else
- error(ERR_BAD_SYMBOL);
- }
- void printCodeTable(){
- int i = 0;
- FILE* ofp;
- ofp = fopen("parcerOutput.txt", "w");
- if(ofp == NULL){
- printf("Failed to open parcerOutput.txt.\n");
- exit(-1);
- }
- while(code_table[i].op != 0){
- fprintf(ofp, "%d %d %d\n", code_table[i].op, code_table[i].l, code_table[i].m);
- i++;
- }
- fclose(ofp);
- }
- int virtualMachineMain(){
- FILE* ifp = fopen("parcerOutput.txt", "r");
- if(ifp == NULL){
- printf("Failed to open parcerInput.txt #2\n");
- exit(-1);
- }
- //file to print stack execution on.
- FILE* ofp = fopen("output.txt","w");
- if(ofp==NULL){
- printf("failed to open output.txt.\n");
- exit(-1);
- }
- storeToMemory(ifp);
- printAssembly(ofp);
- runVM(ofp);
- fclose(ofp);
- fclose(ifp);
- return 0;
- }
- void storeToMemory(FILE* ifp){
- int i = 0;
- while(fscanf(ifp, "%d %d %d", &memory[i][1], &memory[i][2], &memory[i][3]) != EOF){
- memory[i][0] = i;
- i++;
- }
- totalLinesOfCode = i;
- }
- void printAssembly(FILE* ofp){
- int i;
- char* OpAsString;
- fprintf(ofp, "Line\tOP\tL\tM\n");
- for(i = 0; i<totalLinesOfCode; i++)
- {
- switch(memory[i][1]){
- case 1: OpAsString = "lit";
- break;
- case 2: OpAsString = "opr";
- break;
- case 3: OpAsString = "lod";
- break;
- case 4: OpAsString = "sto";
- break;
- case 5: OpAsString = "cal";
- break;
- case 6: OpAsString = "inc";
- break;
- case 7: OpAsString = "jmp";
- break;
- case 8: OpAsString = "jpc";
- break;
- case 9: OpAsString = "sio";
- break;
- case 10: OpAsString = "sio";
- break;
- }
- fprintf(ofp, "%d\t%s\t%d\t%d\n", memory[i][0], OpAsString, memory[i][2], memory[i][3]);
- }
- fprintf(ofp, "\n");
- }
- void runVM(FILE* ofp){
- initializeVM(ofp);
- while(numOfOpr <= numOfCal){
- fetch();
- execute(ofp);
- }
- }
- void initializeVM(FILE* ofp){
- int i;
- SP = 0;
- BP = 1;
- PC = 0;
- initialPrint(ofp);
- IR.line = 0;
- IR.op = 0;
- IR.l = 0;
- IR.m = 0;
- for(i=0; i<MAX_STACK_HEIGHT; i++)
- Stack[i] = 0;
- for(i=0; i<1000; i++)
- ARLengthStroage[i] = 0;
- ARLengthStroagePointer = 0;
- numOfCal = 0;
- numOfOpr = 0;
- }
- void initialPrint(FILE* ofp){
- fprintf(ofp, "\t\t\t\tpc\tbp\tsp\tstack\n");
- fprintf(ofp, "initial values\t\t\t%d\t%d\t%d\n", PC, BP, SP);
- }
- void fetch(){
- IR.line = memory[PC][0];
- IR.op = memory[PC][1];
- IR.l = memory[PC][2];
- IR.m = memory[PC][3];
- PC++;
- }
- void execute(FILE* ofp){
- switch(IR.op){
- //Lit
- case 1: SP++;
- Stack[SP] = IR.m;
- ARLengthStroage[ARLengthStroagePointer]++;
- break;
- //Opr
- case 2: ALUop();
- break;
- //Lod
- case 3: SP++;
- Stack[SP] = Stack[base(IR.l) + IR.m];
- ARLengthStroage[ARLengthStroagePointer]++;
- break;
- //Sto
- case 4: Stack[base(IR.l) + IR.m] = Stack[SP];
- SP--;
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Cal
- case 5: Stack[SP + 1] = 0;
- Stack[SP + 2] = base(IR.l);
- Stack[SP + 3] = BP;
- Stack[SP + 4] = PC;
- BP = SP + 1;
- PC = IR.m;
- ARLengthStroagePointer++;
- ARLengthStroage[ARLengthStroagePointer] = 0;
- numOfCal++;
- break;
- //Inc
- case 6: SP = SP + IR.m;
- ARLengthStroage[ARLengthStroagePointer] += IR.m;
- break;
- //Jmp
- case 7: PC = IR.m;
- break;
- //Jpc
- case 8: if (Stack[SP]==0)
- PC = IR.m;
- SP--;
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Sio
- case 9: printf("%d\n", Stack[SP]);
- SP--;
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Sio
- case 10: SP++;
- printf("Please enter the value to put on the stack:\t");
- scanf("%d", &Stack[SP]);
- printf("\n");
- ARLengthStroage[ARLengthStroagePointer]++;
- break;
- }
- print(ofp);
- }
- void ALUop(){
- switch(IR.m){
- //Ret
- case 0: SP = BP - 1;
- PC = Stack[SP + 4];
- BP = Stack[SP + 3];
- numOfOpr++;
- ARLengthStroagePointer--;
- break;
- //Neg
- case 1: Stack[SP] = 0 - Stack[SP];
- break;
- //Add
- case 2: SP--;
- Stack[SP] = Stack[SP] + Stack[SP + 1];
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Sub
- case 3: SP--;
- Stack[SP] = Stack[SP] - Stack[SP + 1];
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Mul
- case 4: SP--;
- Stack[SP] = Stack[SP] * Stack[SP + 1];
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Div
- case 5: SP--;
- Stack[SP] = Stack[SP] / Stack[SP + 1];
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Odd
- case 6: Stack[SP] = Stack[SP] % 2;
- break;
- //Mod
- case 7: SP--;
- Stack[SP] = Stack[SP] % Stack[SP + 1];
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Eql
- case 8: SP--;
- Stack[SP] = (Stack[SP] == Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Neq
- case 9: SP--;
- Stack[SP] = (Stack[SP] != Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Lss
- case 10: SP--;
- Stack[SP] = (Stack[SP] < Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Leq
- case 11: SP--;
- Stack[SP] = (Stack[SP] <= Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Gtr
- case 12: SP--;
- Stack[SP] = (Stack[SP] > Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- //Geq
- case 13: SP--;
- Stack[SP] = (Stack[SP] >= Stack[SP + 1]);
- ARLengthStroage[ARLengthStroagePointer]--;
- break;
- }
- }
- int base(l){
- int b1 = BP;
- while(l>0){
- b1 = Stack[b1 + 1];
- l--;
- }
- return b1;
- }
- void print(FILE* ofp){
- char* OpAsString;
- switch(IR.op){
- case 1: OpAsString = "lit";
- break;
- case 2: OpAsString = "opr";
- break;
- case 3: OpAsString = "lod";
- break;
- case 4: OpAsString = "sto";
- break;
- case 5: OpAsString = "cal";
- break;
- case 6: OpAsString = "inc";
- break;
- case 7: OpAsString = "jmp";
- break;
- case 8: OpAsString = "jpc";
- break;
- case 9: OpAsString = "sio";
- break;
- case 10: OpAsString = "sio";
- break;
- }
- fprintf(ofp, "%d\t%s\t%d\t%d\t%d\t%d\t%d\t", IR.line, OpAsString, IR.l, IR.m, PC, BP, SP);
- printStack(ofp);
- fprintf(ofp, "\n");
- }
- void printStack(FILE* ofp){
- int i, j, stackPos=0, ARsize;
- for ( i=0; i<=ARLengthStroagePointer; ++i )
- {
- ARsize = ARLengthStroage[i];
- if ( i != 0 )
- {
- fprintf(ofp, "| ");
- if ( ARsize == 0 )
- {
- // we know we are in a call so print out 4 items
- ARsize = 4;
- }
- }
- for ( j=0; j<ARsize; ++j )
- {
- fprintf(ofp, "%d ", Stack[j+stackPos+1]);
- }
- stackPos += ARsize;
- }
- }
- void printParcerOutput(){
- char temp;
- FILE* ifp;
- ifp = fopen("parcerOutput.txt", "r");
- if(ifp == NULL){
- printf("failed to open parcerOutput.txt.\n");
- exit(-1);
- }
- while((temp = fgetc(ifp))!= EOF){
- printf("%c", temp);
- }
- printf("\n");
- fclose(ifp);
- }
- void printOutput(){
- char temp;
- FILE* ifp;
- ifp = fopen("output.txt", "r");
- if(ifp == NULL){
- printf("failed to open output.txt.\n");
- exit(-1);
- }
- while((temp = fgetc(ifp))!= EOF){
- printf("%c", temp);
- }
- printf("\n");
- fclose(ifp);
- }
- void checkRepeat(){
- int i;
- if(Kind == VARIABLE){
- for(i=MAX_SYMBOL_TABLE_SIZE-1; i>=0; i--){
- if(strcmp(Name, symbol_table[i].name)==0)
- if(Level == symbol_table[i].level)
- error(ERR_REPEAT);
- }
- }
- else{
- for(i=MAX_SYMBOL_TABLE_SIZE-1; i>=0; i--)
- if(strcmp(Name, symbol_table[i].name)==0)
- error(ERR_REPEAT);
- }
- }
- void testPrint(){
- int i=0;
- node* temp;
- for(i=0; i<10; i++){
- if(symbol_table[i].kind == VARIABLE){
- temp = symbol_table[i].head;
- printf("%s:", symbol_table[i].name);
- while(temp!=NULL){
- printf("%s ", temp->procName);
- temp = temp->next;
- }
- printf("\n");
- }
- }
- printf("\n");
- }
- node* generateLinkedList(){
- node* temp = Head;
- node* tempSymbolTemp;
- node* tempSymbolHead = malloc(sizeof(node));
- node* follow;
- tempSymbolTemp = tempSymbolHead;
- while(temp != NULL){
- strcpy(tempSymbolTemp->procName, temp->procName);
- tempSymbolTemp->next = malloc(sizeof(node));
- follow = tempSymbolTemp;
- temp = temp->next;
- tempSymbolTemp = tempSymbolTemp->next;
- }
- follow->next = NULL;
- return tempSymbolHead;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement