diff --git a/.classpath b/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..18d70f02cb8eeded3bb20b75f0cd29bb66157990 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000000000000000000000000000000000000..ab3dbafb906418b96d8807659a173f3c2dc04b4f --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + lexer + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..8000cd6ca6142c8827db81f47ca38a3d5d7e2eaf --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/bin/com/lexer/Analyze.class b/bin/com/lexer/Analyze.class new file mode 100644 index 0000000000000000000000000000000000000000..d83553e03d4c9a37a12214b6cbbc9ab52e5f510f Binary files /dev/null and b/bin/com/lexer/Analyze.class differ diff --git a/bin/com/lexer/LexerFrame.class b/bin/com/lexer/LexerFrame.class new file mode 100644 index 0000000000000000000000000000000000000000..b8c1ae56e64654ddb02e408dc7d654eb37559fa0 Binary files /dev/null and b/bin/com/lexer/LexerFrame.class differ diff --git a/bin/com/lexer/Unidentifiable.class b/bin/com/lexer/Unidentifiable.class new file mode 100644 index 0000000000000000000000000000000000000000..6983e4abbb0af06b87f9a5741ead571cf8eca2bc Binary files /dev/null and b/bin/com/lexer/Unidentifiable.class differ diff --git a/bin/com/lexer/Word.class b/bin/com/lexer/Word.class new file mode 100644 index 0000000000000000000000000000000000000000..bc06f5f14231560568f471b5c1e51f4e31d7e47e Binary files /dev/null and b/bin/com/lexer/Word.class differ diff --git a/doc/help.doc b/doc/help.doc new file mode 100644 index 0000000000000000000000000000000000000000..5d8aaa6055d4597a516e66526e8a19572c08fe81 Binary files /dev/null and b/doc/help.doc differ diff --git a/image/clear.png b/image/clear.png new file mode 100644 index 0000000000000000000000000000000000000000..b3041d4094b8614175f1486ee01e85509d3a0c8b Binary files /dev/null and b/image/clear.png differ diff --git a/image/copy.png b/image/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..d32a8f3713b767297f94e4b3ed3830ffa267b32c Binary files /dev/null and b/image/copy.png differ diff --git a/image/cut.png b/image/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..e768d2737d4fe656eb4a42e54ed3ef1568a16134 Binary files /dev/null and b/image/cut.png differ diff --git a/image/exit.png b/image/exit.png new file mode 100644 index 0000000000000000000000000000000000000000..b29700771daa9f0faa67d0631c4d0a8d59d77710 Binary files /dev/null and b/image/exit.png differ diff --git a/image/help.png b/image/help.png new file mode 100644 index 0000000000000000000000000000000000000000..d8acd61a529c3b9b397f0b78286a4f7682b319f4 Binary files /dev/null and b/image/help.png differ diff --git a/image/lexer.png b/image/lexer.png new file mode 100644 index 0000000000000000000000000000000000000000..75f2276f07c77a3664f2752be4766e1978c55352 Binary files /dev/null and b/image/lexer.png differ diff --git a/image/open.png b/image/open.png new file mode 100644 index 0000000000000000000000000000000000000000..4c56f688c5165b5de4e5fe71f36c1d7aa45f2ff4 Binary files /dev/null and b/image/open.png differ diff --git a/image/paste.png b/image/paste.png new file mode 100644 index 0000000000000000000000000000000000000000..5bafb7ccf03858aeb0966734c6f4dba210b15e5c Binary files /dev/null and b/image/paste.png differ diff --git a/image/save.png b/image/save.png new file mode 100644 index 0000000000000000000000000000000000000000..8c01edbcda5cbc3815c509eaea7ea94c50967a56 Binary files /dev/null and b/image/save.png differ diff --git a/src/com/lexer/Analyze.java b/src/com/lexer/Analyze.java new file mode 100644 index 0000000000000000000000000000000000000000..9bd169042242603191e5a7f1b62cdea922a46b44 --- /dev/null +++ b/src/com/lexer/Analyze.java @@ -0,0 +1,306 @@ +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 divide(String str){ + ArrayList list=new ArrayList(); + + String s=""; + char ch; + int i; + int row=1; + + for(i=0;i='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'9'||ch<'0') + break; + } + if(i0){ + if(!selectFileName.endsWith(".txt")){ + selectFileName=selectFileName.concat(".txt"); + } + + file=fileChooser.getCurrentDirectory(); + file=new File(file.getPath().concat(File.separator).concat(selectFileName)); + + if(file.exists()){ + int i=JOptionPane.showConfirmDialog(this, "文件已经存在,是否覆盖?"); + if(i!=JOptionPane.YES_OPTION){ + return; + } + } + + try { + file.createNewFile(); + FileWriter out=new FileWriter(file); + out.write(fileContentTextArea.getText()); + out.close(); + JOptionPane.showMessageDialog(this, "保存成功!"); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + + /** + * 剪切 + */ + public void doCut(){ + fileContentTextArea.cut(); + } + + /** + * 复制 + */ + public void doCopy(){ + int dot1,dot2; + + dot1=fileContentTextArea.getSelectionStart(); + + dot2=fileContentTextArea.getSelectionEnd(); + + if(dot1!=dot2){ + fileContentTextArea.copy(); + JOptionPane.showMessageDialog(null, "复制成功!"); + } + } + + /** + * 黏贴 + */ + public void doPaste(){ + + //调用系统剪切板 + Clipboard clipboard=getToolkit().getSystemClipboard(); + + Transferable content=clipboard.getContents(this); + + try { + if(content.getTransferData(DataFlavor.stringFlavor) instanceof String){ + fileContentTextArea.paste(); + } + } catch (UnsupportedFlavorException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + /** + * 清除文本框内容 + */ + public void doClear(){ + fileContentTextArea.setText(null); + } + + /** + * 词法分析 + */ + public void doTokenizing(){ + + consoleTextArea.setText(null); + ArrayList wlist=new ArrayList(); + ArrayList ulist=new ArrayList(); + + 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; + } + } + + } + + + /** + * 打开使用说明书 + */ + public void doHelp(){ + try { + Runtime.getRuntime().exec("cmd /c start "+System.getProperty("user.dir")+"\\doc\\help.doc") ; + } catch (IOException e1) { + e1.printStackTrace(); + } + } + + /** + * 关于 + */ + public void showAbout(){ + JDialog dialog=new JDialog(); + dialog.setTitle("词法分析器 "); + JLabel label=new JLabel(" 基于Java的C语言词法分析器"); + dialog.add(label); + dialog.setVisible(true); + dialog.setSize(250, 160); + dialog.setResizable(false); + + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = dialog.getSize(); + if (frameSize.height > screenSize.height) { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) { + frameSize.width = screenSize.width; + } + dialog.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); + + } + + /** + * 退出 + */ + public void doExit(){ + + int isExit=JOptionPane.showConfirmDialog(this, "您真的要关闭词法分析器?"); + if(isExit==JOptionPane.YES_OPTION){ + System.exit(0); + }else{ + return; + } + } + + /** + * 点击事件 + */ + @Override + public void actionPerformed(ActionEvent e) { + if(e.getSource()==openMenuItem){ + openFile(); + }else if(e.getSource()==saveMenuItem){ + saveFile(); + }else if(e.getSource()==exitMenuItem){ + doExit(); + }else if(e.getSource()==cutMenuItem){ + doCut(); + }else if(e.getSource()==copyMenuItem){ + doCopy(); + }else if(e.getSource()==pasteMenuItem){ + doPaste(); + }else if(e.getSource()==clearMenuItem){ + doClear(); + }else if(e.getSource()==lexerMenuItem){ + doTokenizing(); + }else if(e.getSource()==helpMenuItem){ + doHelp(); + }else if(e.getSource()==aboutMenuItem){ + showAbout(); + }else if(e.getSource()==openButton){ + openFile(); + }else if(e.getSource()==saveButton){ + saveFile(); + }else if(e.getSource()==lexerButton){ + doTokenizing(); + }else if(e.getSource()==cutButton){ + doCut(); + }else if(e.getSource()==copyButton){ + doCopy(); + }else if(e.getSource()==pasteButton){ + doPaste(); + }else if(e.getSource()==clearButton){ + doClear(); + }else if(e.getSource()==exitButton){ + doExit(); + } + } + + /** + * 构造方法 + */ + public LexerFrame(){ + setTitle("词法分析器 版本 V 1.0"); + + Image logo=Toolkit.getDefaultToolkit().getImage("../lexer/image/lexer.png"); + setIconImage(logo); + + //创建菜单栏 + createMenu(); + + //创建工具栏 + createToolBar(); + + //左面板 + leftPanel=new JPanel(); + + fileContentTextArea=new JTextArea(60,60); + fileContentTextArea.setFont(new Font("隶书",Font.BOLD,12)); + scrollPane1=new JScrollPane(fileContentTextArea); + scrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + scrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane1.getViewport().add(fileContentTextArea); + scrollPane1.getViewport().setPreferredSize(new Dimension(300,530)); + leftPanel.add(scrollPane1); + + //右面板 + rightPanel=new JPanel(); + rightPanel.setLayout(new BorderLayout()); + + + //分析后的内容放在表格里 + + model=new DefaultTableModel(values,title); + table=new JTable(model); + scrollPane2=new JScrollPane(table); + scrollPane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane2.getViewport().add(table); + scrollPane2.getViewport().setPreferredSize(new Dimension(100,100)); + + //控制台 + consoleTextArea = new JTextArea(100,100); + consoleTextArea.setFont(new Font("隶书",Font.BOLD,12)); + scrollPane3=new JScrollPane(consoleTextArea); + scrollPane3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + scrollPane3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); + scrollPane3.getViewport().add(consoleTextArea); + scrollPane3.getViewport().setPreferredSize(new Dimension(300,100)); + + //添加到右部面板 + rightPanel.add("Center",scrollPane2); + rightPanel.add("South",scrollPane3); + + + //创建一个分隔面板 + splitPane=new JSplitPane(); + + //左面板 + splitPane.setLeftComponent(leftPanel); + + //右面板 + splitPane.setRightComponent(rightPanel); + + add("North",toolBar); + add("Center",splitPane); + + //设置运行时窗口的位置 + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = getSize(); + if (frameSize.height > screenSize.height) { + frameSize.height = screenSize.height; + } + if (frameSize.width > screenSize.width) { + frameSize.width = screenSize.width; + } + setLocation((screenSize.width - frameSize.width) / 6, (screenSize.height - frameSize.height) / 6); + + + setSize(800,600); + setResizable(false); + setVisible(true); + } + /** + * 主方法 + * @param args + */ + public static void main(String[] args) { + new LexerFrame(); + } + + +} diff --git a/src/com/lexer/Unidentifiable.java b/src/com/lexer/Unidentifiable.java new file mode 100644 index 0000000000000000000000000000000000000000..937dc49d5d3ba9a2252005920ebdbf0a981609c1 --- /dev/null +++ b/src/com/lexer/Unidentifiable.java @@ -0,0 +1,38 @@ +package com.lexer; + +/** + * + * JavaBean类 + * 不可以识别的标识符 + */ +public class Unidentifiable { + + //不可以识别的标识符行 + int row; + + //获取到的不可以识别的标识符 + String word; + + public Unidentifiable(int row,String word){ + this.row=row; + this.word=word; + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public String getWord() { + return word; + } + + public void setWord(String word) { + this.word = word; + } + + +} diff --git a/src/com/lexer/Word.java b/src/com/lexer/Word.java new file mode 100644 index 0000000000000000000000000000000000000000..4c7a266703700909d19e602e6668cf28e397b27c --- /dev/null +++ b/src/com/lexer/Word.java @@ -0,0 +1,36 @@ +package com.lexer; + +/** + * + * 可以识别的标识符 + */ +public class Word { + + //标识符所在的行 + private int row; + + //获取到的标识符 + private String word; + + public Word(int row,String word){ + this.row=row; + this.word=word; + } + + public int getRow() { + return row; + } + + public void setRow(int row) { + this.row = row; + } + + public String getWord() { + return word; + } + + public void setWord(String word) { + this.word = word; + } + +} \ No newline at end of file