编译原理词法分析
词法分析在编译原理中的重要的一步,它为语法分析打下了坚实的基础。也是为了前面的学习理论在实践中实现,如果你学习过编译原理,你就可以知道,前面好多的内容在讲解理论的内容,这些内容相对来说比较抽象,如果没有合适的例子你是不能理解的,我是这样理解词法分析的—它就像语文里面的语法,如果以面向对象的思想理解的话。语文里面的语法相当于一个实例,而词法分析相当于对象。下面就有我来说下我用java写的词法分析

代码实现
1、我们要定义一个int型的syn(用来存放种别码) token为存放的单词自身字符串,sum为整型常数。static char ch; static char[]token=new char[8];static int syn,p,m,n,sum;

3、扫描分析我在这里分了几种情况,开始扫描-当遇到字母时停下,判断是变量还是关键字。--遇到数字时拿出全部数字—遇到其他时拿出来


源代码
1、package LexP;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;public class LexlPa { /* 初始化数据 syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 11---数字 10---变量名 18---:= 1---true 2---if 3---false 4---while 5---do 6---end 26---; 27---( 28---) 23---> 15---* 13---+ 16---/ 0---# */ static String prog; static char ch; static char[]token=new char[8]; static int syn,p,m,n,sum; static //关键字表的初值 String[] rwtable={"true","if","then","while","do","false"}; /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //1、输入字符串 以#结束 prog="x:=9; if (x>0) then x:=2*a+1/3; #"; //1、从文件中读取字符串 //prog=dofile.readFileByChars("src/data.txt"); //2、扫描输出 p=0; do{ scaner(); switch(syn){ case 11:System.out.println("("+syn+" , "+sum+")");//单词符号:Digit digit* //System.out.print(sum); //System.out.println(")"); break; case -1:System.out.println("error!"); break; default: System.out.print("("); System.out.print(syn); System.out.print(" , "); String str=new String(token); System.out.print(str); System.out.println(")"); } }while(syn!=0); } //扫描程序 private static void scaner() throws IOException {// 1、初始化 for(int i=0;i<8;i++) token[i]=' ';// 2、读字母 ch=prog.charAt(p++); while(ch==' '){//如果是空格,则取下一个字符 ch=prog.charAt(p++); } // System.out.println(ch);// 3、开始执行扫描// 1、是字母// 读标识符,查保留字表// 查到,换成属性字表,写到输出流// 没查到, 查名表,换成属性字,写到输出流 if(ch>='a'&&ch<='z'){ m=0; //获取完整单词 while((ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')){ token[m++]=ch; ch=prog.charAt(p++); } token[m++]='\0'; --p; syn=10;//单词符号为letter(letter|digit)* //判断是哪个关键字 String newStr=new String(token); newStr=newStr.trim();//去空格 //System.out.println("newStr:"+newStr); for(n=0;n<6;n++){ //System.out.println("rwtable:"+rwtable[n]); if(newStr.equals(rwtable[n])){ syn=n+1; System.out.println("syn 的值是:"+syn); break; } } token[m++]='\0'; }// 2、是数字// 取数字,查常量表,换成属性字表,写到输出流 else if(ch>='0'&&ch<='9'){ sum=0; while(ch>='0'&&ch<='9'){ sum=sum*10+ch-'0'; ch=prog.charAt(p++); } --p; syn=11;//digitdigit* 数字 token[m++]='\0'; String str1=new String(token); /// System.out.println(str1+"cxscx"); /* try{ sum=Integer.parseInt(str1); }catch(Exception e) { System.out.println("fsdaf"); }*/ // System.out.println(sum); }// 3、是特殊符号 没有建立// 查特殊符号表,换成属性字。写到输出流// 4、错误error// 4、是否分析结束// 未结束,到2// 结束,到出口 else switch(ch){ case'<': m=0; token[m++]=ch; ch=prog.charAt(p++); if(ch=='>'){ syn=21;//<> } else if(ch=='='){ syn=22;//<= token[m++]=ch; } else{ syn=20;//< --p; } break; case'>': token[m++]=ch; ch=prog.charAt(p++); if(ch=='='){ syn=24;//>= } else{ syn=23;//> --p; } break; case':': token[m++]=ch; ch=prog.charAt(p++); if(ch=='='){ syn=18;//:= token[m++]=ch; } else{ syn=17;//: --p; } break; case'+': syn=13;token[0]=ch;token[1]='\0';break; case'-': syn=14;token[0]=ch;token[1]='\0';break; case'*': syn=15;token[0]=ch;token[1]='\0';break; case'/': syn=16;token[0]=ch;token[1]='\0';break; case'=': syn=25;token[0]=ch;token[1]='\0';break; case';': syn=26;token[0]=ch;token[1]='\0';break; case'(': syn=27;token[0]=ch;token[1]='\0';break; case')': syn=28;token[0]=ch;token[1]='\0';break; case'#': syn=0;token[0]=ch;token[1]='\0';break; default: syn=-1; } /*File txt=new File("src/nihao.txt"); if(!txt.exists()){ txt.createNewFile(); } byte[] bytes=new byte[token.length];//定义一个长度与需要转换的char数组相同的byte数组 for(int i=0;i<bytes.length ;i++){//循环将char的每个元素转换并存放在上面定义的byte数组中 byte b=(byte)token[i];//将每个char转换成byte bytes[i]=b;//保存到数组中 } FileOutputStream fos; try { fos = new FileOutputStream(txt,true); fos.write(syn); fos.write(bytes); fos.close(); } catch (Exception e) { e.printStackTrace(); } */ }}