的主页               欢迎光临!!!!
首页 词法扫描器的生成器算法winlex C语言上机练习题
winlex
词法扫描器的生成器算法
摘要

  本算法仿照unix下的LEX的功能,在windows环境下开发词法分析器的自动生成算法。该算法用C++的类完全封装起来,实现了较好的安全性与透明性,并且与C++实现了无缝嵌入,避免了LEX中的二次编译。
  词法扫描器的自动生成器算法,理论方面应用编译原理的关于正规式的知识和自动机理论,程序采用面向对象的C++类的知识和指针的相关操作,通过结合数据结构的链表、栈、图等知识,有效提高词法扫描器开发过程的效率和质量。

  该算法能自动检测正规式的是否正确,可以很容易的进行二义性处理。由于本算法临时支持的辅助运算符不多,所以在处理有的问题时不如LEX方便,但由于C++在结构控制上的灵活性,可以在一定程序上弥补以上的不足。该算法没有进行DFA的化简。由于DFA与它的最简DFA所表示的正规集是相同的,所以用DFA和最简DFA来识别输入串的结果是一样的,但速度肯定会受影响。

理论
算法模型
使用说明
二义性
程序源码
  返回顶部
词法扫描器的生成器的算法理论基础
    等待更新
  返回顶部
词法扫描器的生成器的算法模型
      等待更新
  返回顶部
词法扫描器的生成器算法的使用说明
      本算法临时支持的正规式运算符如下:
  括号:( )
  或取:|
  闭包:*
  转义:\\ (由于C++的转义符为\,所以\\才能被算法识别)
  运算优先级与LEX相似。

该算法封装在winlex类中。需要的头文件有:winlex.h(winlex类的定义及成员函数),winlexclass.h(winlex类中用到的其它类的定义及成员函数)。其使用格式如下:

#include"winlex.h"

#include<iostream>

using namespace std;

main()

{

       winlex a("(a|b(a|(\\|ac)*)*)*");

       //定义一个winlexa,并用正规式(a|b(a|(\\|ac)*)*)*初始化

       //初始化过程是由正规式->nfa->dfa的过程

       cout<<a.recognise("ab|ac|acab|acaabbabaab")<<endl;

       //识别输入串是否符合正规式,返回值为bool

       //识别过程是用dfa识别输入串的过程

}

  由于本算法临时支持的运算符不多,所以在处理有的问题时不如LEX方便,但由于C++在结构控制上的灵活性,可以在一定程序上弥补以上的不足。比如下面程序,识别以小写字母开始,由小写字母组成的字符串的程序如下:

#include"winlex.h"

#include<iostream>

using namespace std;

main()

{

       const string a_z="(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)";

       string s=a_z+a_z+"*";//相当于LEX语法中的“[a-z]+

       winlex a(s); //定义由小写字母组成的字符串类a

       cout<<a.recognise("aaasadfzaaa")<<endl;//输出1

       cout<<a.recognise("sdaf2knvoi")<<endl;//输出0

}

  返回顶部
关于规则的二义性的处理
   

  有时在词法分析程序中可能有多于一条规则与同一个字符串匹配,这就是规则的二义性,在这种情况下,可以按照以下两个原则来处理:

  1.能匹配最多字符的规则优先。

  2.在能匹配相同数目的字符的规则中,先给出的规则优先

  比如在词法中有关键字integer和小写字母组成的标示符,由于integer也符合标示符的规则,所以就产生了二义性。这时可以按照以上两条规则处理如下:

#include"winlex.h"

#include<iostream>

using namespace std;

main()

{

       const string a_z="(a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)";

       string s=a_z+a_z+"*";//相当于LEX语法中的“[a-z]+

       winlex a(s); //定义由小写字母组成的字符串类a

       winlex keyword("integer"); //定义关键字类keyword

       string ts="integer";

       if(keyword.recognise(ts))//先判断是否与关键字匹配

       {

              cout<<"关键字"<<endl;

              return;//若匹配就返回关键字

       }

       if(a.recognise(ts))//若不匹配,再判断是否与标示符匹配

        cout<<"标示符"<<endl;//若匹配返回标示符

}

  返回顶部
程序源码
      

  程序源码由两部分组成,一个是winlex.h封装了主类winlex,一个是winlexclass.h,封装了winlex中调用的各种类。

  winlex.h

  winlexclass.h

     
email:guolianga0316@126.com  vw_@163.com