Lexical Analysis of Compiling Principle in Java

Lexical Analysis of Compiling Principle in Java


topic

Insert picture description here
Insert picture description here
Insert picture description here

Prerequisites

Enter the termination conditions (this is the title)

The character # indicates that the input is terminated (here I entered the last #)

Variable naming rules

Variable names can only be a combination of letters, numbers, and underscores, and can only start with letters or underscores

Consider compact input that may occur when assigning values

Variable assignments are not separated by spaces, such as

x:=9; 或 x :=9;
规范输入应该是
x := 9;

Consider invalid input and consider it invalid

  • At the beginning of an invalid character, the string before the space is invalid, such as
    begin $@djsalfjsdfl1325end= 10 ;
    
    Consider $@djsalfjsdfl1325end=invalid
  • Calculated column error (appears at the beginning of the number), such as
    10*x 写成 10x
    10*x+30y/2;
    10*x+2/30y;
    
    Think 10xand 30yinvalid

Ideas

Click to enlarge
Insert picture description here

Code

import java.util.Scanner;

/**
 * @author yinglongwu
 */
public class LexicalAnalysis {

	public static void main(String[] args) {
		//获取输入,用空格正则表达式将字符串分割成字符串数组
		String[] sArr = getString().split("\\ ");
		System.out.println("正在进行词法分析,请稍等...");
		//对字符串数组中的每个字符串进行词法分析
		for (int i = 0; i < sArr.length; i++) {
			//System.out.println("正在分析"+sArr[i]);
			analysis(sArr[i]);
		}
		
	}
	
	//获取输入
	public static String getString() {
		Scanner scanner = new Scanner(System.in);
		String s = new String();
		String sIn = new String();
		System.out.println("请输入你要进行词法分析的语句(#表示输入结束):");
		//获取输入,录入空格,不录入回车,不录入最后一个#
		//(sIn=scanner.nextLine())获取字符串输入(每次回车为结束)endsWith("#")字符串是否以#结尾
		while (true) {
			if (!(sIn=scanner.nextLine()).endsWith("#")) {
				s = s + sIn + " ";//如果用户输入回车,用空格表示切断
			}else {
				//s = s + sIn.substring(0,sIn.length()-1);	//不录入最后一个#
				s = s + sIn + " ";//录入最后一个#
				break;
			}
		}
		System.out.println("检测到#输入已结束。");
		return s;
	}
	
	//对每个字符串进行分析
	public static void analysis(String s) {
		if (s.isEmpty()) {
			return;	//字符串为空则结束
		}
		
		//下面三个条件分别是,首字符为字母或下划线,首字符为关键符号,首字符为数字
		if (String.valueOf(s.charAt(0)).matches("[a-zA-z[_]]")) {
			//System.out.println(s+"的首字符为字母或下划线");
			letterAnalysis(s);
		} else if (String.valueOf(s.charAt(0)).matches("[+-[*]/:=<>()#;]")) { //*为正则表达式中的特殊字符所以需要单独写,否则报异常
			//System.out.println(s+"的首字符为关键符号");
			charAnalysis(s);
		} else if (String.valueOf(s.charAt(0)).matches("[0-9]")){
			//System.out.println(s+"的首字符为数字");
			numAnalysis(s);
		} else {
			System.out.println("(无效字符串,"+s+")");
		}
	}
	
	//首字符为字母或下划线的分析方法
	public static void letterAnalysis(String s) {
		switch (s) {
		case "begin":
			System.out.println("(1,begin)");
			break;
		case "if":
			System.out.println("(2,if)");
			break;
		case "then":
			System.out.println("(3,then)");
			break;
		case "while":
			System.out.println("(4,while)");
			break;
		case "do":
			System.out.println("(5,do)");
			break;
		case "end":
			System.out.println("(6,end)");
			break;
		default: //不是关键字
			boolean t = false;//默认没有非字母、数字、下滑线的字符
			int n = s.length();//记录符号下标,默认没有符号,所以为长度
			//判断是否有符号
			for (int i = 0; i < s.length(); i++) {
				if (s.substring(i, i+1).matches("[+-[*]/:=<>();]")) {
					n = i; //记录下标
					break;
				}
			}
			//对符号前的每一个字符判断是否有非法字符
			for (int i = 0; i < n; i++) {
				if (!s.substring(i,i+1).matches("[a-zA-z[_]]")) {
					t = true;	//如果含有非法字符
					System.out.println("(无效字符串,"+s.substring(0, n)+")");
					break;
				}
			}
			//如果没有非法字符,输出结果
			if (!t) {
				System.out.println("("+10+","+"'"+s.substring(0, n)+"'"+")");				
			}
			//符号后的继续判断
			analysis(s.substring(n));
			break;
		}
	}
	
	//首字符为符号的分析方法
	public static void charAnalysis(String s) {
		switch (s) {
		case "+":
			System.out.println("(13,+)");
			break;
		case "-":
			System.out.println("(14,-)");
			break;
		case "*":
			System.out.println("(15,*)");
			break;
		case "/":
			System.out.println("(16,/)");
			break;
		case ":":
			System.out.println("(17,:)");
			break;
		case ":=":
			System.out.println("(18,:=)");
			break;
		case "<":
			System.out.println("(20,<)");
			break;
		case "<>":
			System.out.println("(21,<>)");
			break;
		case "<=":
			System.out.println("(22,<=)");
			break;
		case ">":
			System.out.println("(23,>)");
			break;
		case ">=":
			System.out.println("(24,>=)");
			break;
		case "=":
			System.out.println("(25,=)");
			break;
		case ";":
			System.out.println("(26,;)");
			break;
		case "(":
			System.out.println("(27,()");
			break;
		case ")":
			System.out.println("(28,))");
			break;
		case "#":
			System.out.println("(0,#)");
			break;
		default: //不是关键字符
			boolean t = false;
			for (int i = 1; i < s.length(); i++) {
				//如果第二个字符满足双字符条件
				if (s.substring(i, i+1).matches("[=>]")) {
					t = true;
					//截取第二个字符前的字符串调用自身进行判断
					charAnalysis(s.substring(0, i+1));
					//第二个字符后的继续判断
					analysis(s.substring(i+1));
					break;
				}
			}
			if (!t) {//如果第二个字符不满足双字符条件
				//截取第一个字符前的字符串调用自身进行判断
				charAnalysis(s.substring(0, 1));
				//第一个字符后的继续判断
				analysis(s.substring(1));
			}
			break;
		}
	}
	
	//首字符为数字的分析方法
	public static void numAnalysis(String s) {
		boolean t = false; //标记是否有字母
		int n = s.length(); //记录符号下标,这里的意思是不存在符号
		//对每一个字符进行判断是否为符号
		for (int i = 0; i < s.length(); i++) {
			//如果有符号
			if (s.substring(i, i+1).matches("[+-[*]/:=<>()#;]")) {
				n = i; //记录符号的下标
				break;
			}
		}
		//对关键符号前的每一个字符判断是否有非数字
		for (int i = 0; i < n; i++) {
			if (!s.substring(i,i+1).matches("[0-9]")) {
				t = true;	//如果含有字母
				System.out.println("(无效字符串,"+s.substring(0, n)+")");
				break;
			}
		}
		//符号前没有字母的输出结果
		if (!t) {
			System.out.println("("+11+","+s.substring(0, n)+")");
		}
		//符号后的继续分析
		analysis(s.substring(n));
	}
}

test

  • Example questions
    Insert picture description here
  • Consider compact input when assigning
    Insert picture description here
  • Variable name is invalid
    Insert picture description here
  • Column error
    Insert picture description here
Published 318 original articles · Like 44 · Visitors 20,000+

Guess you like

Origin blog.csdn.net/qq_43594119/article/details/105371200