前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >词法分析程序

词法分析程序

作者头像
SuperHeroes
发布2018-05-30 17:43:34
1K0
发布2018-05-30 17:43:34
举报
文章被收录于专栏:云霄雨霁云霄雨霁

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

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

取词阶段:

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

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

词法分析伪代码如下:

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

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

读写文件操作:

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

代码语言:javascript
复制
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();
	}
}

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.12.11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档