Análisis léxico del principio de compilación en Java

Análisis léxico del principio de compilación en Java


Titulo

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Prerrequisitos

Ingrese las condiciones de terminación (este es el título)

El carácter # indica que la entrada ha finalizado (aquí ingresé el último #)

Reglas de nomenclatura variable

Los nombres de variables solo pueden ser una combinación de letras, números y guiones bajos, y solo pueden comenzar con letras o guiones bajos

Considere la entrada compacta que puede ocurrir al asignar valores

Las asignaciones variables no están separadas por espacios, como

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

Considere la entrada inválida y considérela inválida

  • Al comienzo de un carácter no válido, la cadena antes del espacio no es válida, como
    begin $@djsalfjsdfl1325end= 10 ;
    
    Considerar $@djsalfjsdfl1325end=inválido
  • Error de columna calculada (aparece al principio del número), como
    10*x 写成 10x
    10*x+30y/2;
    10*x+2/30y;
    
    Pensar 10xe 30yinválido

Ideas

Click para ampliar
Inserte la descripción de la imagen aquí

Código

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));
	}
}

Prueba

  • Preguntas de ejemplo
    Inserte la descripción de la imagen aquí
  • Considere la entrada compacta al asignar
    Inserte la descripción de la imagen aquí
  • El nombre de la variable es ilegal
    Inserte la descripción de la imagen aquí
  • Error de columna
    Inserte la descripción de la imagen aquí
318 artículos originales publicados · Me gusta 44 · Visitantes más de 20,000

Supongo que te gusta

Origin blog.csdn.net/qq_43594119/article/details/105371200
Recomendado
Clasificación