編譯原理詞法分析程序設計

編譯原理詞法分析程序設計

1.   課程設計目的:

結合講授內容,設計與實現一個簡單詞法分析器,通過設計編制調試一個具體的詞法分析程序,加深對詞法分析程序的功能及實現方法的理解。並掌握在對程序設計語言源程序進行掃描過程中將其分解爲各類單詞的詞法分析方法。

 

2.  課程設計內容:

 

設計與實現一個簡單詞法分析。具體內容是產生一個二元式文本文件,擴展名爲dyd,可將Pascal或C程序(測試程序)分解成爲一個一個的單詞及類型。

(選做:並查「單詞符號與種別對照表」得出其種別,用一數字表示。)

詞法編譯器基本功能包括:
(1) 輸入源程序:輸入C/java源程序;
(2) 輸出單詞,輸出形式爲:(序號,類型,單詞);
(3) 輸出出錯信息,輸出形式爲:(出錯行號,出錯列號,出錯信息);

3.  課程設計要求:

(1)掌握和實現詞法分析器的功能:

輸入源程序,輸出單詞符號(二元式表示)。

 

二元式

(單詞流)

 

源程序

(字符流)

 

詞法分析器

 

                輸入                   輸出

 

 

(2)單詞符號的分類:

關鍵字:是由程序語言定義的具有固定意義的標識符。if、int、for、while、do、return、break、continue等等,單詞種別碼爲1。

標識符:用來表示各種名字,如變量等,單詞種別碼爲10。

常數:常數的類型有整型,實型等無符號數,單詞種別碼爲11。

運算符:算術運算符,關係運算符,邏輯運算符+、-、*、/、=、>、<等;可以考慮更復雜情況>=、<=、!= ;單詞種別碼爲4。

界限符:逗號,分號等「,」「;」「(」「)」「{」「}」等等, 單詞種別碼爲5。

(3)實驗步驟:

1、確定詞法分析器的接口關係;

2、設計算法參考教材圖2.5。

(4)選用圖形界面的形式,讀文件和顯示結果,同時將結果輸出到文件中。

(5)最終上交的文件包括:測試文件、詞法分析器源程序文件、輸出文件。

(6)將運行結果粘貼到實驗報告中。


1.  實驗方法與步驟:

第一步,設計軟件圖形界面,其界面如下:

在設計該圖形界面的過程中,滾動條一直沒有出來,查了好多資料,才知道把JTextArea文本框放到有滾動條的面板裏,如下

scrollPane_1.setViewportView(textArea_1);

       textArea_1.setLineWrap(true);        //**自動換行功能

       textArea_1.setWrapStyleWord(true);            // **斷行不斷字功能

       //分別設置水平和垂直滾動條總是出現

       scrollPane_1.setHorizontalScrollBarPolicy(

               JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

       scrollPane_1.setVerticalScrollBarPolicy(

               JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

 

 

在此過程中也遇到過如何將文本內容顯示到文本框裏麻煩  解決函數如下:

private String readTxt(String path) {

        if (path == null || "".equals(path)) {

            return"";

        }

        StringBuffer sb = new StringBuffer();

        File file = new File(path);

        InputStreamReader read = null;

        BufferedReader reader = null;

        try {

            read = new InputStreamReader(new FileInputStream(file), "gb2312");

            reader = new BufferedReader(read);

            String line;

            while ((line = reader.readLine()) != null) {

                sb.append(line);

                sb.append("\n");

            }

        } catch (UnsupportedEncodingException e) {

            e.printStackTrace();

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        } catch (IOException e) {

            e.printStackTrace();

        } finally {

            if (read != null) {

                try {

                    read.close();

                } catch (IOException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

                }

            }

            if (reader != null) {

                try {

                    reader.close();

                } catch (IOException e) {

                    // TODO Auto-generated catch block

                    e.printStackTrace();

                }

            }

 

}

        return sb.toString();

    }

執行時掉用該函數將文本框裏的內容轉化爲字符串最後再顯示到文本框裏

將字符串寫入到文件裏函數如下:

publicvoid writefile(String path,String content,boolean append)

    {

       BufferedWriter bw;

       File writefile;

       boolean addStr = append;

       writefile = new File(path);

       if(writefile.exists()==false)

       {

           try {

              writefile.createNewFile();

              writefile = new File(path);

           } catch (IOException e) {

              // TODO自動生成的 catch 塊

              e.printStackTrace();

           }

          

          

       }

       else

       {

           writefile.delete();

           try {

              writefile.createNewFile();

              writefile = new File(path);

           } catch (IOException e) {

              // TODO自動生成的 catch 塊

              e.printStackTrace();

           }

       }

       try {

           FileWriter fw = new FileWriter(writefile,addStr);

           bw = new BufferedWriter(fw);

           fw.write(content);

           fw.flush();

           fw.close();

          

       } catch (IOException e) {

           // TODO自動生成的 catch 塊

           e.printStackTrace();

       }

      

      

    }

寫完函數就是簡單的調用問題了

最後是詞法分析的原理了,由於函數代碼較長,就不整理到報告裏了!!!

該軟件的執行功能及過程如下:

一、打開寫有c語言程序或者Pascal程序的文件進行詞法分析

過程如下:

點擊打開文件按鈕,進入選擇文件界面如下:

選擇cc.txt,確定後如下:

如上圖,編輯框裏已經顯示出文件的內容

點擊保存輸入可對該詞法分析的內容保存到一個自定義的文本里。過程如下

點擊保存輸出彈出選擇輸出文件保存路徑及自定義文件名文本框

輸入文件名後點擊確定出現如下分析頁面:

輸出文本內容如下:

點擊全部清空,兩個文本框清空


二、對編輯框輸入的內容直接進行分析,分析結果顯示到分析框中,運行流程如下

在編輯框中輸入C語言程序

點擊詞法分析:

點擊全部清空:

完整代碼如下:

package bianyi;


import java.awt.EventQueue;


import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.GroupLayout;
import javax.swing.JOptionPane;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JPanel;


import java.awt.Color;


import javax.swing.JLabel;


import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;


import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.JScrollPane;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.JTextArea;
import javax.swing.JButton;


public class Fenci {


private JFrame frame;
public String path;
public String path1;


/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Fenci window = new Fenci();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}


/**
* Create the application.
*/
public Fenci() {
initialize();
}


/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setTitle("\u7F16\u8BD1\u539F\u7406\u8BCD\u6CD5\u5206\u6790");
frame.setBounds(100, 100, 802, 679);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);

JPanel panel = new JPanel();
panel.setBackground(new Color(224, 255, 255));
GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
groupLayout.setHorizontalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 781, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
groupLayout.setVerticalGroup(
groupLayout.createParallelGroup(Alignment.LEADING)
.addGroup(groupLayout.createSequentialGroup()
.addComponent(panel, GroupLayout.PREFERRED_SIZE, 631, GroupLayout.PREFERRED_SIZE)
.addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

JLabel label = new JLabel("\u5317\u4FE1\u79D1\u5927\u8BCD\u6CD5\u5206\u6790\u7B80\u6613\u8F6F\u4EF6");
label.setFont(new Font("隸書", Font.BOLD, 36));

JLabel label_1 = new JLabel("\u7F16\u8F91\u6846");
label_1.setFont(new Font("隸書", Font.BOLD, 26));

JLabel label_2 = new JLabel("\u5206\u6790\u6846");
label_2.setFont(new Font("隸書", Font.BOLD, 26));

JScrollPane scrollPane = new JScrollPane();
scrollPane.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent arg0) {
}
public void ancestorMoved(AncestorEvent arg0) {
}
public void ancestorRemoved(AncestorEvent arg0) {
}
});

JScrollPane scrollPane_1 = new JScrollPane();

JButton button = new JButton("\u6253\u5F00\u6587\u4EF6");
button.setFont(new Font("隸書", Font.BOLD, 20));

JButton button_1 = new JButton("\u4FDD\u5B58\u8F93\u51FA");
button_1.setFont(new Font("隸書", Font.BOLD, 20));

JButton button_2 = new JButton("\u8BCD\u6CD5\u5206\u6790");
button_2.setFont(new Font("隸書", Font.BOLD, 20));

JButton button_3 = new JButton("\u5168\u90E8\u6E05\u7A7A");
button_3.setFont(new Font("隸書", Font.BOLD, 20));
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(
gl_panel.createParallelGroup(Alignment.TRAILING)
.addGroup(gl_panel.createSequentialGroup()
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 350, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED, 27, Short.MAX_VALUE)
.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 376, GroupLayout.PREFERRED_SIZE))
.addGroup(gl_panel.createSequentialGroup()
.addGap(37)
.addComponent(button)
.addGap(66)
.addComponent(button_1)
.addGap(71)
.addComponent(button_2, GroupLayout.PREFERRED_SIZE, 133, GroupLayout.PREFERRED_SIZE)
.addGap(37)
.addComponent(button_3, GroupLayout.PREFERRED_SIZE, 126, GroupLayout.PREFERRED_SIZE)))
.addContainerGap())
.addGroup(gl_panel.createSequentialGroup()
.addGroup(gl_panel.createParallelGroup(Alignment.TRAILING, false)
.addGroup(gl_panel.createSequentialGroup()
.addGap(153)
.addComponent(label))
.addGroup(gl_panel.createSequentialGroup()
.addGap(136)
.addComponent(label_1)
.addPreferredGap(ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(label_2)))
.addGap(172))
);
gl_panel.setVerticalGroup(
gl_panel.createParallelGroup(Alignment.LEADING)
.addGroup(gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(label)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.BASELINE)
.addComponent(label_2)
.addComponent(label_1))
.addPreferredGap(ComponentPlacement.UNRELATED)
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addComponent(scrollPane, GroupLayout.PREFERRED_SIZE, 453, GroupLayout.PREFERRED_SIZE)
.addComponent(scrollPane_1, GroupLayout.PREFERRED_SIZE, 452, GroupLayout.PREFERRED_SIZE))
.addGap(18)
.addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
.addComponent(button, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
.addComponent(button_1, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
.addComponent(button_2, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE)
.addComponent(button_3, GroupLayout.PREFERRED_SIZE, 33, GroupLayout.PREFERRED_SIZE))
.addGap(21))
);

final JTextArea textArea_1 = new JTextArea();
textArea_1.setFont(new Font("隸書", Font.BOLD, 20));
textArea_1.setBackground(new Color(245, 222, 179));
scrollPane_1.setViewportView(textArea_1);
textArea_1.setLineWrap(true);        //**自動換行功能 
textArea_1.setWrapStyleWord(true);            // **斷行不斷字功能
//分別設置水平和垂直滾動條總是出現 
scrollPane_1.setHorizontalScrollBarPolicy( 
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 
scrollPane_1.setVerticalScrollBarPolicy( 
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

final JTextArea textArea = new JTextArea();
textArea.setFont(new Font("隸書", Font.BOLD, 20));
textArea.setBackground(new Color(245, 222, 179));
scrollPane.setViewportView(textArea);
textArea.setLineWrap(true);        //**自動換行功能 
textArea.setWrapStyleWord(true);            // **斷行不斷字功能
//分別設置水平和垂直滾動條總是出現 
scrollPane.setHorizontalScrollBarPolicy( 
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); 
scrollPane.setVerticalScrollBarPolicy( 
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser filechooser = new JFileChooser();
int returnValue = filechooser.showOpenDialog(filechooser);
{

if(returnValue == JFileChooser.APPROVE_OPTION)
{
File file = filechooser.getSelectedFile();

path=file.getAbsolutePath();
String text=readTxt(path);
textArea.setText(text);
}
}
}
});
button_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JFileChooser filechooser = new JFileChooser();
filechooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);//設置能選擇文件和文件夾
filechooser.setMultiSelectionEnabled(false);//禁用多重選擇
int returnValue = filechooser.showOpenDialog(filechooser);
{

if(returnValue == JFileChooser.APPROVE_OPTION)
{
File file = filechooser.getSelectedFile();

path1=file.getAbsolutePath();
String rename = JOptionPane.showInputDialog("請輸入保存文件名字:");
String name=path1+"\\"+rename;
Suanfa.suanfa1(path, name);
String text=readTxt(name);
textArea_1.setText(text);
}
}
}
});
button_2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {

String intfile ="in.text";
String outfile="out.text";
String neirong=textArea.getText();
writefile(intfile,neirong,false);
Suanfa.suanfa1(intfile, outfile);
String text=readTxt(outfile);
textArea_1.setText(text); 

}
});
button_3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
textArea.setText("");
textArea_1.setText("");
}
});

panel.setLayout(gl_panel);
frame.getContentPane().setLayout(groupLayout);
}
private String readTxt(String path) {
        if (path == null || "".equals(path)) {
            return "";
        }
        StringBuffer sb = new StringBuffer();
        File file = new File(path);
        InputStreamReader read = null;
        BufferedReader reader = null;
        try {
            read = new InputStreamReader(new FileInputStream(file), "gb2312");
            reader = new BufferedReader(read);
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
                sb.append("\n");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (read != null) {
                try {
                    read.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }


}
        return sb.toString();
    }
public void writefile(String path,String content,boolean append)
{
BufferedWriter bw;
File writefile;
boolean addStr = append;
writefile = new File(path);
if(writefile.exists()==false)
{
try {
writefile.createNewFile();
writefile = new File(path);
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}


}
else
{
writefile.delete();
try {
writefile.createNewFile();
writefile = new File(path);
} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}
}
try {
FileWriter fw = new FileWriter(writefile,addStr);
bw = new BufferedWriter(fw);
fw.write(content);
fw.flush();
fw.close();

} catch (IOException e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
}


}


}






package bianyi;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileWriter;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;public class Suanfa {public static void suanfa1(String infile,String outfile){try {              FileInputStream f = new FileInputStream(infile);              BufferedReader dr = new BufferedReader(new InputStreamReader(f));                BufferedWriter output = new BufferedWriter(new FileWriter(outfile));                String line = "";              int cnt = 0;              while ((line = dr.readLine()) != null) {                  cnt++;                  if (cnt == 1) {                                           output.write(String.format("line : %d\r\n", cnt));                  } else {                                           output.write(String.format("\r\n\r\nline : %d\r\n", cnt));                  }                  if (line.equals("")) {                                           output.write("空行~\r\n");                  } else {                                            char[] strLine = line.toCharArray();                                            for (int i = 0; i < strLine.length; i++) {                          char ch = strLine[i];                          String token = "";                            if (isAlpha(ch)) // 判斷關鍵字和標識符                          {                              do {                                  token += ch;                                  i++;                                  if(i>=strLine.length) break;                                  ch = strLine[i];                              } while (ch != '\0' && (isAlpha(ch) || isDigit(ch)));                                --i; // 指針回退                                if (isMatchKeyword(token.toString())) // 是關鍵字                              {                                                                 output.write(String.format(                                          "%-10s\t<%s,1 關鍵字-->\r\n", token, token));                              } else // 是標識符                              {                                  if (symbol.isEmpty()                                          || (!symbol.isEmpty() && !symbol                                                  .containsKey(token))) {                                      symbol.put(token, symbol_pos);                                                                           output.write(String.format(                                              "%-10s\t<10 標識符,(%s,入口:%d)>\r\n",                                              token, token, symbol_pos));                                      symbol_pos++;                                  } else {                                  //%-10s\t<ERROR:標識符重複!>\r\n                                      output                                              .write(String                                                      .format(                                                              "%-10s\t<ERROR:標識符重複!>\r\n ",                                                              token));                                  }                              }                              token = "";                          } else if (isDigit(ch)) // 判斷數字常量                          {                              int s = 1;                              Boolean isfloat = false;                              while (ch != '\0'                                      && (isDigit(ch) || ch == '.' || ch == 'e' || ch == '-')) {                                  if (ch == '.' || ch == 'e')                                      isfloat = true;                                    int k;                                  for (k = 1; k <= 6; k++) {                                      char tmpstr[] = digitDFA[s].toCharArray();                                      if (ch != '#'                                              && 1 == in_digitDFA(ch, tmpstr[k])) {                                          token += ch;                                          s = k;                                          break;                                      }                                  }                                  if (k > 6)                                      break;                                  i++;if(i>=strLine.length) break;                                  ch = strLine[i];                              }                              // if(ch) --i; // 指針回退                              Boolean haveMistake = false;                                if (s == 2 || s == 4 || s == 5) {                                  haveMistake = true;                              } else // 1,3,6                              {                                  if (!isOp(ch) || ch == '.')                                      haveMistake = true;                              }                                if (haveMistake) // 錯誤處理                              {                                  while (ch != '\0' && ch != ',' && ch != ';'                                          && ch != ' ') // 一直到「可分割」的字符結束                                  {                                      token += ch;                                      i++;if(i>=strLine.length) break;                                      ch = strLine[i];                                  }                                                                  output.write(String.format(                                          "%-10s\tERROR:請確保實常數輸入正確!\r\n", token));                              } else {                                  if (isfloat) {                                                                         output.write(String.format(                                              "%-10s\t<11實型常量,%s>\r\n", token,                                              token));                                  } else {                                                                          output.write(String.format(                                              "%-10s\t<11整型常量,%s>\r\n", token,                                              token));                                  }                              }                              --i;                              token = "";                          } else if (ch == '\'') // 識別字符常量,類似處理字符串常量。                          {                              int s = 0;                              Boolean haveMistake = false;                              String token1 = "";                              token1 += ch;                              while (s != 3) {                                  i++;if(i>=strLine.length) break;                                  ch = strLine[i];                                  if (ch == '\0') {                                      haveMistake = true;                                      break;                                  }                                  for (int k = 0; k < 4; k++) {                                      char tmpstr[] = stConDFA[s].toCharArray();                                      if (in_sinStConDFA(ch, tmpstr[k])) {                                          token1 += ch; // 爲輸出                                          if (k == 2 && s == 1) {                                              if (isEsSt(ch)) // 是轉義字符                                                  token = token + '\\' + ch;                                              else                                                  token += ch;                                          } else if (k != 3 && k != 1)                                              token += ch;                                          s = k;                                          break;                                      }                                  }                              }                              if (haveMistake) {                                                                 output.write(String.format(                                          "%s\tERROR:字符常量引號不封閉\r\n", token1));                                  --i;                              } else {                                  if (token.length() == 1) {                                                                          output.write(String.format(                                              "%-10s\t<字符常量,%s>\r\n", token1,                                              token));                                  } else if (token.length() == 2) {                                      if (isEsSt(token.charAt(1))                                              && token.charAt(0) == '\\') {                                                                                   output.write(String.format(                                                  "%-10s\t<字符常量,%s>\r\n", token1,                                                  token));                                      }                                  }                              }                              token = "";                          } else if (ch == '"') // 處理字符串常量的                          {                              String token1 = "";                              token1 += ch;                                int s = 0;                              Boolean haveMistake = false;                              while (s != 3 ) {                                  i++;                                  if(i>=strLine.length-1)                                   {                                      haveMistake = true;                                      break;                                  }                                                                    ch = strLine[i];                                  if (ch == '\0') {                                      haveMistake = true;                                      break;                                  }                                  for (int k = 0; k < 4; k++) {                                      char tmpstr[] = stConDFA[s].toCharArray();                                      if (in_stConDFA(ch, tmpstr[k])) {                                          token1 += ch;                                          if (k == 2 && s == 1) {                                              if (isEsSt(ch)) // 是轉義字符                                                  token = token + '\\' + ch;                                              else                                                  token += ch;                                          } else if (k != 3 && k != 1)                                              token += ch;                                          s = k;                                          break;                                      }                                  }                              }                              if (haveMistake) {                                                                  output.write(String.format(                                          "%-10s\tERROR:字符串常量引號不封閉\n", token1));                                  --i;                              } else {                                                                  output                                          .write(String.format(                                                  "%-10s\t<字符串常量,%s>\r\n",                                                  token1, token));                              }                              token = "";                          } else if (isOp(ch)) // 運算符,界符                          {                              token += ch;                              if (isPlusEqu(ch)) // 後面可以用一個"="                              {                                  i++;if(i>=strLine.length) break;                                  ch = strLine[i];                                  if (ch == '=')                                      token += ch;                                  else {                                      if (isPlusSame(strLine[i - 1])                                              && ch == strLine[i - 1])                                          token += ch; // 後面可以用一個和自己一樣的                                      else {                                          --i;                                      }                                  }                              }                                                          output.write(String.format("%-10s\t<%s,符號-->\r\n",                                      token, token));                              token = "";                          } else if (ch == '/') // 註釋+除號: 註釋只要識別出來就好。                          {                              token += ch;                              i++;if(i>=strLine.length) break;                              ch = strLine[i];                                if (ch != '*' && ch != '/') // 除號處理                              {                                  if (ch == '=')                                      token += ch; // /=                                  else {                                      --i; // 指針回退 // /                                  }                                                                  output.write(String.format("%-10s\t<%s,-->\n",                                          token, token));                                  token = "";                              } else // 註釋可能是‘//’也可能是‘/*’                              {                                  Boolean haveMistake = false;                                  if (ch == '*') {                                      token += ch; // ch == '*'                                      int s = 2;                                        while (s != 4) {                                          i++;if(i>=strLine.length) break;                                          ch = strLine[i]; // 注意判斷溢出!                                          if (ch == '\0') {                                              haveMistake = true;                                              break;                                          }                                          for (int k = 2; k <= 4; k++) {                                              char tmpstr[] = noteDFA[s]                                                      .toCharArray();                                              if (1 == in_noteDFA(ch, tmpstr[k],                                                      s)) {                                                  token += ch;                                                  s = k;                                                  break;                                              }                                          }                                      }                                  }                                  else if(ch == '/') //這裏就不用狀態轉移了...                                  {                                      int index = line.lastIndexOf("//");                                                                            String tmpstr=line.substring(index);                                      int tmpint = tmpstr.length();                                      for(int k=0;k<tmpint;k++)                                       {                                          i++;                                      }                                      token = tmpstr;                                  }                                                                  output.write(String.format("%-10s\t", token));                                  if (haveMistake) {                                                                          output.write("ERROR:註釋沒有封閉\r\n");                                      --i;                                  } else {                                                                           output.write(String.format("(註釋:%s)\n",                                              token));                                  }                                    token = "";                              }                          }                          else // 一些很奇怪的字符                          {                              if(ch != ' ' && ch != '\t')                              {                                                                   output.write(String.format("%-10c ERROR:存在不合法字符\n",ch));                              }                          }                      }                  }                }