好久沒發作業了@@
這次的驗收作業跟以往比,
相對的比較輕鬆,
程式內容大綱可以參考課本有,
除了
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;
}
沒有留言:
張貼留言