THOMPSON-算法的实现_第1页
THOMPSON-算法的实现_第2页
THOMPSON-算法的实现_第3页
THOMPSON-算法的实现_第4页
THOMPSON-算法的实现_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、实验二:THOMPSON 算法的实现一实验目的掌握THOMPSON 算法原理和方法。二实验要求、内容及步骤1.输入字母表上的正规式r,输出一个接受L(r)的NFA;2.采用C+语言,实现该算法;3.编制测试程序4.调试程序;三实验设备计算机、Windows 操作系统、Visual C+ 程序集成环境。四实验原理Thompson构造法:从正规表达式构造NFA输入:字母表上的一个正规表达式r输出:接受L(r)的NFA N方法:将r分解成最基本的子表达式,使用下面的规则1和2为r的每个基本符号( 或中的符号)构造NFA。用规则3逐步组合前面构造的NFA,直到获得整个正规表达式的NFA为止。规则1.

2、对, 构造NFA 这里 i 是新的开始状态,f是新的接受状态。很明显这个NFA识别。 规则2. 对于中的每个符号a,构造NFA同样,i 是新的开始状态, f 是新的接受状态。 这个NFA识别 a。规则3 . 如果N(s) 和 N(t) 是正规表达式s和t的NFA,则:对于正规表达式 s | t, 可构造复合的NFA N(s|t): 对于正规表达式 st, 可构造复合的NFA N(st):对于正规表达式 s*, 构造复合的NFA N(s*):对于括起来的正规表达式 (s), 使用N (s) 本身作为它的NFA。在构造过程中,每次构造的新状态都要赋予不同的名字。这样,任何NFA的两个状态都具有不同

3、的名字。即使同一符号在r中出现多次,我们也要为该符号的每个实例创建一个独立的带有自己状态的NFA。五.程序设计框架六.程序流程图七.实验代码核心代码如下:#ifndef THOMPSON_H#define THIMPSON_H#include #include #include #include using namespace std;#define MAX 100/节点,定义成结构体,便于以后扩展struct statestring StateName;/边 空转换符永#表示struct edgestate StartState;state EndState;char TransSymbol

4、;/单元struct celledge EdgeSetMAX;int EdgeCount;state StartState;state EndState;/全局变量声明/int EDGE_NUM = 0;int STATE_NUM = 0;/int CELL_NUM = 0;/函数声明void input(string&);int check_legal(string);int check_character(string);int check_parenthesis(string);int is_letter(char);string add_join_symbol(string);/中缀转

5、后缀string postfix(string);/优先级 in stack priorityint isp(char);/优先级 in coming priorityint scp(char);/表达式转NFAcell express_2_NFA(string);/处理 a|bcell do_Unite(cell,cell);/处理 abcell do_Join(cell,cell);/处理 a*cell do_Star(cell);/处理 acell do_Cell(char);/将一个单元的边的集合复制到另一个单元void cell_EdgeSet_Copy(cell&,cell);/产

6、生一个新的状态节点,便于管理state new_StateNode();/显示void Display(cell);#endif#include Thompson.h/主函数,void main()string Regular_Expression = (a|b)*abb;cell NFA_Cell;Regular_Expression = (a|b)*abb;/接受输入input(Regular_Expression);/调试需要先屏蔽/添加“+”,便于转后缀表达式Regular_Expression = add_join_symbol(Regular_Expression);/中缀转后缀R

7、egular_Expression = postfix(Regular_Expression);/表达式转NFANFA_Cell = express_2_NFA(Regular_Expression);/显示Display(NFA_Cell);/*表达式转NFA处理函数,返回最终的NFA结合*/cell express_2_NFA(string expression)int length = expression.size();char element;cell Cell,Left,Right;stack STACK;for(int i=0;ilength;i+)element = expre

8、ssion.at(i);switch(element)case |:Right = STACK.top();STACK.pop();Left = STACK.top();STACK.pop();Cell = do_Unite(Left,Right);STACK.push(Cell);break;case *:Left = STACK.top();STACK.pop();Cell = do_Star(Left);STACK.push(Cell);break;case +:Right = STACK.top();STACK.pop();Left = STACK.top();STACK.pop();

9、Cell = do_Join(Left,Right);STACK.push(Cell);break;default:Cell = do_Cell(element);STACK.push(Cell);cout处理完毕!endl;Cell = STACK.top();STACK.pop();return Cell;/处理 a|bcell do_Unite(cell Left,cell Right)cell NewCell;NewCell.EdgeCount=0;edge Edge1,Edge2,Edge3,Edge4;/获得新的新状态节点state StartState = new_StateNo

10、de();state EndState = new_StateNode();/构建边Edge1.StartState = StartState;Edge1.EndState = Left.EdgeSet0.StartState;Edge1.TransSymbol = #;Edge2.StartState = StartState;Edge2.EndState = Right.EdgeSet0.StartState;Edge2.TransSymbol = #;Edge3.StartState = Left.EdgeSetLeft.EdgeCount-1.EndState;Edge3.EndSta

11、te = EndState;Edge3.TransSymbol = #;Edge4.StartState = Right.EdgeSetRight.EdgeCount-1.EndState;Edge4.EndState = EndState;Edge4.TransSymbol = #;/构建单元/先将Left和Right的EdgeSet复制到NewCellcell_EdgeSet_Copy(NewCell,Left);cell_EdgeSet_Copy(NewCell,Right);/将新构建的四条边加入EdgeSetNewCell.EdgeSetNewCell.EdgeCount+ = Ed

12、ge1;NewCell.EdgeSetNewCell.EdgeCount+ = Edge2;NewCell.EdgeSetNewCell.EdgeCount+ = Edge3;NewCell.EdgeSetNewCell.EdgeCount+ = Edge4;/构建NewCell的启示状态和结束状态NewCell.StartState = StartState;NewCell.EndState = EndState;return NewCell;/处理 abcell do_Join(cell Left,cell Right)/将Left的结束状态和Right的开始状态合并,将Right的边复制

13、给Left,将Left返回/将Right中所有以StartState开头的边全部修改,for(int i=0;iRight.EdgeCount;i+)if(Right.EdgeSeti.StartState.StateNpare(Right.StartState.StateName)=0)Right.EdgeSeti.StartState = Left.EndState;STATE_NUM-;else if(Right.EdgeSeti.EndState.StateNpare(Right.StartState.StateName)=0)Right.EdgeSeti.

14、EndState = Left.EndState;STATE_NUM-;Right.StartState = Left.EndState;cell_EdgeSet_Copy(Left,Right);/将Left的结束状态更新为Right的结束状态Left.EndState = Right.EndState;return Left;/处理 a*cell do_Star(cell Cell)cell NewCell;NewCell.EdgeCount=0;edge Edge1,Edge2,Edge3,Edge4;/获得新的新状态节点state StartState = new_StateNode(

15、);state EndState = new_StateNode();/构建边Edge1.StartState = StartState;Edge1.EndState = EndState;Edge1.TransSymbol = #;Edge2.StartState = Cell.EndState;Edge2.EndState = Cell.StartState;Edge2.TransSymbol = #;Edge3.StartState = StartState;Edge3.EndState = Cell.StartState;Edge3.TransSymbol = #;Edge4.Star

16、tState = Cell.EndState;Edge4.EndState = EndState;Edge4.TransSymbol = #;/构建单元/先将Cell的EdgeSet复制到NewCellcell_EdgeSet_Copy(NewCell,Cell);/将新构建的四条边加入EdgeSetNewCell.EdgeSetNewCell.EdgeCount+ = Edge1;NewCell.EdgeSetNewCell.EdgeCount+ = Edge2;NewCell.EdgeSetNewCell.EdgeCount+ = Edge3;NewCell.EdgeSetNewCell.

17、EdgeCount+ = Edge4;/构建NewCell的启示状态和结束状态NewCell.StartState = StartState;NewCell.EndState = EndState;return NewCell;/处理 acell do_Cell(char element)cell NewCell;NewCell.EdgeCount=0;edge NewEdge;/获得新的新状态节点state StartState = new_StateNode();state EndState = new_StateNode();/构建边NewEdge.StartState = StartS

18、tate;NewEdge.EndState = EndState;NewEdge.TransSymbol = element;/构建单元NewCell.EdgeSetNewCell.EdgeCount+ = NewEdge;NewCell.StartState = NewCell.EdgeSet0.StartState;NewCell.EndState = NewCell.EdgeSet0.EndState;/EdgeCount此时为1return NewCell;void cell_EdgeSet_Copy(cell& Destination,cell Source)int D_count

19、= Destination.EdgeCount;int S_count = Source.EdgeCount;for(int i=0;iS_count;i+)Destination.EdgeSetD_count+i = Source.EdgeSeti;Destination.EdgeCount = D_count + S_count;/*获得新的状态节点,统一产生,便于管理,不能产生重复的状态并添加到state_set数组中*/state new_StateNode()state newState;newState.StateName = STATE_NUM+65;/转换成大写字母STATE_

20、NUM+;return newState;/接收输入正规表达式,RegularExpression作为回传函数void input(string &RegularExpression)cout请输入正则表达式: (操作符:() * |;字符集:az AZ)RegularExpression;while(!check_legal(RegularExpression);/coutRegularExpressionendl;/*检测输入的正则表达式是否合法*/int check_legal(string check_string)if(check_character(check_string)&ch

21、eck_parenthesis(check_string)return true;return false;/*检查输入的字符是否合适 () * | az AZ合法返回true,非法返回false*/int check_character(string check_string)int length = check_string.size();for(int i=0;ilength;i+)char check = check_string.at(i);if(is_letter(check)/小写和大写之间有5个字符,故不能连续判断/cout字母 合法;else if(check=(|check

22、=)|check=*|check=|)/cout操作符 合法;elsecout含有不合法的字符!endl;cout请重新输入:endl;return false;return true;/*先检查括号是否匹配*合法返回true,非法返回false*/ int check_parenthesis(string check_string)int length = check_string.size();char * check = new charlength;strcpy(check,check_string.c_str();/char a = check_string.at(1);stack

23、STACK;for(int i=0;ilength;i+)if(checki=()STACK.push(i);else if(checki=)if(STACK.empty()cerr有多余的右括号endl;/暂时不记录匹配位置locationcout请重新输入:endl;return false;elseSTACK.pop();if(!STACK.empty()/暂时不记录匹配位置locationcerr有多余的左括号endl;cout请重新输入:endl;return false;/coutcheck=a&check=A&checka+b+b*/string add_join_symbol(

24、string add_string)/* 测试终止符0string check_string = abcdefg0aaa;coutcheck_stringendl;int length = check_string.size();char * check = new char2*length;strcpy(check,check_string.c_str();coutcheckendl;char *s = ssss0 aa;coutsendl;string a(s);coutaendl;*/int length = add_string.size();int return_string_len

25、gth = 0;char *return_string = new char2*length;/做多是两倍char first,second;for(int i=0;ilength-1;i+)first = add_string.at(i);second = add_string.at(i+1);return_stringreturn_string_length+ = first;/若第二个是字母、第一个不是(、|都要添加if(first!=(&first!=|&is_letter(second)return_stringreturn_string_length+ = +;/若第二个是(,第一

26、个不是|、(,也要加else if(second=(&first!=|&first!=()return_stringreturn_string_length+ = +;/将最后一个字符写入return_stringreturn_string_length+ = second;return_stringreturn_string_length = 0;string STRING(return_string);cout加+后的表达式:STRINGendl;return STRING;/*优先级表: #(*|+)isp 017538icp 086421*/in stack priority 栈内优先

27、级int isp(char c)switch(c)case #: return 0;case (: return 1;case *: return 7;case |: return 5;case +: return 3;case ): return 8;/若走到这一步,说明出错了cerrERROR!endl;return false;/in coming priority 栈外优先级int icp(char c)switch(c)case #: return 0;case (: return 8;case *: return 6;case |: return 4;case +: return 2;case ): return 1;/若走到这一步,说明出错了cerrERROR!endl;return false;/*中缀表达式转后缀表达式*/string postfix(string e)/设定e的最后一个符号式“#”,而其“#”一开始先放在栈s的栈底e = e+#;stack s;char ch = #,ch1,op;s.push(ch);/读一个字符string out_string = ;int read_location = 0;c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论