Syntaxhighlighter

2010年10月23日 星期六

語言結構期中範本


好久沒發作業了@@
這個範本大約300行,




因為剛開始定義了些變數不然可以更精簡的,
不過這樣也比較方便看,

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

沒有留言:

張貼留言