基于Java构造词法分析器+语法分析器完成编译原理实验

功能概述:
根据简单语言的词法和各单词符号种别码表,编写C或C++语言源程序,实现针对该简单语言的词法分析器,然后构造语法分析器。

(1)文件struct.java定义单词符号的二元组结构、全局变量、关键字表的结束标志等。
(2)文件funs.java实现词法扫描算法scanner及其所需的各种基本操作算法。
(3)文件text.java调用scanner算法,实现词法分析器的功能。

所用知识:1.词法分析 2.语法分析
开发环境:Eclipse 2021 jdk1.8

//struct.java 将属性封装,可以用Java自带的集合ArrayList<>
package text;
public class struct {
	private String word;
	private int num;
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getWord() {
		return word;
	}
	public void setWord(String word) {
		this.word = word;
	}
	
}

//funs.java 完成主要功能
package text;
import java.util.Scanner;
public class funs {
	
	String keys[]= { "begin","if" ,"then","while","do","end","game over"};
	int p_input=0,p_token=0,over=1,k=0,r=0,r1=0;
	String input;
	char b[]= new char[220],a[];
	String e[]= new String[220];
	int e1[]=new int[220];
	char ch;
	
	public void fun() { 
		
		@SuppressWarnings("resource")
		Scanner in=new Scanner(System.in);
		System.out.print("输入字符串#号结束:");
		input =in.nextLine();
		b=input.toCharArray();a=new char[b.length+1];
		for(int u=0;u<=b.length-1;u++) 
			a[u]=b[u];
		System.out.print(input+"\n"); 
		struct s=new struct();
		while(over<1000&&over!=-1) { 
				s=scanner(a[p_input]); 
				if(over<1000&&s.getNum()!=0) {
					e[r1]=s.getWord(); 
					e1[r1]=s.getNum();
					r1++;
					System.out.print("("+s.getNum()+","+s.getWord()+") ");
					}
				over=s.getNum();
		}
	}
	
	public struct scanner(char a) {
		
		struct myword=new struct();
		char token[]= new char[220];
		p_token=0;
		a=get_ch(); //
		String s="";int m=0;
		if(numbers(a)==1) {
			while(numbers(a)==1) {
				merge(token);
				a=get_ch();  
				m++;
			}
			restre(); 
			myword.setNum(11); 
			for(int i=0;i<m;i++) s+=token[i];
			myword.setWord(s);
			return myword;}
		
		else if(letters(a)==1) {
			while(letters(a)==1||numbers(a)==1) {		
				m++;
				merge(token);  
				a=get_ch();
			}
			restre(); 
			for(int i=0;i<m;i++) s+=token[i];
			myword.setNum(key(s));
			myword.setWord(s);
			return myword;
		}
		else switch (a) {
			case '+': 
				myword.setNum(13);  
				myword.setWord("+");
				return myword;
			case '-':
					myword.setNum(14); 
					myword.setWord("-");
					return myword; 
			case '*':
					myword.setNum(15); 
					myword.setWord("*");
					return myword;
				
			case '/':
				myword.setNum(16); 
				myword.setWord("/");
				return myword;
				
			case ';':
				myword.setNum(26); 
				myword.setWord(";");
				return myword;
			case ':':
				a=get_ch();
				if(a=='='){ 
					myword.setNum(18); 
					myword.setWord(":=");
				}
				else {
				myword.setNum(17); 
				myword.setWord(":");}
				return myword;
			
			case '(':
				myword.setNum(27);  
				myword.setWord("(");
				return myword;
				
			case ')':
				myword.setNum(28); 
				myword.setWord(")");
				return myword;
				
			case '#':
				myword.setNum(0); 
				myword.setWord("#");
				return myword;
				
			case '=':
				myword.setNum(25); 
				myword.setWord("=");
				return myword;
			case '>':  
				a=get_ch();
		        if (a == '=')
		        {
		        	myword.setNum(24); 
		        	myword.setWord(">=");
		            return(myword);
		        }
		        myword.setNum(23);
		        myword.setWord(">");
		        return(myword);      
		    case '<':   
		    	a=get_ch();
		        if (ch == '=')
		        {
		        	myword.setNum(22); 
		        	myword.setWord("<=");
		            return(myword);
		        }
		        myword.setNum(20);
		        myword.setWord("<");
		        return(myword);
			case '\0':
				myword.setNum(1000); 
				myword.setWord("OVER");
				return myword;	
			case ' ':
				get_sp();
				return myword;	
			default:
				myword.setNum(-1);
				myword.setWord("ERRO");
				return myword;
				
				}
		}

	
	public char get_ch() {//获取当前字符
		ch=a[p_input];
		p_input++;  
		return ch;
	}
	public void restre() {//往回走一个
		p_input--; 
	}
		
	public  void get_sp() {//去掉空格
		while(ch==' ' ||ch==10){
			//if(p_input<=a.length-1) {
			ch=a[p_input];
			p_input++;		//}
		}p_input--; 
	}
	 
	public void merge(char[] token) {//合并
		
		token[p_token]=ch;
		p_token++;
		
	}
	public int letters(char a) {//识别数字
		if(a<='Z'&&a>='A'||a<='z'&&a>='a')  return 1;
		return 0;
	}
	public int numbers(char a) {//识别字母		
		if(a>='0'&&a<='9') return 1;
		return 0;
	}
	public int key(String s) {//识别关键字
		int r=0,i;
		for(i=0;i<=5;i++) 
			if(keys[i].equals(s)) {r++; break;}
		if(r==1) return i+1;
		else return 10;
	}

	void ex() {
	    te();
	    while(e1[r]==13||e1[r]==14)
	    {
	        r++;
	        te();
	    }
	    return;
	}

	void fa() {
	    if (e1[r]==10 || e1[r]== 11) r++;
	    else if (e1[r]== 27)
	    {
	        r++;
	        ex();
	        if (e1[r]== 28) r++;
	        else { System.out.print("\n)错误"); k = 1; }
	    }
	    else { System.out.print("\n表达式错误"); k = 1; } 
	    return;
	}

	void te() {
	    fa();
	    while (e1[r]==15||e1[r]==16) 
	    {
	    	r++;
	        fa();
	    }
	    return;
	}

	void st() {
	    if (e1[r]==10)
	    {
	        r++;
	        if (e1[r] == 18)
	        {
	            r++;
	           if(e1[r]==6)  System.out.print("\n;错误");
	            ex(); 

	        }
	        else { System.out.print("\n赋值号错误"); k = 1; }
	    }
	    else  { System.out.print("\n输出于醋错误"); k = 1;}
	    return;
	}
	void yu() {
	    st();
	    while (e1[r]==26)//;
	    {
	        r++;
	        st();
	    
	    }
	    return;
	}
	void lr() {

	    if (e1[r]== 1)//begin
	    {
	        r++;
	        yu();
	        if (e1[r] == 6) //end
	        {
	            r++;
	            if ( k == 0) System.out.print("\nsuccess");

	        }
	        else { if (k != 1) System.out.print("\nend错误"); k = 1; }

	    }
	    else System.out.print("\nbegin错误");
	    return;

	}	

}

package text;

public class test { 

	public static void main(String[] args) {
		funs s=new funs();
		s.fun(); s.lr();
	}	
}

运行结果:
|
| |在这里插入图片描述

|在这里插入图片描述

通过分析语法,知道‘;’只可能紧跟语句和end,而当end时即出现;错误,在st()函数调用ex()之前,单词往后走之后判断即可检查出具体错误,至于其他的具体错误此处未列出。

  • 2
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值