好久沒發作業了@@
這次的驗收作業跟以往比,
相對的比較輕鬆,
程式內容大綱可以參考課本有,
除了
fopen 開檔
寫入與讀入檔案
其餘都是以前學過的,
我只幫忙定義完某些函式,
再加上助教要求判定的一些符號,
趁著11月期中前有心要做作業的可以參考看看,
有啥要修改不懂得可以問我@@盡量幫忙解答
#include <iostream> #define ID 10 #define INT_LIT 11 #define MAIN 12 #define IF 13 #define ELSE 14 #define PRINTF 15 #define RETURN 16 #define INT 17 #define CHAR 18 #define LPAREN 40 #define RPAREN 41 #define LBRACE 123 #define RBRACE 125 #define COMMA 44 #define SEMICOLON 59 #define DBQUOTATION 34 #define QUOTATION 39 #define ASSIGNOP 61 #define PLUSOP 43 #define MINUSOP 45 #define MUTIOP 42 #define DIVIDEOP 47 #define PERCENT 37 #define LESS 60 #define MORE 62 #define SCANEOF -1 using namespace std; /* Global variables */ FILE *input; FILE *output; char lexeme[100]; char nextChar; int charClass; int lexLen; const int LETTER = 0; const int DIGIT = 1; const int UNKNOWN = 2; bool error = 0; // 判斷 type bool isalpha(char c){ if( ( (c >= 65) && (c <= 90) ) ||( (c >= 97) && (c <= 122) ) ||( c == 95 ) ) return 1; return 0; } bool isdigit(char c){ if( (c >= 48) && (c <= 57) ) return 1; return 0; } bool isspace(char c){ if (c == ' ') return 1; if(c== '\n') return 1; return 0; } //檢查內容 int lookup(char *lexeme,int type){ if( strncmp(lexeme,"main",4) == 0 ) return MAIN; else if( strncmp(lexeme,"if",2) == 0 ) return IF; else if( strncmp(lexeme,"else",4) == 0 ) return ELSE; else if( strncmp(lexeme,"printf",6) == 0 ) return PRINTF; else if( strncmp(lexeme,"return",6) == 0 ) return RETURN; else if( strncmp(lexeme,"int",3) == 0 ) return INT; else if( strncmp(lexeme,"char",4) == 0 ) return CHAR; else if( strncmp(lexeme,"(",1) == 0 ) return LPAREN; else if( strncmp(lexeme,")",1) == 0 ) return RPAREN; else if( strncmp(lexeme,"{",1) == 0 ) return LBRACE; else if( strncmp(lexeme,"}",1) == 0 ) return RBRACE; else if( strncmp(lexeme,",",1) == 0 ) return COMMA; else if( strncmp(lexeme,";",1) == 0 ) return SEMICOLON; else if( strncmp(lexeme,"\"",1) == 0 ) return DBQUOTATION; else if( strncmp(lexeme,"'",1) == 0 ) return QUOTATION; else if( strncmp(lexeme,"=",1) == 0 ) return ASSIGNOP; else if( strncmp(lexeme,"+",1) == 0 ) return PLUSOP; else if( strncmp(lexeme,"-",1) == 0 ) return MINUSOP; else if( strncmp(lexeme,"*",1) == 0 ) return MUTIOP; else if( strncmp(lexeme,"/",1) == 0 ) return DIVIDEOP; else if( strncmp(lexeme,"%",1) == 0 ) return PERCENT; else if( strncmp(lexeme,"<",1) == 0 ) return LESS; else if( strncmp(lexeme,">",1) == 0 ) return MORE; else if(lexeme[0] == EOF) return SCANEOF; else { if( type == 1 ) { if( lexeme[0] == '_' ) error = 1; return ID; } else return UNKNOWN; } } /* addChar - a function to add nextChar to lexeme */ void addChar(){ if(lexLen <= 99) lexeme[lexLen++] = nextChar; else printf("Error - lexeme is too long \n"); } /* getChar - a function to get the next character of input and determine its character class */ void getChar(){ /* do whatever is required to get the next character from input and put it in nextChar */ nextChar = fgetc(input); if(isalpha(nextChar)) charClass = LETTER; else if(isdigit(nextChar)) charClass = DIGIT; else charClass = UNKNOWN; } /* getNonBlank - calls getChar until it returns a non-whitespace character */ void getNonBlank(){ while(isspace(nextChar)) getChar(); } /* 印出對應的符號 */ void print(int x){ if( x == EOF ) fprintf(output,"EOF"); else for( int i=0; i<lexLen; i++) fprintf(output,"%c",lexeme[i]); switch(x) { case 10: fprintf(output,"\t\t%s\n","ID"); break; case 11: fprintf(output,"\t\t%s\n","INT_LIT"); break; case 12: fprintf(output,"\t\t%s\n","MAIN"); break; case 13: fprintf(output,"\t\t%s\n","IF"); break; case 14: fprintf(output,"\t\t%s\n","ELSE"); break; case 15: fprintf(output,"\t\t%s\n","PRINTF"); break; case 16: fprintf(output,"\t\t%s\n","RETURN"); break; case 17: fprintf(output,"\t\t%s\n","INT"); break; case 18: fprintf(output,"\t\t%s\n","CHAR"); break; case 40: fprintf(output,"\t\t%s\n","LPAREN"); break; case 41: fprintf(output,"\t\t%s\n","RPAREN"); break; case 123: fprintf(output,"\t\t%s\n","LBRACE"); break; case 125: fprintf(output,"\t\t%s\n","RBRACE"); break; case 44: fprintf(output,"\t\t%s\n","COMMA"); break; case 59: fprintf(output,"\t\t%s\n","SEMICOLON"); break; case 34: fprintf(output,"\t\t%s\n","DBQUOTATION"); break; case 39: fprintf(output,"\t\t%s\n","QUOTATION"); break; case 61: fprintf(output,"\t\t%s\n","ASSIGNOP"); break; case 43: fprintf(output,"\t\t%s\n","PLUSOP"); break; case 45: fprintf(output,"\t\t%s\n","MINUSOP"); break; case 42: fprintf(output,"\t\t%s\n","MUTIOP"); break; case 47: fprintf(output,"\t\t%s\n","DIVIDEOP"); break; case 37: fprintf(output,"\t\t%s\n","PERCENT"); break; case 60: fprintf(output,"\t\t%s\n","LESS"); break; case 62: fprintf(output,"\t\t%s\n","MORE"); break; case -1: fprintf(output,"\t\t%s","SCANEOF"); break; default: fprintf(output,"\t\t%s\n","UNKNOWN"); break; } } /* lex - a simple lexical analyzer */ int lex(){ lexLen = 0; static int first = 1; /*If is the first call to lex, initialize by calling getChar */ if(first) { getChar(); first = 0; } getNonBlank(); switch (charClass) { /* Parse identifiers and reserved words */ case LETTER: addChar(); getChar(); while(charClass == LETTER || charClass == DIGIT) { addChar(); getChar(); } return lookup(lexeme,1); /* Parse integer literals */ case DIGIT: addChar(); getChar(); if(lexeme[0] != '0') { while(charClass == DIGIT) { addChar(); getChar(); } } if( charClass == LETTER ) error = 1; return INT_LIT; default: addChar(); getChar(); return lookup(lexeme,0); } /* End of switch */ } /* End if function lex */ int main(int argc,char* argv[]){ if( argc != 3) //執行時須輸入3樣參數, 例如: Example.exe input.txt output.txt cout<< "Error!! 請輸入來源檔與輸出檔!"<<endl; else { input = fopen(argv[1],"r"); output = fopen(argv[2],"w"); int c; do { c = lex(); print(c); } while( (c != EOF) && (!error) ); } if( error ) fprintf(output,"Syntax Error!"); system("pause"); return 0; }
沒有留言:
張貼留言