当前位置:文档之家› 编译原理词法分析器java

编译原理词法分析器java

实验一词法分析器的设计一、实验目的1.理解词法分析器的任务和输出形式2.理解扫描器的工作原理3.掌握状态转换图的绘制以及单词的识别技术4.掌握词法分析器的设计过程,能够使用某种高级语言实现一个词法分析器二、实验环境Myeclipse三、实验要求给出一个简单的词法语言规则描述,其中:1开头的种别码为关键词,2开头的为算符,3开头的为界符,4开头的为标识符,5开头的为常数,标识符为字母开头,以字母和数字组成的任意符号串,常数为整数,即以数字组成的符号串。

四、实验难点1.对整数的二进制转换,以及对指针的操作2.标识符的设置五、实验代码1.ciFa.Javapackage com.yaoer.test1;import javax.swing.*;import javax.swing.border.TitledBorder;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;@SuppressWarnings("serial")public class ciFa extends JFrame{private JButton jbtShow = new JButton("进行词法分析");//按钮private JTextArea jta = new JTextArea();//输入文本框private JTextArea jtaOut = new JTextArea();//输出文本框private JPanel jpl=new JPanel();private String intput ="";private String output ="";private compiler comp = new compiler();* @param args*/public static void main(String[] args){ciFa frame = new ciFa();frame.setTitle("词法分析器");//frame.setLocationRelativeTo(frame);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(500, 400);frame.setVisible(true);}public ciFa(){jta.setWrapStyleWord(true);jta.setLineWrap(true);jtaOut.setWrapStyleWord(true);jtaOut.setLineWrap(true);jtaOut.setEditable(false);JScrollPane scrollPane = new JScrollPane(jta);JScrollPane scrollPane2 = new JScrollPane(jtaOut);scrollPane.setPreferredSize(new Dimension(300,300));scrollPane2.setPreferredSize(new Dimension(300,300));jtaOut.setBorder(new TitledBorder("词法分析结果"));jta.setBorder(new TitledBorder("请在这输入"));jpl.setLayout(new GridLayout(2,2));jpl.add(jta);jpl.add(jtaOut);add(jbtShow,BorderLayout.SOUTH);add(jpl);jbtShow.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){intput = jta.getText();output=puterComp(intput);jtaOut.append(output);}});}piler.Javapackage com.yaoer.test1;public class compiler {public String computerComp(String str){String output="";int index=0;int k = 0;while(index<str.length()){if(isJieFu(str.charAt(index))!=-1){ //判断界符output+=("( 30"+isJieFu(str.charAt(index))+" "+str.charAt(index)+" 界符)");index++;}else if(isMath(str.charAt(index))){ //判断常数int index1=index;output+=("( ");String sub;String result;while(isMath(str.charAt(index))){output+=(str.charAt(index));index++;if(index>=str.length()){if(str.charAt(index1)=='0'){if(index1+1>=str.length()){sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}else{if(isMath(str.charAt(index1+1))){output+=(" 非法字符)"); }else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}}else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}return output;}}if(isLetter(str.charAt(index))){if(str.charAt(index)==' '||str.charAt(index)=='\n'){//空格或者回车处理index++;}while((!isMath(str.charAt(index)))||(isLetter(str.charAt(index)))){output+=(str.charAt(index));index++;if(index>=str.length()) {output+=(" 非标识符)");return output;}}output+=(" 非法字符)");}else{if(str.charAt(index1)=='0'){if(isMath(str.charAt(index1+1))){output+=(" 非法字符)"); }else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}else{sub =str.substring(index1, index);result = Zhuan(sub);output+=(" "+result+" 数字)");}}}else if(isLetter(str.charAt(index))){ //标识符判断int i=index;String sub;while(isLetter(str.charAt(index))||isMath(str.charAt(index))){index++;if(index>=str.length()){//System.out.println(index);sub =str.substring(i, index);if(isKeyword(sub)!=0){if(isKeyword(sub)>=10){output+=("( "+" 1"+isKeyword(sub)+" "+sub+" 关键字)");}else{output+=("( "+" 10"+isKeyword(sub)+" "+sub+" 关键字)");}}else{output+=("( "+sub+" 标识符)");}return output;}}sub = str.substring(i, index);//判断是不是关键字if(isKeyword(sub)!=0){if(isKeyword(sub)>=10){output+=("( "+" 1"+isKeyword(sub)+" "+sub+" 关键字)");}else{output+=("( "+" 10"+isKeyword(sub)+" "+sub+" 关键字)");}}else{output+=("("+sub+" 标识符)");}}else if(isCompu(str.charAt(index))!=0){if(index+1>=str.length()){if(str.charAt(index)=='&'||str.charAt(index)=='|'){output+=("("+str.charAt(index)+" 非法字符)");index++;}else{if(isCompu(str.charAt(index))<=8){output+=("("+" 20"+isCompu(str.charAt(index))+" "+str.charAt(index)+" 运算符)");}else if(str.charAt(index)=='!'){output+=("( 218 "+str.charAt(index)+" 运算符)");}index++;}}else{if(isCompu(str.charAt(index+1))==0){if(str.charAt(index)=='&'||str.charAt(index)=='|'){output+=("("+str.charAt(index)+" 非法字符)");index++;}else{if(isCompu(str.charAt(index))<=8){output+=("("+"20"+isCompu(str.charAt(index))+" "+str.charAt(index)+" 运算符)");}else if(str.charAt(index)=='!'){output+=("("+" 218"+str.charAt(index)+" 运算符)");}index++;}}else{if(index+2>=str.length()){if( isCompu(str.charAt(index+1))!=0){if(str.charAt(index)=='='){if(str.charAt(index+1)=='='){output+=("("+" 210 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='<' ){switch (str.charAt(index+1)) {case '=':output+=("("+" 209 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '<':output+=("( 215 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '>':output+=("( 211 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;default:output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;break;}}else if(str.charAt(index)=='>' ){if(str.charAt(index+1)=='='){output+=("( 207 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else if(str.charAt(index+1)=='>'){output+=("( 214 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='&'){if(str.charAt(index+1)=='&'){output+=("( 216 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='|'){if(str.charAt(index+1)=='|'){output+=("( 217 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='+'){if(str.charAt(index+1)=='+'){output+=("( 212 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='-'){if(str.charAt(index+1)=='-'){output+=("( 213 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}return output;}else{if( isCompu(str.charAt(index+1))!=0){if(str.charAt(index)=='='){if(str.charAt(index+1)=='='){output+=("("+" 210 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='<' ){switch (str.charAt(index+1)) {case '=':output+=("("+" 209 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '<':output+=("("+" 215 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;case '>':output+=("( 211 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;break;default:output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;break;}}else if(str.charAt(index)=='>' ){if(str.charAt(index+1)=='='){output+=("( 207 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else if(str.charAt(index+1)=='>'){output+=("( 214 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='&'){if(str.charAt(index+1)=='&'){output+=("( 216 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='|'){if(str.charAt(index+1)=='|'){output+=("( 217 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='+'){if(str.charAt(index+1)=='+'){output+=("( 212"+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else if(str.charAt(index)=='-'){if(str.charAt(index+1)=='-'){output+=("( 213 "+str.charAt(index)+str.charAt(index+1)+" 运算符)");index++;index++;}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}else{output+=("("+str.charAt(index)+str.charAt(index+1)+" 非法字符)");index++;index++;}}}}}}else if(str.charAt(index)==' '||str.charAt(index)=='\n'){//空格或者回车处理index++;}else {//其他字符output+=("("+str.charAt(index)+" 非法字符)");index++;}k++;if(k%10==0){output+=("\n");}}return output;}/*** 1.判断是不是关键字* @param str* @return*/public int isKeyword(String str){int result = 0;String[]arr={"void","main","int","char","if","else","for","while","return","cout","ci n"} ;for(int i=0;i<arr.length;i++){if(str.equals(arr[i])){result = i+1;break;}else {result = 0;}}return result;}/*** 2.判断是不是运算符* @param charr* @return*/public int isCompu(char charr) {char arr[]={'+','-','*','/','=','>','&','<','!','|'};for(int i=0;i<arr.length;i++) {if (charr==arr[i]){return i+1;}}return 0;}/*** 3.判断是不是界符* @param charr* @return*/public int isJieFu(char charr){char arr[]={'(',')','[',']','{','}',',',';'};for(int i=0;i<arr.length;i++){if (charr==arr[i]){return i+1;}}return -1;}/*** 4.判断是不是标识符* @param charr* @return*/public boolean isLetter(char charr){if(((charr>='a'&&charr<='z')||(charr>='A'&&charr<='Z')) ||charr=='_'){ return true;}else{return false;}}/*** 5.判断是不是数字* @param charr* @return*/public boolean isMath(char charr){if((charr>='0')&&(charr<='9')){return true;}else{return false;}}/*** 将十进制转换为二进制* @param num* @return*/public String Zhuan(String num){int number = Integer.parseInt(num);int sum;String result = "";for (int i = number; i >= 1; i /= 2) {if (i % 2 == 0) {sum = 0;} else {sum = 1;}result = sum + result;}return result;}}六、实验中遇到的问题及感想在编写词法分析器的程序中,几个子函数的功能还是比较容易实现的,但是要把它们的功能连在一起,实现对程序源代码的词法分析就困难了,例如在分析运算符的时候,有的运算符是由2个符号组成的,有的是1个,在读入一个字符的时候还要进行超前搜索,看看第二个字符是否可以和第一个字符组成一个运算符。

相关主题