词法分析器用C实现.doc
《词法分析器用C实现.doc》由会员分享,可在线阅读,更多相关《词法分析器用C实现.doc(13页珍藏版)》请在冰点文库上搜索。
设计界面如上图所示:
代码如下:
namespaceWindowsApplication1
{
publicpartialclassForm1:
Form
{
publicForm1()
{
InitializeComponent();
}
stringStr="",text2="";
privatevoid打开ToolStripMenuItem_Click(objectsender,EventArgse)
{
stringFname="";
openFileDialog1.Filter="文本文件(*.txt)|*.txt";
openFileDialog1.Title="打开文件";
openFileDialog1.RestoreDirectory=true;
if(openFileDialog1.ShowDialog()==DialogResult.OK)
Fname=openFileDialog1.FileName;
richTextBox1.LoadFile(Fname,RichTextBoxStreamType.PlainText);
Str=richTextBox1.Text;
}
privatevoid保存ToolStripMenuItem_Click(objectsender,EventArgse)
{
stringFname=openFileDialog1.FileName;
richTextBox1.SaveFile(Fname,RichTextBoxStreamType.PlainText);
}
privatevoid另存为ToolStripMenuItem_Click(objectsender,EventArgse)
{
stringFname;
saveFileDialog1.Filter="文本文件(*.txt)|*.txt";
saveFileDialog1.Title="保存文件";
saveFileDialog1.RestoreDirectory=true;
saveFileDialog1.ShowDialog();
Fname=saveFileDialog1.FileName;
if(Fname!
="")
richTextBox1.SaveFile(Fname,RichTextBoxStreamType.PlainText);
}
privatevoid关闭ToolStripMenuItem_Click(objectsender,EventArgse)
{
Application.Exit();
}
privatevoid字体ToolStripMenuItem_Click(objectsender,EventArgse)
{
fontDialog1.ShowEffects=true;
fontDialog1.Font=richTextBox1.SelectionFont;
if(fontDialog1.ShowDialog()==DialogResult.OK)
richTextBox1.SelectionFont=fontDialog1.Font;
}
privatevoid词法分析ToolStripMenuItem_Click(objectsender,EventArgse)
{
Gets.LineNo=1;//初始化行号
Gets.errors=0;//初始化错误个数
Gets.text5="";
stringtext1=richTextBox1.Text+'\0';
Getsgetstring=newGets();
text2=getstring.GetString(text1);
richTextBox2.Text="*****************Token串生成表如下********************"+"\r\n"+text2;
textBox2.Text=getstring.ErrorN0();
}
privatevoidForm1_Load(objectsender,EventArgse)
{
}
privatevoid符号表ToolStripMenuItem_Click(objectsender,EventArgse)
{
textBox2.Text="***********************符号表信息******************"+"\r\n";
textBox2.Text+=Gets.text4;
}
privatevoid错误详细信息ToolStripMenuItem_Click(objectsender,EventArgse)
{
textBox2.Text=Gets.text5;
}
}
主要实现功能的代码如下:
创建一个Gets类用来对输入的字符串进行扫描
classGets
{
inti=0,j=0;//记录字符位置,token数组的位置
publicstaticintLineNo=1;//行号
stringtoken="";//记录识别出的单词
stringtext2="";
stringtext3="";//用来记录错误信息
stringwrong="";//记录异常信息
publicstaticinterrors=0;//错误字段的个数
publicstaticstringtext5="";//记录错误的详细信息
intflag1=0,flag2=0,flag3,flag4,flag5,flag6=0;//标记成对出现的界符
publicstaticstringtext4="入口:
单词名称长度类型种属值内存地址"+"\r\n";//用来记录符号表
string[]m_KeyWords=newstring[32]{"auto","double","int","struct","break","else","long","switch","case","enum",
"register","typedef","char","extern","return","union","const","float","short","unsigned","continue","for","signed","void","default",
"goto","sizeof","volatile","do","if","while","static"};
string[]m_operator=newstring[28]{"+","-","*","/","%",">","<",">=","<=","==","-=","+=","*=","/=",//运算符
"!
=","=","%=","&","&&","|","||","!
","++","--","~","<<",">>","?
:
"};
string[]m_bound=newstring[15]{"{","}","[","]",";",",",".","(",")",":
","\"","#",">","<","\'"};//界符
publicstringGetString(stringstr)//读入字符串
{
stringspace="";//空格数
if(str.Length==0)//判断字符串是否为空
return"";
try
{
while(str[i]!
='\0') //读入字符判断,空格、字母、数字、界符
{
if(str[i]==''||str[i]=='\t'||str[i]=='\r')
{
i++;//跳过无意义的字符
}
elseif(str[i]=='\n') //如果是换行符,则行号加1
{
LineNo++;
i++;
}
elseif(isalpha(str[i])) //如果是字母
{
i=recog_id(str,i);
for(j=0;j{
if(token.CompareTo(m_KeyWords[j])==0)
break;
}
if(j>=m_KeyWords.Length) //不是保留字
{
for(intm=0;m<12-token.Length;m++)
space=space+"";
text2=text2+LineNo.ToString()+":
"+token+space+"标识符Token码75"+"\r\n";;
text4=text4+LineNo.ToString()+":
"+token+""+token.Length+space+"标识符"+""+"简单变量"+""+"未知"+""+"未知"+"\r\n";
token="";
space="";
}
if(j{
for(intm=0;m<12-token.Length;m++)
space=space+"";
text2=text2+LineNo.ToString()+":
"+m_KeyWords[j]+space+"保留字Token码"+Convert.ToString(gettoken(token,1))+"\r\n";;
token="";
space="";
}
}
elseif(isdigit(str[i])) //如果是数字
{
i=recog_dig(str,i);
for(intm=0;m<12-token.Length;m++)
space=space+"";
text2=text2+LineNo.ToString()+":
"+token+space+"常量Token码76"+"\r\n";
text4=text4+LineNo.ToString()+":
"+token+""+token.Length+space+"整数"+""+"简单变量"+""+"未知"+""+"未知"+"\r\n";
token="";
space="";
}
elseif(isbound(str[i]))//识别界符
{
i=recog_bound(str,i);
for(intm=0;m<12-token.Length;m++)
space=space+"";
text2=text2+LineNo.ToString()+":
"+token+space+"界符Token码"+Convert.ToString(gettoken(token,3))+"\r\n";;
token="";
space="";
}
elseif(isoperator(str[i]))
{
i=recog_Operator(str,i);
for(intm=0;m<12-token.Length;m++)
space=space+"";
text2=text2+LineNo.ToString()+":
"+token+space+"运算符Token码"+Convert.ToString(gettoken(token,2))+"\r\n";
token="";
space="";
}
else{error(0);i++;}
}
}
catch(DivideByZeroExceptione1)
{
wrong=e1.Message;
}
catch(IndexOutOfRangeExceptione2)
{
wrong=e2.Message;
}
catch(Exceptione)
{
wrong=e.Message;
}
returntext2;
}
publicboolisalpha(charch)//判断是否为字母
{
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
returntrue;
elsereturnfalse;
}
publicboolisdigit(charch)//判断是否为数字
{
if(ch>='0'&&ch<='9')
returntrue;
elsereturnfalse;
}
publicboolissign(charch)//识别下划线
{
if(ch=='_')
returntrue;
elsereturnfalse;
}
publicboolisbound(charch)//判断是否为界符
{
for(intj=0;jif(ch.CompareTo(m_bound[j][0])==0)
{
returntrue;
}
returnfalse;
}
publicboolisoperator(charch)
{
for(inti=0;iif(ch==m_operator[i][0])
{
returntrue;
}
returnfalse;
}
privateintrecog_Operator(stringstr,inti)
{
charstate='0';
stringsstr="";
while(state!
='2')
{
switch(state)
{