语法分析器

package com.analysis4;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

/**
*1.保留字
*2.运算符
*3.界符
*/

public class Demo {

public static int baoliuzi = 0;
public static int yunsuanfu = 0;
public static int biaoshifu = 0;
public static int jiefu = 0;
public static int elsewords = 0;

//将txt文件转为数组
public  String txt2String(File file) throws IOException
{
	StringBuilder result =new StringBuilder();
	try {
		BufferedReader br= new BufferedReader(new FileReader(file));
		String s=null;
		while((s=br.readLine())!=null){
			result.append(System.lineSeparator()+s);
		}
		br.close();
	} catch (FileNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	return result.toString();
}

//对文本进行预处理
public  char[] preTreatment(char[] sourcefile)
{
	char []afterfile = new char[10000];
	int index=0;
	if(sourcefile.length!=0)
	{
		for(int i=0;i='a'&&c<='z')||(c>='A'&&c<'Z'))
	{
		return true;
	}
	else
		return false;
}

//判断是否为保留字,并返回编号
public int isReserve(String s,String []reserve)
{
	int index=-1;
	for(int i=0;i='0'&&c<='9')
	{
		return true;
	}
	else
		return false;
}


public static void main(String[] args) throws IOException {
	// TODO Auto-generated method stub
	//保留字
	String []reserve={"if","else","while","throw","this","int","String","char","double","float","this",
			"static","public","private","default","switch","catch","void","try","return"};//0~99
	//运算符
	String []operator={"+","-","*","/","++","--","==","!=",">","<",">=",
			"<=","&&","||","!","&","|","^","~","<<",">>",">>>","+=","="};//110~149
	//界符
	char []divide={'<','>','(',')','{','}','[',']','\'','"',',',';','?','/','\\',':','.'};//150~无穷
	Demo la=new Demo();
	//源代码的txt文件
	File file=new File("D://1.txt");
	//将txt格式的源文件放入sourcefile的字符数组中
	String source=la.txt2String(file);
	char sourcefile[] = source.toCharArray();  
	//将源代码进行预处理,去掉注释和换行符
	char afterfile[]=la.preTreatment(sourcefile);
	//index记录源代码的字符数组扫描到的数组下标
	int index=0;
	//temp用于存储临时的字符串
	String temp="";
	//当未扫描到终结符则一直往下扫描
	while(afterfile[index]!='\0'){
		//当开头为字母时,可能为保留字或是标识符
		if(la.isLetter(afterfile[index]))
		{
			temp+=afterfile[index];
			//当下一个字符不为字母或数字,则停止扫描,并将扫描结果存入temp
			while(la.isLetter(afterfile[index+1])||la.isDigit(afterfile[index+1]))
			{
				index++;
				temp+=afterfile[index];
			}
			//将temp与保留字数组匹配,匹配成功即为保留字,否则为标识符
			if(la.isReserve(temp, reserve)!=-1) {
				System.out.println("保留字:("+la.isReserve(temp, reserve)+","+temp+")");
				baoliuzi++;
			}
			else {
				System.out.println("标识符:("+100+","+temp+")");
				biaoshifu++;
			}
		}
		//当开头为数字时,可能为整数或小数
		else if(la.isDigit(afterfile[index]))
		{
			temp+=afterfile[index];
			while(la.isDigit(afterfile[index+1]))
			{
				index++;
				temp+=afterfile[index];
			}
			//若在数字后有小数点,继续判断
			if(afterfile[index+1]=='.')
			{
				index++;
				//小数点后无数字,检测出错
				if(!la.isDigit(afterfile[index+1])){
					System.out.println("此处有误,小数点后无数字");
					temp="";
					break;
					}
				//小数点后有数字,检测为小数
				else
				{
					temp+=afterfile[index];
					while(la.isDigit(afterfile[index+1]))
					{
						index++;
						temp+=afterfile[index];
					}
				}
				System.out.println("小数常数:("+102+","+temp+")");
			}
			//无小数点,检测为整数
			else
			{
				System.out.println("整数常数:("+100+","+temp+")");
			}
		}
		//既不是数字也不是字母也不是空格,则为界符或运算符,跳过空格
		else if(afterfile[index]!=' ')
		{
			temp+=afterfile[index];
			/*由于界符只有一个字符长度,则temp放入一个字符后直接开始匹配界符数组,
			 * 匹配成功则continue循环,匹配失败则继续扫描
			*/
			if(la.isDivide(temp, divide)!=-1)
			{
				System.out.println("界符:("+la.isDivide(temp, divide)+","+temp+")");
				temp="";
				index++;
				jiefu++;
				continue;
			}
			//判断是否为运算符
			else
			{
				//若下一个字符也是符号类型则加入temp
				while((la.isDivide(afterfile[index+1]+"", divide)==-1)&&(la.isDigit(afterfile[index+1])==false)
						&&(la.isLetter(afterfile[index+1])==false))
				{
					index++;
					temp+=afterfile[index];
				}
				//与运算符数组匹配,匹配成功,则为运算符,失败,则可能出现了检测不了的字符。
				if(la.isOperator(temp, operator)!=-1) {
					System.out.println("运算符:("+la.isOperator(temp, operator)+","+temp+")");
					yunsuanfu++;
				}
				else {
					System.out.println(temp+"无法识别,可能为中文字符或者此字符暂未被收录......");
					elsewords++;
				}
			}
			
		}
		temp="";
		index++;
	}
	System.err.println("保留字的个数为:"+baoliuzi);
	System.err.println("标识符的个数为"+biaoshifu);
	System.err.println("界符的个数为"+jiefu);
}

}

//保留字 标识符 ( 运算符) 界符

//public class Demo{
// public static void main(String[] args){
// System.out.println(“Hello World!!!”);
// }
//}


package com.analysis3;

import java.util.Stack;

public class GramerAnasys {

//加入同步符号的LL(1)分析表
private  String [][] analysisTable = new String[][]{
		{"TZ","","","TZ","synch","synch"},
		{"","+TZ","","","ε","ε"},
		{"FY","synch","","FY","synch","synch"},
		{"","ε","*FY","","ε","ε"},
		{"i","synch","synch","(E)","synch","synch"}
};

//存储终结符
private String [] VT = new String[]{"i","+","*","(",")","#"};

//存储终结符
private String [] VN = new String[]{"E","Z","T","Y","F"};
//输入串

private StringBuilder strToken = new StringBuilder("i+i*i+i*i");

//分析栈
private Stack stack = new Stack();

//a保存从输入串中读取的一个输入符号,当前符号
private String a = null;

//X中保存stack栈顶符号
private String X = null;

//flag标志预测分析是否成功
private boolean flag = true;

//记录输入串中当前字符的位置
private int cur = 0;

//记录步数
private int count = 0;

//输出语法规则
protected void print(){
	System.out.printf("E→TZ \n"+"Z→+TZ|ε \n"+"T→FY \n"+"Y→*FY|ε \n"+"F→(E)|i \n");
	
}
//初始化
protected void init(){
	strToken.append("#");
	stack.push("#");
	System.out.printf("%-9s %-38s %6s %-20s\n","步骤 ","符号栈 ","        输入串 ","    所用产生式 ");
	stack.push("E");
	curCharacter();
	System.out.printf("%-6d %-20s %6s \n",count,stack.toString(),strToken.substring(cur, strToken.length()));
}

//读取当前栈顶符号
protected String stackPeek(){
	X = stack.peek();
	return X;
}

//返回输入串中当前位置的字母
private String curCharacter(){
		a = String.valueOf(strToken.charAt(cur));
	return a;
}

//判断X是否是终结符
protected boolean XisVT(){
	for(int i = 0 ; i < (VT.length - 1); i++){
		if(VT[i].equals(X)){
			return true;
		}
	}
	return false;
}

//查找X在非终结符中分析表中的横坐标
protected String VNTI(){
	int Ni = 0 , Tj = 0;
	for(int i = 0 ; i < VN.length ; i++){
		if(VN[i].equals(X)){
			Ni = i;
		}
	}
	for(int j = 0 ; j < VT.length ; j++){
		if(VT[j].equals(a)){
			Tj = j;
		}
	}
	return analysisTable[Ni][Tj];
}

//判断M[A,a]={X->X1X2...Xk}
//把X1X2...Xk推进栈
//X1X2...Xk=ε,不推什么进栈
protected boolean productionType(){
	if(VNTI() != ""){
		return true;
	}
	return false;
}

//推进stack栈
protected void pushStack(){
	stack.pop();
	String M = VNTI();
	String ch;
	for(int i = (M.length() -1) ; i >= 0 ; i--){
		ch = String.valueOf(M.charAt(i));
		stack.push(ch);
	}
	System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,M);
}

//总控程序
protected void totalControlProgram(){
	while(flag == true){
		stackPeek();
		if(XisVT() == true){
			if(X.equals(a)){
				cur++;
				a = curCharacter();
				stack.pop();
				System.out.printf("%-6d %-20s %6s \n",(++count),stack.toString(),strToken.substring(cur, strToken.length()));
			}else{
				ERROR();
			}
		}else if(X.equals("#")){
			if(X.equals(a)){
				flag = false;
			}else{
				ERROR();
			}
		}else if(productionType() == true){
			if(VNTI().equals("synch")){
				ERROR();
			}else if(VNTI().equals("ε")){
				stack.pop();
				System.out.printf("%-6d %-20s %6s %-1s->%-12s\n",(++count),stack.toString(),strToken.substring(cur, strToken.length()),X,VNTI());
			}else{
				pushStack();
			}
		}else{
			ERROR();
		}
	}
}

//出现错误
protected void ERROR(){
	System.out.println("输入串出现错误,无法进行分析!!!");
	System.exit(0);
}

//打印存储分析表
protected void printf(){
	if(flag == false){
		System.err.println("输入串正确!!!");
	}else {
		System.out.println("输入串错误!!!");
	}
	
}

public static void main(String[] args) {
	
	GramerAnasys gramerAnasys= new GramerAnasys();
	gramerAnasys.print();
	gramerAnasys.init();
	gramerAnasys.totalControlProgram();
	gramerAnasys.printf();
}

}

你可能感兴趣的:(java)