本题目是编译原理实验,现在只发布核心代码,仅供交流,欢迎评论!
实验要求:
根据编译中的分词原理,编写一个词法分析程序:
1. 输入:任意一个C语言程序的源代码。
2. 处理:对输入进行分析,分离出保留字、标识符、常量、算符和界符。
3. 输出:对应的二元式(种别编码自定,可暂编为一类对应一个编码)。
一、说明
/**
*
* @author 刘小文
* 本词法分析器只对一部分进行了分析,并没有包含全部的信息,暂编一类对应一个编码
* (1)关键字:二元式定义如下:(单词种别为1,关键字名称) yes
* 关键字表:"auto","break","case","char","const","continue","default","do","double","else","enum","extern","float","for","goto","if","int","long","register","return","short","signed","static", "sizeof","struct","switch","typedef","union","unsigned","void","volatile","while"
*
* (2)标识符:二元式定义如下:(单词种别为2,标识符名称) yes
*
* (3)常 数:二元式定义如下:(单词种别3,常数值) yes
* 常数表:整型常数、浮点型常数、布尔型常数、字符型常数、字符串
*
* (4)运算符:二元式定义如下:(单词种别4,运算符) no 三目运算符没有判断
* 运算符表:+、+=、++、-、-=、--、*、*=、/、/=、%、%=、>、>=、<、<=、=、==、!、!= 、. 、->、>>、<<、&、&&、||、||、~、^
*
* (5)界 符:二元式定义如下:(单词种别5,界符) yes
* 界符表:#、;、,、(、)、{、}、[、]
*
* no 不加双引号的汉字误判为标识符,应为非法字符 ;加双引号的汉字,正确的判断为字符串常数
*/
二、词法分析器核心代码
Thread lexer = new Thread() { public void run() { //下面是预处理代码,去除注释、换行符等 String pretreatment = sourceTa.getText().replaceAll("//////[^//n]*|/////*([^//*^///]*|[//*^///*]*|[^//**///]*)*//*///", "");//去除注释,//和/**/ pretreatment = pretreatment.replaceAll("//s+", " ");//去掉多余的空白符,一个以上的用空格来代替 int m=0;//前进指针 String temp = new String();//暂存单词符号 char[] pretreatArray=pretreatment.toCharArray();//C语言源代码,字节数组pretreatArray //下面是进行单词符号分离,进行判断类型 while(m<pretreatArray.length) { if(Character.isSpace(pretreatArray[m]))//该字符是空格 { m++;//指向下一个 } //*********************************************关键字1和标识符2********************************************************************** else if(Character.isLetter(pretreatArray[m])||pretreatArray[m] == '_')//该字符是字母 { //不是界符和算符的单词符号,暂存到temp中 while(m<pretreatArray.length&& !Character.isSpace(pretreatArray[m])&& pretreatArray[m]!='('&& pretreatArray[m]!=')'&&pretreatArray[m]!='['&& pretreatArray[m]!=']'&& pretreatArray[m]!='{'&& pretreatArray[m]!='}'&& pretreatArray[m]!='+'&& pretreatArray[m]!='-'&& pretreatArray[m]!='*'&& pretreatArray[m]!='%'&& pretreatArray[m]!='/'&& pretreatArray[m]!='>'&& pretreatArray[m]!='<'&& pretreatArray[m]!='='&& pretreatArray[m]!='!'&& pretreatArray[m]!=','&& pretreatArray[m]!=';'&& pretreatArray[m]!='"'&& pretreatArray[m]!='.'&& pretreatArray[m]!='/''&& pretreatArray[m]!='//') { temp=temp+temp.valueOf(pretreatArray[m]); m++; } int key = 0; //判断是不是关键字,关键字key置为1 for(int i = 0;i < keyWords.length;i++) { if(temp.equals(keyWords[i])) { setDocs(temp+"/t"+"关键字"+"/t"+"二元式为:(1 ,"+temp+" )"+"/n",Color.blue,false,15);//输出二元式 key = 1;//****************关键字**************** break; } } if(key == 0)//布尔型常数和自定义变量,由字母、数字和下划线组成,第一个字符必须为字母或下划线 { int p=1; for(int i=0;i<temp.length();i++) { if(!Character.isLetter(temp.charAt(i))&&!Character.isDigit(temp.charAt(i))&&temp.charAt(i)!='_') p=0;//非法标识符 } if(p == 1&&(temp.equalsIgnoreCase("true")||temp.equalsIgnoreCase("false")))//****************布尔型常数************************ { setDocs(temp+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp+" )"+"/n",Color.black,false,15);//输出二元式 } else if(p == 1)//****************标识符**************** { setDocs(temp+"/t"+"标识符"+"/t"+"二元式为:(2 ,"+temp+" )"+"/n",Color.orange,false,15);//输出二元式 } else { setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } temp=""; } //**************************************************************常数3************************************************************ else if(Character.isDigit(pretreatArray[m]))//该字符是数字 { boolean flag=false; int mn=0; int xy=0; int ab=0; //得到常数,得到一个非 界符和算符的单词符号,保存到temp中(即为以数字开头的关键字、变量名(即为非法字符)和常数) while(m<pretreatArray.length&& !Character.isSpace(pretreatArray[m])&& pretreatArray[m]!='('&& pretreatArray[m]!=')'&& pretreatArray[m]!='['&& pretreatArray[m]!=']'&& pretreatArray[m]!='{'&& pretreatArray[m]!='}'&& pretreatArray[m]!='+'&&pretreatArray[m]!='*'&& pretreatArray[m]!='%'&& pretreatArray[m]!='/'&& pretreatArray[m]!='>'&& pretreatArray[m]!='<'&& pretreatArray[m]!='='&&pretreatArray[m]!='!'&& pretreatArray[m]!=','&& pretreatArray[m]!=';'&& pretreatArray[m]!='"'&& pretreatArray[m]!='/''&& pretreatArray[m]!='//'|| ((m<pretreatArray.length && Character.isDigit(pretreatArray[m]))||(m<pretreatArray.length && pretreatArray[m]=='.')||(m<pretreatArray.length && Character.isLetter(pretreatArray[m])))) { temp=temp+temp.valueOf(pretreatArray[m]); m++; } //mn=0时该单词符号是纯常数 for(int i=0;i<temp.length();i++) { if(temp.charAt(i)!='.'&& !Character.isDigit(temp.charAt(i))) { mn=1; break; } } if(mn==0)//该单词符号是纯常数 { for(int k=0;k<temp.length();k++) { if(temp.charAt(k)=='.') flag=true; } if(flag)//***************浮点型****************** { try{ setDocs(temp+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp+" )"+"/n",Color.black,false,15);//输出二元式 }catch(Exception ex){ setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } else //*********************整型****************** { try{ setDocs(temp+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp+" )"+"/n",Color.black,false,15);//输出二元式 }catch(Exception ex){ setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } } else //****************浮点型(科学计数法)或非法字符************** { for(int i=0;i<temp.length();i++) if(Character.isLetter(temp.charAt(i))||temp.charAt(i)=='-') { ++xy;//非数字字符的个数 ab=i; } //e或E之前必须有数字,且e或E后面的指数必须为整数 if(xy==1 && (temp.charAt(ab)=='e' || temp.charAt(ab)=='E')) { try{ Integer.parseInt(temp.substring(ab+1));//判断e或E后面的指数为整数,不是整数执行catch语句 setDocs(temp+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp+" )"+"/n",Color.black,false,15);//输出二元式 }catch(Exception ex){ setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } else if(xy==1 && temp.charAt(ab)=='-') { setDocs(temp.substring(0, ab)+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp.substring(0, ab)+" )"+"/n",Color.black,false,15);//输出二元式 m = ab; } else if(xy==2 &&Character.isDigit(temp.charAt(ab-2))&& (temp.charAt(ab-1)=='e' || temp.charAt(ab-1)=='E') && temp.charAt(ab)=='-') { try{ Integer.parseInt(temp.substring(ab+1));//判断e或E后面的指数为整数,不是整数执行catch语句 setDocs(temp+"/t"+"常数"+"/t"+"二元式为:(3 ,"+temp+" )"+"/n",Color.black,false,15);//输出二元式 }catch(Exception ex){ setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } else { setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } xy = 0; ab = 0; } temp=""; } else if(pretreatArray[m]=='/'')//**************字符型*********'abc'**************** { m++; while(m<pretreatArray.length) { if(pretreatArray[m]!='/'') { temp = temp+pretreatArray[m]; m++; } else break; } if(m == pretreatArray.length) { setDocs("'"+temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } else { setDocs("'"+temp+"'"+"/t"+"常数"+"/t"+"二元式为:(3 ,"+"'"+temp+"'"+" )"+"/n",Color.black,false,15);//输出二元式 m++; } temp = ""; } // else if(pretreatArray[m]=='//')//************字符型********/n等转义字符******************* // { // m++; // if(pretreatArray[m]=='n'||pretreatArray[m]=='t'||pretreatArray[m]=='b'||pretreatArray[m]=='r'||pretreatArray[m]=='f'||pretreatArray[m]=='//'||pretreatArray[m]=='/''||pretreatArray[m]=='"'||pretreatArray[m]=='0'||pretreatArray[m]=='a') // { // setDocs("//"+pretreatArray[m]+"/t"+"常数"+"/t"+"二元式为:(3 ,"+"//"+pretreatArray[m]+" )"+"/n",Color.black,false,15);//输出二元式 // m++; // } // } else if(pretreatArray[m]=='"')//**************字符串常数********"abc"**************** { m++; while(m<pretreatArray.length) { if(pretreatArray[m]!='"') { temp = temp+pretreatArray[m]; m++; } else break; } if(m == pretreatArray.length) { setDocs("/""+temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } else { setDocs("/""+temp+"/""+"/t"+"常数"+"/t"+"二元式为:(3 ,"+"/""+temp+"/""+" )"+"/n",Color.black,false,15);//输出二元式 m++; } temp = ""; } //*************************************************运算符4***************************************************************** else if(pretreatArray[m]=='+')//*************** + **************** { m++; if(m<pretreatArray.length && Character.isDigit(pretreatArray[m]))//+后跟数字 { setDocs("+"+"/t"+"运算符"+"/t"+"二元式为:(4 ,+ )"+"/n",Color.green,false,15);//输出二元式 + } else if(m<pretreatArray.length&& pretreatArray[m]=='+')//+后跟+ { m++; if(m<pretreatArray.length &&pretreatArray[m] == '+')//看是不是+++ { setDocs("+++"+"/t"+"非法标识符"+"/n",Color.red,true,15); m++; } else//++后面跟着除了+之外的字符 { setDocs("++"+"/t"+"运算符"+"/t"+"二元式为:(4 ,++ )"+"/n",Color.green,false,15);//输出二元式 ++ } } else if(m<pretreatArray.length&& pretreatArray[m]=='=')//+后跟= { setDocs("+="+"/t"+"运算符"+"/t"+"二元式为:(4 ,+= )"+"/n",Color.green,false,15);//输出二元式 += m++; } else //+后跟除了数字或+或=之外的字符 { m--; setDocs("+"+"/t"+"运算符"+"/t"+"二元式为:(4 ,+ )"+"/n",Color.green,false,15);//输出二元式 + m++; } temp=""; } else if(pretreatArray[m]=='-')//*************** - **************** { m++; if(m<pretreatArray.length && Character.isDigit(pretreatArray[m]))//-后跟数字 { setDocs("-"+"/t"+"运算符"+"/t"+"二元式为:(4 ,- )"+"/n",Color.green,false,15);//输出二元式 - } else if(m<pretreatArray.length&& pretreatArray[m]=='-')//-后跟- { m++; if(m<pretreatArray.length &&pretreatArray[m] == '-')//看是不是--- { setDocs("---"+"/t"+"非法标识符"+"/n",Color.red,true,15); m++; } else//--后面跟着除了-之外的字符 { setDocs("--"+"/t"+"运算符"+"/t"+"二元式为:(4 ,-- )"+"/n",Color.green,false,15);//输出二元式 -- } } else if(m<pretreatArray.length&& pretreatArray[m]=='=')//-后跟= { setDocs("-="+"/t"+"运算符"+"/t"+"二元式为:(4 ,-= )"+"/n",Color.green,false,15);//输出二元式 -= m++; } else if(m<pretreatArray.length&& pretreatArray[m]=='>')//-> { setDocs("->"+"/t"+"运算符"+"/t"+"二元式为:(4 ,-> )"+"/n",Color.green,false,15);//输出二元式 -= m++; } else //-后跟除了数字 - =之外的字符 { m--; setDocs("-"+"/t"+"运算符"+"/t"+"二元式为:(4 ,- )"+"/n",Color.green,false,15);//输出二元式 + m++; } temp=""; } else if(pretreatArray[m]=='*'||pretreatArray[m]=='%'||pretreatArray[m]=='/'||pretreatArray[m]=='>'||pretreatArray[m]=='<'||pretreatArray[m]=='='||pretreatArray[m]=='!') { temp = temp.valueOf(pretreatArray[m]); try{ char next = pretreatArray[++m]; if((temp.charAt(0) == '>'&&next == '>') || (temp.charAt(0) == '<'&&next == '<'))// >> << { setDocs(temp+next+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+next+" )"+"/n",Color.green,false,15);//输出二元式 m++; } else if(next == '=') { setDocs(temp+"="+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+"="+" )"+"/n",Color.green,false,15);//输出二元式 m++; } else { setDocs(temp+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+" )"+"/n",Color.green,false,15);//输出二元式 } } catch(Exception ex){ setDocs(temp+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+" )"+"/n",Color.green,false,15);//输出二元式 } temp = ""; } else if(pretreatArray[m]=='&'||pretreatArray[m]=='|') { temp = temp.valueOf(pretreatArray[m]); try{ if(pretreatArray[++m] == temp.charAt(0))//&& || { setDocs(temp+temp+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+temp+" )"+"/n",Color.green,false,15);//输出二元式 m++; } else { setDocs(temp+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+" )"+"/n",Color.green,false,15);//输出二元式 } } catch(Exception ex){ setDocs(temp+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+temp+" )"+"/n",Color.green,false,15);//输出二元式 } temp = ""; } else if(pretreatArray[m]=='.'||pretreatArray[m]=='~'||pretreatArray[m]=='^') { setDocs(pretreatArray[m]+"/t"+"运算符"+"/t"+"二元式为:(4 ,"+pretreatArray[m]+" )"+"/n",Color.green,false,15);//输出二元式 m++; } //********************************************************界符5******************************************************************** else if(pretreatArray[m]=='#'||pretreatArray[m]==';'||pretreatArray[m]==','|| pretreatArray[m]=='('||pretreatArray[m]==')'||pretreatArray[m]=='{'||pretreatArray[m]=='}'|| pretreatArray[m]=='['||pretreatArray[m]==']') { setDocs(pretreatArray[m]+"/t"+"界符"+"/t"+"二元式为:(5 ,"+pretreatArray[m]+" )"+"/n",Color.cyan,false,15);//输出二元式 m++; } //******************************************************非法标识符******************************************************************* else { while(m<pretreatArray.length&& !Character.isSpace(pretreatArray[m])&& pretreatArray[m]!='('&& pretreatArray[m]!=')'&&pretreatArray[m]!='['&& pretreatArray[m]!=']'&& pretreatArray[m]!='{'&& pretreatArray[m]!='}'&& pretreatArray[m]!='+'&& pretreatArray[m]!='-'&& pretreatArray[m]!='*'&& pretreatArray[m]!='%'&& pretreatArray[m]!='/'&& pretreatArray[m]!='>'&& pretreatArray[m]!='<'&& pretreatArray[m]!='='&& pretreatArray[m]!='!'&& pretreatArray[m]!=','&& pretreatArray[m]!=';'&& pretreatArray[m]!='"'&& pretreatArray[m]!='.'&& pretreatArray[m]!='/''&& pretreatArray[m]!='//') { temp=temp+temp.valueOf(pretreatArray[m]); m++; } setDocs(temp+"/t"+"非法标识符"+"/n",Color.red,true,15); } } } };
三、运行结果