Java 实现《编译原理》简单词法分析功能
2019-06-13 23:19
1936 查看
Java 实现《编译原理》简单词法分析功能
简易词法分析功能
要求及功能
(1)读取一个 txt 程序文件(最后的 # 作为结束标志,不可省去)
{ int a, b; a = 10; if(a>=1){ b = a + 20; } }
(2)词法识别分析表
单词类别|单词自身值|内部编码
-|-|-
关键字| int、for、while、do、return、break、continue| 1
标识符| 除关键字外的以字母开头,后跟字母、数字的字符序列| 2
常数| 无符号整型数| 3
运算符| +、-、*、/、>、<、=、>=、<=、!=| 4
界限符| ,、;、{、}、(、)| 5
换行符|\n| 6
(3)输出结果:
(5,{) (6,\n) (1,int) (2,a) (5,,) (2,b) (5,;) (6,\n) (2,a) (4,=) (3,10) (5,;) (6,\n) (2,if) (5,() (2,a) (4,>=) (3,1) (5,)) (5,{) (6,\n) (2,b) (4,=) (2,a) (4,+) (3,20) (5,;) (6,\n) (5,}) (6,\n) (5,}) (6,\n) (0,#)
并保存成新的 txt 文件
编程实现
(1)程序文件目录:
(2)Word.java 文件:
package com.java997.analyzer.lexical; /** * <p> * 表示识别后的词实体类 * * @author XiaoPengwei * @since 2019-06-13 */ public class Word { /** * 种别码 */ private int typeNum; /** * 扫描得到的词 */ private String word; public int getTypeNum() { return typeNum; } public void setTypeNum(int typeNum) { this.typeNum = typeNum; } public String getWord() { return word; } public void setWord(String word) { this.word = word; } }
(3)CodeScanner.java 文件:
package com.java997.analyzer.lexical; /** * <p> * 字符扫描 * * @author XiaoPengwei * @since 2019-06-13 */ public class CodeScanner { private static String _KEY_WORD_END = "end string of string"; private int charNum = 0; private Word word; private char[] input = new char[255]; private char[] token = new char[255]; private int p_input = 0; private int p_token = 0; private char ch; /** * 关键字数组 */ private String[] rwtab = {"int", "if", "while", "do", "return", "break", "continue", _KEY_WORD_END}; /** * 逻辑运算数组 */ private String[] logicTab = {"==",">=","<=","!=", _KEY_WORD_END}; public CodeScanner(char[] input) { this.input = input; } /** * 取下一个字符 * * @return */ public char m_getch() { if (p_input < input.length) { ch = input[p_input]; p_input++; } return ch; } /** * 如果是标识符或者空白符就取下一个字符 */ public void getbc() { while ((ch == ' ' || ch == '\t') && p_input < input.length) { ch = input[p_input]; p_input++; } } /** * 把当前字符和原有字符串连接 */ public void concat() { token[p_token] = ch; p_token++; token[p_token] = '\0'; } /** * 回退一个字符 */ public void retract() { p_input--; } /** * 判断是否为字母 * * @return boolean * @author XiaoPengwei */ public boolean isLetter() { return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'; } /** * 判断是否为数字 * * @return boolean * @author XiaoPengwei */ public boolean isDigit() { return ch >= '0' && ch <= '9'; } /** * 查看 token 中的字符串是否是关键字,是的话返回关键字种别编码,否则返回 2 * * @return */ public int isKey() { int i = 0; while (rwtab[i].compareTo(_KEY_WORD_END) != 0) { if (rwtab[i].compareTo(new String(token).trim()) == 0) { return i + 1; } i++; } return 2; } /** * 可能是逻辑预算字符 * * @return */ public Boolean isLogicChar() { return ch == '>' || ch == '<'|| ch == '='|| ch == '!'; } /** * 查看 token 中的字符串是否是逻辑运算符,是的话返回关键字种别编码,否则返回 2 * * @return */ public int isLogicTab() { int i = 0; while (logicTab[i].compareTo(_KEY_WORD_END) != 0) { if (logicTab[i].compareTo(new String(token).trim()) == 0) { return i + 1; } i++; } return 4; } /** * 能够识别换行,单行注释和多行注释的 * 换行的种别码设置成30 * 多行注释的种别码设置成31 * * @return */ public Word scan() { token = new char[255]; Word myWord = new Word(); myWord.setTypeNum(10); myWord.setWord(""); p_token = 0; m_getch(); getbc(); if (isLetter()) { while (isLetter() || isDigit()) { concat(); m_getch(); } retract(); myWord.setTypeNum(isKey()); myWord.setWord(new String(token).trim()); return myWord; } else if (isLogicChar()) { while (isLogicChar()) { concat(); m_getch(); } retract(); myWord.setTypeNum(4); myWord.setWord(new String(token).trim()); return myWord; } else if (isDigit()) { while (isDigit()) { concat(); m_getch(); } retract(); myWord.setTypeNum(3); myWord.setWord(new String(token).trim()); return myWord; } else { switch (ch) { //5 case ',': myWord.setTypeNum(5); myWord.setWord(","); return myWord; case ';': myWord.setTypeNum(5); myWord.setWord(";"); return myWord; case '{': myWord.setTypeNum(5); myWord.setWord("{"); return myWord; case '}': myWord.setTypeNum(5); myWord.setWord("}"); return myWord; case '(': myWord.setTypeNum(5); myWord.setWord("("); return myWord; case ')': myWord.setTypeNum(5); myWord.setWord(")"); return myWord; //4 case '=': myWord.setTypeNum(4); myWord.setWord("="); return myWord; case '+': myWord.setTypeNum(4); myWord.setWord("+"); return myWord; case '-': myWord.setTypeNum(4); myWord.setWord("-"); return myWord; case '*': myWord.setTypeNum(4); myWord.setWord("*"); return myWord; case '/': myWord.setTypeNum(4); myWord.setWord("/"); return myWord; case '\n': myWord.setTypeNum(6); myWord.setWord("\\n"); return myWord; case '#': myWord.setTypeNum(0); myWord.setWord("#"); return myWord; default: concat(); myWord.setTypeNum(-1); myWord.setWord("ERROR INFO: WORD = \"" + new String(token).trim() + "\""); return myWord; } } } }
(4)MainAnalyzer.java 文件:
package com.java997.analyzer.lexical; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.Scanner; /** * <p> * 执行主程序 * * @author XiaoPengwei * @since 2019-06-13 */ public class MainAnalyzer { private File inputFile; private File outputFile; private String fileContent; private ArrayList<Word> list = new ArrayList<>(); /** * 构造方法 * * @param input * @param output * @author XiaoPengwei */ public MainAnalyzer(String input, String output) { //实例化输入文件 inputFile = new File(input); //实例化输出文件 outputFile = new File(output); } /** * 从指定的 txt 文件中读取源程序文件内容 * * @return java.lang.String */ public String getContent() { StringBuilder stringBuilder = new StringBuilder(); try (Scanner reader = new Scanner(inputFile)) { while (reader.hasNextLine()) { String line = reader.nextLine(); stringBuilder.append(line + "\n"); System.out.println(line); } System.out.println("Successful reading of files:" + inputFile.getName()); } catch (FileNotFoundException e) { e.printStackTrace(); } return fileContent = stringBuilder.toString(); } /** * 然后扫描程序,在程序结束前将扫描到的词添加到 list 中 * 最后把扫描结果保存到指定的文件中 * * @param fileContent * @return void */ public void analyze(String fileContent) { int over = 1; Word word = new Word(); //调用扫描程序 CodeScanner scanner = new CodeScanner(fileContent.toCharArray()); System.out.println("The result:"); while (over != 0) { word = scanner.scan(); System.out.println("(" + word.getTypeNum() + "," + word.getWord() + ")"); list.add(word); over = word.getTypeNum(); } saveResult(); } /** * 将结果写入到到指定文件中 * 如果文件不存在,则创建一个新的文件 * 用一个 foreach 循环将 list 中的项变成字符串写入到文件中 */ public void saveResult() { //创建文件 if (!outputFile.exists()) { try { outputFile.createNewFile(); } catch (IOException e1) { e1.printStackTrace(); } } //写入文件 try (Writer writer = new FileWriter(outputFile)) { for (Word word : list) { writer.write("(" + word.getTypeNum() + " ," + word.getWord() + ")\n"); } } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { //注意输入文件路径/名称必须对, 输出文件可以由程序创建 MainAnalyzer analyzer = new MainAnalyzer("D:\\analyzer\\src\\main\\java\\com\\java997\\analyzer\\lexical\\input.txt", "D:\\analyzer\\src\\main\\java\\com\\java997\\analyzer\\lexical\\output.txt"); analyzer.analyze(analyzer.getContent()); } }
(5)input.txt 文件:
{ int a, b; a = 10; if(a>=1){ b = a + 20; } } #
执行测试
相关文章推荐
- java实现屏幕共享功能实例分析
- java在线聊天项目 实现基本聊天功能后补充的其他功能详细需求分析 及所需要掌握的Java知识基础 SWT的激活方法,swt开发包下载,及破解激活码
- JAVA中用动态代理类实现记忆功能
- JAVA中用动态代理类实现记忆功能(一)
- 利用java实现浏览器功能
- 经典java转码程序,有备无患!实现和 jdk/bin/native2ascii.exe 同样的功能
- 用Java事件处理机制实现录制回放功能
- Java实现随机验证码功能实例
- 如何在Java应用程序中实现copy图像功能
- 用java 实现 oracle的自动备份和恢复功能。
- JAVA中用动态代理类实现记忆功能(一)
- 在JAVA应用程序中如何实现FTP的功能
- 实现编辑器的Undo Redo功能用Java来
- 用java实现msn功能
- JXTA Platform JAVA参考实现源代码分析系列文章(2)
- 蔡军生先生第二人生的源码分析(4)Log调试功能的实现
- JAVA 实现各种排序算法和复杂度分析1
- 物理隔离功能及实现技术分析
- 快速排序方法Java实现与分析
- java实现发送电子邮件功能