编译原理实验 之 词法分析

来源:互联网 发布:电子称软件下载 编辑:程序博客网 时间:2024/06/05 02:28


     词法分析步骤是编译器处理的第一步,目的是将用户输入的符号流转化为 后面语法分析所需的 词法单元的形式.

    

    一般来说,经过了词法分析之后, 所有的输入内容都将变成"编译器可识别"的形式. 词法单元主要分为几类, 比如标示符,常量,标点符号,操作符,关键字等等. 对于常量和标示符而言,词法分析的结果还应该包含它所带有的实际含义和值.

 

    词法分析的作用: 1.剔除空格 换行符 制表符等等,

    2.通过换行符记录数据的行数,以便在返回错误的时候定位到错误行.

    

   词法分析的实现有很多方式,这里我们采用栈的数据结构对其词法分析过程进行模拟.


    先贴出我们实验课的词法内容吧.
  
    
(1)待分析的简单语言的词法
1) 关键字
begin if then while do end
2) 运算符和界符
:= + - * / < <= > >= <> = ; ( ) #
3) 其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:
ID=letter(letter|digit)*
NUM=digitdigit*
4) 空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,词法分析阶段通常被忽略。

4) 空格由空白、制表符和换行符组成。空格一般用来分隔IDNUM、运算符、界符和关键字,词法分析阶段通常被忽略。

2)各种单词符号对应的种别编码

单词符号

种别码

单词符号

种别码

begin

1

:

17

if

2

:=

18

then

3

<

20

while

4

<>

21

do

5

<=

22

end

6

>

23

letter(letter|digit)*

10

>=

24

digitdigit*

11

=

25

+

13

;

26

-

14

(

27

*

15

)

28

/

16

#

0

3)词法分析程序的功能

输入:所给文法的源程序字符串

输出:二元组(syn, tokensum)构成的序列。

syn为单词种别码;

token为存放的单词自身字符串;

sum为整形常数。

例如:对源程序begin x:=9;if x>0 then x:=2*x+1/3;end# 经词法分析后输出如下序列:(1begin(10,’x’) (18,:=) (11,9) (26,;) (2,if)……





   实验的内容并不复杂,用到的数据结构和类型也很简单,没有什么复杂的算法,慢慢写就可以了.


   后面就是代码了,也许会有些小bug,因为后面改的时候不记得是否保存了.....不过应该不是大问题..大家参考就好.
   
   
#include "define.h"




int _isLetter(char exp)                        //判断字母
{
    
if(exp >='A'&&exp<='Z'||exp>='a'&&exp<='z')
return 1;
return 0;
};




bool _isKey(string s)                                   //判断关键字
{
if(Keylist->Key_search(s))
  return true;
return false;
};


bool _isOpe(char c)                             //判断操作符
{
if(Opelist->Ope_search(c))
return true;
return false;
};


int _isDigit(char exp)                          //判断数字
{
if(exp >='0'&&exp <='9')
return 1;
return 0;
};




int NO(char c)                               //返回键值
{
if(c=='+')return 13;
if(c=='-')return 14;
if(c=='*')return 15;
if(c=='/')return 16;
if(c=='>')return 20;
if(c=='<')return 23;
if(c=='=')return 25;
if(c==':')return 17;
if(c==';')return 26;
if(c=='#')return 0;
if(c==')')return 28;
if(c=='(')return 27;
};
int NO(char c1,char c2)
{
if(c1=='<'&&c2=='>')return 21;
if(c1==':'&&c2=='=')return 18;
if(c1=='<'&&c2=='=')return 22;
if(c1=='>'&&c2=='=')return 24;
};




void print()                                       //打印函数,也是处理栈,
{
int sz;
int n[MAX_LENGTH];char str[MAX_LENGTH] ={' '};char o[MAX_LENGTH] = {' '};
if(!cs.empty())
{
   sz = cs.size();
for(int i=sz-1;i>-1;i--)
{ str[i]=cs.top();cs.pop();}
if(_isKey(str));
else {cout<<"("<<10<<",";
        for(int j=0;j<sz;j++)
cout<<str[j];cout<<")"<<endl;}
}
else if(!ns.empty())
{
sz = ns.size();
for(int i=sz-1;i>-1;i--)
{
            n[i]=ns.top();
       ns.pop();
        }
        cout<<"("<<11<<",";
for(int j=0;j<sz;j++)
cout<<n[j]-48;
cout<<")"<<endl;
}


};


ostream& operator << (ostream& out,char*  st)
{
int i=0; 
while(i<sizeof(st))
{out<<st[i];i++;}
return out;
};




void analysis(const char* filename)                    //词法分析的主体,遇到其他符号的时候就跳到栈的处理,完成匹配.
{
   filein.open(filename,ios::in);
   if(!filein)
   {
  cout<<"File open error!\n";
  return ;
   }
   char c;
   while((c = filein.get())!=EOF)
   {
      
       if(_isOpe(c))
  {
  if(!os.empty())
  {
  cout<<"("<<NO(os.top(),c)<<";"<<os.top()<<c<<")"<<endl;
  os.pop();
  }
  else os.push(c);
  print();                                 //跳
  }
       if(_isLetter(c)==1)
  {   
  cs.push(c);
      if(!os.empty())
  {
  cout<<"("<<NO(os.top())<<";"<<os.top()<<")"<<endl;
  os.pop();
  }
  }
  else if(_isDigit(c)==1&&!cs.empty())
  {
  cs.push(c);
  if(!os.empty())
  {
  cout<<"("<<NO(os.top())<<";"<<os.top()<<")"<<endl;
  os.pop();
  }
  }
  else if(_isDigit(c)==1)
  {   
  ns.push(c);
           if(!os.empty())
  {
  cout<<"("<<NO(os.top())<<";"<<os.top()<<")"<<endl;
  os.pop();
  }     
  }
  else if(c=='\t'||c==' '||c=='\n')
  {   
  if(!os.empty())
  {
  cout<<"("<<NO(os.top())<<";"<<os.top()<<")"<<endl;
  os.pop();
  }  
  print();                       //跳
  }
   }
   filein.close();
};
      上面就是词法分析的核心部分了.也不是很难,细节部分的处理注意一下就好了.
 
       本系列博客的目的其实就是让后面需要的人有个例子对比而已,有发现bug的可以提出来.
      
       最后如果有需要全部代码的可以私信我,在线必回~~
    
      下一次就是自顶向下的语法分析程序了,期待吧~
原创粉丝点击