import java.io.*; 
   
public class Scanner {
    //输出缓冲区类型定义
    class OutArr{
    String name;
    String type;
    OutArr(String n,String t){
        name=n;
        type=t;
    }
    OutArr(char n,char t){
        name=String.valueOf(n);
        type=String.valueOf(t);
    }
    OutArr(String n,char t){
        name=n;
        type=String.valueOf(t);
    }
}
    //保留字表
    private static final String[] KEY_WORD = {      
        "register",
        "return",
        "short",
        "signed",
        "sizeof",
        "static",
        "struct",
        "switch",
        "typedef",
        "union",
        "unsigned",
        "void",
        "volatile",
        "while",        
    };
    int lp=1,st=0;//指针
    int count=0;//用于计算输出个数
    char[] Inbuff=new char[240];    //输入缓冲区?  
    OutArr[] oa=new OutArr[1000];   //输出缓冲区?
    String strToken;                //当前读入单词
    FileReader fr;                  //读文件指针
    FileWriter fw;           //写入文件指针
    public Scanner(String filename) {
        try{
         fr =new FileReader(filename);         
        }catch(IOException e){
            System.out.println("Error");
            e.printStackTrace();
        }
    }
    //把文件读入缓冲区
    FileReader Get(FileReader f){
        int k=1;
        try{         
                        do{             
                            Inbuff[k]=(char)f.read();
                            k++;
                        }while(Inbuff[k]!=(char)-1 && k<239);
        }catch(IOException e){
            System.out.println("Error");
            e.printStackTrace();
        }
        return f;
    }
    //实现lp加1,并检查输入缓冲是否满
    int nextChar(int a){
        a++;
        if(a==Inbuff.length){
            Inbuff[0]=Inbuff[Inbuff.length-1];       
            fr=Get(fr);//Get函数怎么用的?
            a=0;
        }
        return a;            
    }
    //从输入缓冲区读入一个单词
    void readOneWord()  
 {
  int len=Inbuff.length;
                //System.out.println(len+"   "+lp);
  //跳过空格等
  while(Inbuff[lp]==' '||Inbuff[lp]=='\t'||Inbuff[lp]=='\n')
  {
   lp=nextChar(lp);
  }
  //读取标志符/保留字单词
  if(Character.isLetter(Inbuff[lp])){
   int st=lp; //?
   lp=nextChar(lp);
   }
   strToken=new String(Inbuff,st,lp-st);
                        //检查是否保留字,将结果写入输出中
                        for(int i=0;i<43;i++)
                            if(strToken.equals(KEY_WORD[i])){
                                oa[count++]=new OutArr(strToken,"keyword");
                                break;
                            }
                            else if(i==42){
                                 oa[count++]=new OutArr(strToken, "variable");
                                 break;
                            }
  //读取数字常数单词(整数/浮点...)
  else if(Character.isDigit(Inbuff[lp])){
   int st=lp; 
   boolean isFloat=false;
   lp=nextChar(lp);
   while(lp>0 )   {if(Inbuff[lp]=='.')
    isFloat=true;
    lp=nextChar(lp);
   }
   strToken=new String(Inbuff,st,lp-st);
                        //检查是否小数,将结果写入输出中
                        if(isFloat)
                            oa[count++]=new OutArr(strToken, "float_digit");                        else
                            oa[count++]=new OutArr(strToken, "int_digit");
  }
  //读取字符串常数单词
 /* else if(Inbuff[lp]=='\"') {
   char endc='\"';
   lp=nextChar(lp);
   int st=lp; 
   while(lp )   lp=nextChar(lp);    
   }
   strToken=new String(Inbuff,st,lp-st);
   oa[count++]=new OutArr(strToken,"String");
   lp++; //消耗掉 " '
  */
  //读取界符/运算符单词  一符一种
 }
    void Out_result(){
        try{
            fw=new FileWriter("/root/Project/Complier/src/Complier/result.txt");
            for(int i=0;i<=count;i++)              
            fw.append(oa[i].name+"\t"+oa[i].type+"\n");
            
            count=0;
        }catch(Exception e){
            System.err.println("Error");
        }
    }
    //扫描器启动方法
        void Run(){            
                fr=Get(fr);
                int k=0;
               do{
                    readOneWord();
                    k++;
                    if(k==Inbuff.length)
                        k=0;
                    if(count==999)
                        Out_result();                            
                }while (Inbuff[k] !=(char) -1); 
                try{
                    Out_result();
                    fr.close();
                    fw.close();
                }catch(IOException e){
                    System.out.println("Error");
                    e.printStackTrace();
                }
        }
        public static void main(String[] args){
            Scanner s=new Scanner("/root/Project/Complier/build.xml");
            s.Run();
        }
}