Java編寫的C語言詞法分析器

來源:互聯網
上載者:User

標籤:

Java編寫的C語言詞法分析器

 


                

    這是java編寫的C語言詞法分析器,我也是參考很多代碼,然後核心代碼整理起來,放在QQ空間和部落格上,目的是互相學習借鑒,希望可以得到高手改進。這個詞法分析器實現的功能有開啟檔案、儲存檔案、開啟協助文檔、文本域內容的剪下和複製和黏貼、進行詞法分析

程式的項目結構,Word類和Unidentifiable類是兩個JavaBean類,存放的參數有兩個row(整型)、word(String),row用於擷取行數,word用於擷取標識符,LexerFrame是詞法分析器的介面類,Analyze封裝了進行詞法分析的核心代碼 ,doc檔案夾放一個協助文檔,當使用者點擊協助按鈕時可以彈出來以協助使用者使用。




//核心程式:


package com.lexer;import java.util.ArrayList;
/**
*1~20號為關鍵字,用下標表示,i+1就是其機器碼;21~40號為操作符,用下標表示,i+21就是其機器碼;41~60號為分界符,
*  用下標表示,i+41就是其機器碼;使用者自訂的標識符,其機器碼為51;常數的機器碼為52;不可以識別的標識符,其機器碼為0
*/ 

public class Analyze { //關鍵字
 private String keyword[]={"int","long","char","if","else","for","while","return","break","continue",
   "switch","case","default","float","double","void","struct","static","do","short"};
 
 //運算子
 private String operator[]={"+","-","*","/","%","=",">","<","!","==","!=",">=","<=","++","--","&","&&","||","[","]"};
 
 //分界符
 private String delimiter[]={",",";","(",")","{","}","\‘","\"",":","#"};
 
 public Analyze() {
  
 }
 
 /**
  * 判斷是否是數字
  */
 public boolean isDigit(char ch){
  if(ch>=‘0‘&&ch<=‘9‘){
   return true;
  }else{
   return false;
  }
 }
 
 /**
  * 判斷是否是字母的函數
  */
 public boolean isLetter(char ch){
  if((ch>=‘a‘&&ch<=‘z‘)||(ch>=‘A‘&&ch<=‘Z‘)){
   return true;
  }else{
   return false;
  }
 }
 
 /**
  * 判斷是否由兩個運算子組成
  */
 public boolean isTwoOperator(String str,char ch){
  char lc;
  int flag=0;
  if(str.length()>1||str.length()==0){//字元數大於2和無字元的情況
   return false;
  }else{//字元數等於2的情況
   lc=str.charAt(str.length()-1);
   if(ch==‘=‘&&(lc==‘>‘||lc==‘<‘||lc==‘=‘||lc==‘!‘)){
    
   }else if(ch==‘+‘&&lc==‘+‘){
    
   }else if(ch==‘-‘&&lc==‘-‘){
    
   }else if(ch==‘|‘&&lc==‘|‘){
    
   }else if(ch==‘&‘&&lc==‘&‘){
    
   }else{
    return false;//否就返回false
   }
   return true;//其它符號的情況都返回true
  }
 }
 
 /**
  * 擷取關鍵字的機器碼
  */
 public int getKeywordOpcodes(String str){
  
  int i; 
  for(i=0;i<keyword.length;i++){
   if(str.equals(keyword[i]))
    break;
  }
  if(i<keyword.length){
   return i+1;//返回關鍵字的機器碼
  }else{
   return 0;
  }
 }
 
 /**
  * 擷取操作符的機器碼
  */
 public int getOperatorOpcodes(String str){
  int i;
  for(i=0;i<operator.length;i++){
   if(str.equals(operator[i]))
    break;
  }
  
  if(i<operator.length)
   return i+21;//返回操作符的機器碼
  else
   return 0;
 }
 
 /**
  * 擷取分界符的機器碼
  */
 public int getDelimiterOpcodes(String str){
  int i;
  for(i=0;i<delimiter.length;i++){
   if(str.equals(delimiter[i]))
    break;
  }
  
  if(i<delimiter.length)
   return i+41;//返回分界符的機器碼
  else
   return 0;
 }
  
 /**
  * 判斷字元是否可以識別
  */
 public boolean isIdent(String str){
  char ch;
  int i;
  for(i=0;i<str.length();i++){
   ch=str.charAt(i);
   //非數字串的情況和非由英文字母組成的字串
   if((i==0&&!isLetter(ch))||(!isDigit(ch)&&!isLetter(ch))){
    break;
   }
  }
  
  if(i<str.length()){
   return false;
     }else{
   return true;
     }
 }
 
 /**
  *
  * 預先處理函數
  */
 public String preFunction(String str){
  String ts="";
  
  int i;
  
  char ch,nc;
  //這裡的i<str.length()-1
  for(i=0;i<str.length()-1;i++){ 
   ch=str.charAt(i);
   nc=str.charAt(i+1);
   
   if(ch==‘\n‘){//如果字元是分行符號,將\n換成$
    ch=‘$‘;
    ts=ts+ch;
   }else if(ch==‘ ‘||ch==‘\r‘||ch==‘\t‘){
    if(nc==‘ ‘||nc==‘\r‘||ch==‘\t‘){
     continue;//連續‘ ‘或者‘\t‘或者‘\r‘的情況,直接跳過
    }else{
     ch=‘ ‘;//一個‘ ‘或者‘\t‘或者‘\r‘的情況,將這些字元換成‘ ‘
     ts=ts+ch;
    }
   }else{
    ts=ts+ch;//將字元連起來
   }
  }
  ch=str.charAt(str.length()-1);
  if(ch!=‘ ‘&&ch!=‘\r‘&&ch!=‘\t‘&&ch!=‘\n‘){
   ts=ts+ch;
  }
  return ts;
 }
 
 /**
  * 將字串分成一個個單詞,存放在數組列表
  */
 public ArrayList<Word> divide(String str){
  ArrayList<Word> list=new ArrayList<Word>();
  
  String s="";
  char ch;
  int i;
  int row=1;
  
  for(i=0;i<str.length();i++){
   ch=str.charAt(i);
   if(i==0&&ch==‘ ‘)//字串的第一個字元
    continue;
   if(ch==‘ ‘){//‘ ‘或者‘\t‘或者‘\r‘的情況
    if(s!=""){
     list.add(new Word(row, s));
     s="";//置空
    }else{
     continue;
    }
   }else if(isDigit(ch)||isLetter(ch)){
    if(s==""||isDigit(s.charAt(s.length()-1))||isLetter(s.charAt(s.length()-1))){
     s = s + ch;
    }else{
     list.add(new Word(row, s));
     s = "";
     s=s + ch;
    } 
   }else{
    if(isTwoOperator(s, ch)){//兩個運算子的情況
     s = s + ch;
    }else{
     if(s==""&&ch!=‘$‘){
      s = s + ch;
     }else if(s==""&&ch==‘$‘){//若檢測到$符號,就換行
      row++;//行數加一
     }else{
      list.add(new Word(row, s));
      s = "";
      if(ch!=‘$‘){
       s=s + ch;
      }else{
       row++;
      }
     }
    } 
   }
  }
  if(s!=""){
   list.add(new Word(row, s));
  }
  return list;
 }
 
 /**
  * 判斷字串是數字串,單個字元,還是一個字串
  */
 public int check(String str){
  char ch;
  ch=str.charAt(0);
  if(ch>=‘0‘&&ch<=‘9‘){
   return 1;//數字串
  }
  if(str.length()==1)
   return 2;//單個字元
  else
   return 3;//一個字串
 }
 
 /**
  *
  * 檢查字串是否為數字串,返回其機器碼
  */
 public int checkDigit(String str){
  int i;
  char ch;
  for(i=0;i<str.length();i++){
   ch=str.charAt(i);
   if(ch>‘9‘||ch<‘0‘)
    break;
  }
  if(i<str.length()){
   return 0;//不可識別的情況
  }else{
   return 52;//常數
  }
 }
 
 /**
  *
  * 檢查字串是否為單個字元,返回其機器碼
  */
 public int checkChar(String str){
  if(getOperatorOpcodes(str)!=0){//操作符
   return getOperatorOpcodes(str);
  }else if(getDelimiterOpcodes(str)!=0){//分界符
   return getDelimiterOpcodes(str);
  }else if(isIdent(str)){
   return 51;//使用者自訂標識符的機器碼
  }else{
   return 0;//不可以被識別的標識符,機器碼為0
  }
 }
 
 /**
  *
  * 檢查字串是否為字串,返回其機器碼
  */
 public int checkString(String str){
  if(getOperatorOpcodes(str)!=0){//操作符
   return getOperatorOpcodes(str);
  }else if(getKeywordOpcodes(str)!=0){//關鍵字
   return getKeywordOpcodes(str);
    }else if(isIdent(str)){
   return 51;//使用者自訂標識符的機器碼
    }else{
   return 0;//不可以被識別的標識符,機器碼為0
    }
 }
 
 
}


//********************************************************************************************************************
在介面類寫這個方法來調用方法

/**
  * 詞法分析
  */
 public void doTokenizing(){
  
  consoleTextArea.setText(null);
  ArrayList<Word> wlist=new ArrayList<Word>();
  ArrayList<Unidentifiable> ulist=new ArrayList<Unidentifiable>();
  
  String s,ts,str;
  Word word;
  
  int i;
  int opcodes=-1;
  int errorNum=0;
  
  int count=0;
  
  s=fileContentTextArea.getText();
  if(s.length()>1){
   ts=analyze.preFunction(s);
   wlist=analyze.divide(ts);
   values=new String[wlist.size()][3];
   while(wlist.size()>0){
    word=(Word)wlist.remove(0);
    str=word.getWord();
    i=analyze.check(str);
    switch (i) {
    case 1:
     opcodes=analyze.checkDigit(str);
     break;
    case 2:
     opcodes=analyze.checkChar(str);
     break;
    case 3:
     opcodes=analyze.checkString(str);
     break;
    }
    
    if(opcodes==0){
     Unidentifiable u=new Unidentifiable(word.getRow(), str);
     ulist.add(u);
     errorNum++;
    }
    
    values[count][0]=String.valueOf(word.getRow());
    values[count][1]=str;
    values[count][2]=String.valueOf(opcodes);
    
    count++;
    
   }
   
   //更新表格內容
   DefaultTableModel model=(DefaultTableModel)table.getModel();
   while(model.getRowCount()>0){
    model.removeRow(model.getRowCount()-1);
   }
      
        model.setDataVector(values,title);
   
   table=new JTable(model);
    
    consoleTextArea.append("共有"+errorNum+"處錯誤!"+"\n");
    while (ulist.size()>0) {
     int r;
     String string;
     Unidentifiable uni=ulist.remove(0);
     r=uni.getRow();
     string=uni.getWord();
     consoleTextArea.append("第"+r+"行:"+"錯誤,"+string+"\n");
    }
  }else{
   int j;
   j=JOptionPane.showConfirmDialog(this, "請輸入程式!");
   if(j!=JOptionPane.YES_OPTION){
    return;
   }
  }
  
 }

Java編寫的C語言詞法分析器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.