博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
编译原理--词法分析程序
阅读量:6856 次
发布时间:2019-06-26

本文共 4657 字,大约阅读时间需要 15 分钟。

hot3.png

1  算法思想

程序分为4个关键方法,用户输入方法,读、写文件方法以及词法分析方法。其中词法分析方法是程序的核心。

词法分析程序主要分为两个部分,第一是取词,第二是分析。

1.1  取词阶段

依次取字符串的每一个字符,遇到空字符时停下,将取到的字符合并成一个字符串,送去进行分析阶段。

1.2  分析阶段

程序先构建有关键字数组、分隔符数组和运算符数组,通过将取词阶段送来的字符串与各数组中元素进行比较,将字符串分类到相应的类别数组中保存。

1.3  伪代码

While (源码字符串没有取完){        Getchar(获取一个非空字符);        If (是字母) {               拼接到目标字符串后;               While (继续获取字符直到空字符出现);               If (目标字符串是关键字)     记录为关键字;               Else  记录为标识符;        }Else If (是数字){               While(循环获取直到非数字);               记录为常数;       }Else if (是运算符){               标记为运算符;       }Else(是分隔符){               标记为分隔符;      }}

2  算法实现

具体实现时,分析方法主要实现伪代码的逻辑,其中一些具体操作比如判断是否为关键字、运算符等都另写方法实现,分析方法通过调用这些方法实现具体功能。

读写文件操作:分析方法基于缓冲区操作,用户输入的源码也是暂存缓冲区,等分析方法完成后,直接将缓冲区的源码压入文件即可。

import java.io.File;import java.util.Scanner;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;/** * 词法分析程序 * @author 霍淇滨 * */public class Analyzer {	private String keyWords[] = { "auto", "double", "int", "struct", "break", "else",			"long", "switch", "case", "enum", "register", "typedef", "char", "extern",			"return", "union", "const", "float", "short", "unsigned", "continue",			"for", "signed", "void", "default", "goto", "sizeof", "volatile", "do", "if",			"while", "static"}; // 关键字数组	private char operators[] = { '+', '-', '*', '/', '=', '>', '<', '&' }; // 运算符数组	private char separators[] = { ',', ';', '{', '}', '(', ')', '[', ']', '_',			':', '、', '.', '"' }; // 分隔符数组	private String url;	private StringBuffer buffer = new StringBuffer(); // 缓冲区	private char ch; // 字符变量,存放最新读进的源程序字符	private static int i = 0;//下标,存放遍历到的源码位置	private String words; // 存放构成单词符号的字符串	public Analyzer(String yrl) {		this.url = url;	}	/**	 * 接受用户输入	 * @return	 */	public String input(){		String text = "";		System.out.println("输入源码:");		Scanner sc = new Scanner(System.in);		String n = sc.nextLine();		while(!n.equals("$")){			buffer.append(n);//加入到缓冲区			n = sc.nextLine();		}		System.out.println(text);		return text;	}		/**	 * 将用户输入保存为文件	 * @param text	 * @throws IOException	 */	public void writeTxt() throws IOException{		File writename = new File(".\\output.txt"); // 相对路径,如果没有则要建立一个新的output.txt文件          writename.createNewFile(); // 创建新文件          BufferedWriter out = new BufferedWriter(new FileWriter(writename));            out.flush(); // 把缓存区内容压入文件          out.close(); // 最后记得关闭文件     }		/**	 * 将下一个输入字符读到ch中,搜索指示器前移一个字符	 */	public void getChar() {		ch = buffer.charAt(i);		i++;	}	/**	 * 检查ch中的字符是否为空白,若是则调用getChar() 直至ch中进入一个非空白字符	 */	public void getContinue() {		while (Character.isSpaceChar(ch))			getChar();	}	/**	 * 将ch连接到words之后	 */	public void concat() {		words += ch;	}	/**	 * 判断字符是否为字母	 */	boolean isLetter() {		return Character.isLetter(ch);	}	/**	 * 判断字符是否为数字	 */	boolean isDigit() {		return Character.isDigit(ch);	}	/**	 * 判断单词是否为关键字	 */	public boolean isKeyWord() {		for (int i = 0; i < keyWords.length; i++) {			if(keyWords[i].equals(words))return true;		}		return false;	}	/**	 * 判断是否为运算符	 */	public boolean isOperator() {		for (int i = 0; i < operators.length; i++) {			if(ch == operators[i]) return true;		}		return false;	}	/**	 * 判断是否为分隔符	 */	public boolean isSeparators() {		for (int i = 0; i < separators.length; i++) {			if (ch == separators[i]) return true;		}		return false;	}	/**	 * 将源程序读入到缓冲区中	 * @throws IOException 	 */	public void readFile() throws IOException {		FileReader fis = new FileReader(this.url);		BufferedReader br = new BufferedReader(fis);		String temp = null;		while ((temp = br.readLine()) != null) {			buffer.append(temp);		}	}	/**	 * 词法分析	 */	public void analyse() {		words = "";		while (i < buffer.length()) {			getChar();			getContinue();			if (isLetter()) { // 如果ch为字母				while (isLetter() || isDigit()) {					concat();					getChar();				}				i--;ch = ' ';				if (isKeyWord()) { // 如果是为关键字					System.out.println("(关键字,"+words+")");				} else { // 否则是标识符					System.out.println("(标识符,"+words+")");				}				words = "";			} else if (isDigit()) { //如果为数字				while (isDigit()) {					concat();					getChar();				}				i--;ch = ' ';				System.out.println("(常数,"+words+")");				words = "";			} else if (isOperator()) { // 如果是运算符				System.out.println("(运算符,"+ch+")");			} else if (isSeparators()) { // 如果是分隔符				System.out.println("(分隔符,"+ch+")");			}		}	}		/**	 * 测试函数	 * @param args	 * @throws IOException	 */	public static void main(String[] args) throws IOException {		Analyzer ans = new Analyzer("./src/input.txt");//文件路径		//源文件测试//		ans.readFile();//		ans.analyse();		//用户输入测试		ans.input();		ans.analyse();		ans.writeTxt();	}}

程序中未实现注释过滤功能。

转载于:https://my.oschina.net/HuoQibin/blog/1587815

你可能感兴趣的文章
JavaScript 获取当前时间戳
查看>>
基础汇编指令
查看>>
C语言钙片
查看>>
《AjaxPro 教程系列》 一、环境配置和经典用例AutoComplete功能的实现
查看>>
spring+quartz的任务调度
查看>>
ActiveMq 总结(一)
查看>>
XJOI网上同步测试DAY14 T2
查看>>
在SGD中发布Oracle Linux 7 的Xfce桌面环境
查看>>
使用DD_belatedPNG让IE6支持PNG透明图片
查看>>
LOJ6284 数列分块入门8(分块)
查看>>
深入浅出Mybatis系列(二)---配置简介(mybatis源码篇)
查看>>
delphi中 panel如何在Form实现鼠标移动拖放
查看>>
天天爱跑步——树上差分
查看>>
Instll meld in windows
查看>>
一些量化策略评估指标
查看>>
Text selection in div(contenteditable) when double click
查看>>
K3卸载和清理
查看>>
开源库
查看>>
CPU线程 和 Java线程
查看>>
ClassLoader
查看>>