编译器学习(二)非确定有穷自动机的整理

重写了上次的代码

1.将node分为三种,voidchar,char,manychars,分别表示空node,单字符node,多字符node(针对自定义的\w,\n,\a);

2.顺序建树;

3.空节点的父子节点为非空节点,非空节点的父子节点为空节点;

4.空节点有多个子节点,非空节点只有一个子节点,根节点为空节点;

5.每次receive一个正则表达式,就在根节点建一子树;

6.转确定有穷自动机时,每次只需沿子节点前进两个节点(未实现)。

这样就清晰多了。

// main.cpp
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <cstdlib>
using namespace std;

#define DEBUG
const int MAXMATCHSIZE = 5;
const char *word = "\\w";
const char *number = "\\n";
const char *alnum = "\\a";
const char *allchar = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

struct node {
    int type;
    vector<node*> voidnode;    //  type == 0
    char schar;                //  type == 1
    vector<char> mchar;        //  type == 2
    node *next;                //  type >= 1
    int number;
    node(int t = 0):next(NULL), type(t), voidnode(), mchar(), schar(0) {
        static int count = 0;
        number = count++;
        #ifdef DEBUG
            cout << "new node,count=" << count << ",type=" << type << endl;
        #endif
    }
};
class parser {
private:
    node *head;
    map< string, vector<node*> > endnode;
    node* addnode(const string& name,node *cur, char c, bool pack_flag, bool end_flag);// a letter
    node* addnode(const string& name,node *cur, string, bool pack_flag, bool end_flag);// or string
public:
    parser();
    void receive(string ,string);
};

int main() {
    parser p;
    p.receive("begin[\\w]end","first");
    p.receive("123[word]456","second");
    return 0;
}

//  ensure that cur --> voidchar node
node* parser::addnode(const string& name,node *cur, char c, bool pack_flag, bool end_flag) {
    //cout <<c<<endl;
    node *p = new node(1);
    p->schar = c;
    p->next = new node;
    cur->voidnode.push_back(p);
    if (pack_flag) p->next->voidnode.push_back(p);
    if (end_flag) endnode[name].push_back(cur->next);
    return p->next;
}
node* parser::addnode(const string& name,node *cur, string s, bool pack_flag, bool end_flag) {
    //cout<<s<<endl;
    node *p = new node(2);
    p->next = new node;
    if (s[0] == ‘\\‘) {
        int begin = 0, end = 0;
        if (s[1] == word[1])begin = 10, end = 10 + 26 + 26;
        else if (s[1] == alnum[1])end = 36 + 26;
        else end = 10;
        p->mchar = vector<char>(allchar + begin, allchar + end);
    } else {
        p->mchar = vector<char>(s.begin(),s.end());
    }
    cur->voidnode.push_back(p);
    if (pack_flag) p->next->voidnode.push_back(cur);
    if (end_flag) endnode[name].push_back(cur->next);
    return p->next;
}

parser::parser():head(NULL) {
    head = new node();
}

void parser::receive(string s, string name) {
    if (s.empty()) return;
    node *cur = head;
    bool pack_flag = false;
    int len = s.size();
    for (int i = 0; i < len; ) {
        if ( s[i] == ‘*‘ ) pack_flag = true, i++;
        else if (s[i] == ‘[‘) {
            int j;
            for (j = i + 1; j < len && s[j] != ‘]‘; j++);
            cur = addnode(name,cur ,s.substr(i + 1 , j - i - 1) , pack_flag, j == len - 1);
            pack_flag = false;
            i = j + 1;
        }
        else if ( isalnum(s[i]) ) {
            cur = addnode(name,cur, s[i], pack_flag, i == 0);
            pack_flag = false;
            i++;
        }
    }
}
时间: 2024-10-24 12:02:30

编译器学习(二)非确定有穷自动机的整理的相关文章

Windows Azure 实验培训学习与交流(官方版整理二)

Windows Azure 技术更新比较快,也许有很多人下面的都已看过,为以后我们好回头可以查看,也为还没有看到这些官方材料的小伙伴们带来一些帮助,如下是整理的官方版实验材料都以链接形式呈现,方便大家学习和交流. 微软培训材料下载 http://windowsazure-trainingkit.github.io/index.htm 注:Github作为培训材料的存储库微软所有配套的材料都会及时更新到Github上 目前微软团队已将大部分培训材料翻译成中文 https://github.com/

【Ruby on Rails学习二】在线学习资料的整理

由于工作任务重,时间紧,没有太多学习的时间,大致找了些在线学习资料,这里做个整理,希望对同样准备学习的朋友有帮助 在线文档类: Ruby on Rails 实战圣经  使用 Rails 4.2 及 Ruby 2.3(简体中文版) Rails Guides(英文版)                        Rails Guides(简体中文版)                         Ruby on Rails API Ruby 中文社区                       

Java Interface 是常量存放的最佳地点吗?(转帖学习,非原创)

Java Interface 是常量存放的最佳地点吗?(转帖学习,非原创) 由于java interface中声明的字段在编译时会自动加上static final的修饰符,即声明为常量.因而interface通常是存放常量的最佳地点.然而在java的实际应用时却会产生一些问题. 问题的起因有两个,第一,是我们所使用的常量并不是一成不变的,而是相对于变量不能赋值改变.例如我们在一个工程初期定义常量∏=3.14,而由于计算精度的提高我们可能会重新定义∏=3.14159,此时整个项目对此常量的引用都应

IOS开发-OC学习-常用功能代码片段整理

IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是在做与URL有关的功能时,需要在Info.plist中添加一段代码进而实现让网址完成从Http到Https的转换,以及其他的一些功能. 在从一个新手到逐渐学会各种功能.代码.控件.方法如何使用的过程中,也在逐渐积累一些知识,但是一次总不会把这些东西都深刻记住并完全理解.所以在这儿记录下这些东西,用来

聚集索引和非聚集索引(整理)

From : http://www.cnblogs.com/aspnethot/articles/1504082.html 官方说法: 聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序.  聚集索引确定表中数据的物理顺序.聚集索引类似于电话簿,后者按姓氏排列数据.由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引.但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样.    聚集索引对于那些经常要搜索范围值的列特别有效.使用聚集索引找到

Jquery Easy UI初步学习(二)datagrid的使用

第一篇学的是做一个管理的外框,接着就是数据datagrid绑定了,这里我用asp.net mvc3来做的,主要就是熟悉属性.方法. 打开easyui的demo 就可以看到如下一段代码: 和上篇一样class="easyui-datagrid", data-options="...",这是一样的,其他我在网上查了查,并做了整理 DataGrid 属性 参数名 类型 描述 默认值 title string Datagrid面板的标题 null iconCls strin

u-boot学习(二):u-boot简要分析

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 看到不错的文章,不要添加收藏夹,想着以后有时间再看,因为很有可能你以后再也不会看它们了. 想写总结的文章,不要想着等到以后有时间了再总结,因为很有可能你以后更没有时间总结它们了. --送给自己 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Objective C 快速入门学习二

Objective-C 类.对象.方法 1.编写一个复数类: #import <Foundation/Foundation.h>@interface Complex: NSObject //类声明,Complex继承NSObject { int iReal;//成员变量声明,在括号内 int iImag; } //成员函数声明,在括号外 -(void) print; -(void) setReal : (int) n; -(void)setImag : (int) d; @end //@int

《PHP扩展学习系列》系列技术文章整理收藏

<PHP扩展学习系列>系列技术文章整理收藏 1PHP扩展之文本处理(二)--PCRE正则表达式语法10--后向引用http://www.lai18.com/content/321526.html 2PHP扩展之文本处理(二)--PCRE正则表达式语法9--重复/量词http://www.lai18.com/content/321525.html 3PHP扩展之文本处理(二)--PCRE正则表达式语法11--断言http://www.lai18.com/content/321527.html 4