免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
论坛 程序设计 C/C++ thompson
最近访问板块 发新帖
查看: 1584 | 回复: 7
打印 上一主题 下一主题

[C] thompson [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-09-29 11:24 |只看该作者 |倒序浏览
本帖最后由 _nosay 于 2016-09-29 12:34 编辑

我帮大家找到一份大牛写的代码,来自:https://swtch.com/~rsc/regexp/nfa.c.txt
顺便测试打赏功能,大家快向我打赏,我看看能不能收得到

/*
*
Regular expression implementation.
* Supports only ( | ) * + ?.  No escapes.
* Compiles to NFA and then simulates NFA
* using Thompson's algorithm.
*
* See also http://swtch.com/~rsc/regexp/ and
* Thompson, Ken.  Regular Expression Search Algorithm,
* Communications of the ACM 11(6) (June 196, pp. 419-422.
*
* Copyright (c) 2007 Russ Cox.
* Can be distributed under the MIT license, see bottom of file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/*
* Convert infix regexp re to postfix notation.
* Insert . as explicit concatenation operator.
* Cheesy parser, return static buffer.
*/
char*
re2post(char *re)
{
    int nalt, natom;
    static char buf[8000];
    char *dst;
    struct {
        int nalt;
        int natom;
    } paren[100], *p;
    p = paren;
    dst = buf;
    nalt = 0;
    natom = 0;
    if(strlen(re) >= sizeof buf/2)
        return NULL;
    for(; *re; re++){
        switch(*re){
        case '(':
            if(natom > 1){
                --natom;
                *dst++ = '.';
            }
            if(p >= paren+100)
                return NULL;
            p->nalt = nalt;
            p->natom = natom;
            p++;
            nalt = 0;
            natom = 0;
            break;
        case '|':
            if(natom == 0)
                return NULL;
            while(--natom > 0)
                *dst++ = '.';
            nalt++;
            break;
        case ')':
            if(p == paren)
                return NULL;
            if(natom == 0)
                return NULL;
            while(--natom > 0)
                *dst++ = '.';
            for(; nalt > 0; nalt--)
                *dst++ = '|';
            --p;
            nalt = p->nalt;
            natom = p->natom;
            natom++;
            break;
        case '*':
        case '+':
        case '?':
            if(natom == 0)
                return NULL;
            *dst++ = *re;
            break;
        default:
            if(natom > 1){
                --natom;
                *dst++ = '.';
            }
            *dst++ = *re;
            natom++;
            break;
        }
    }
    if(p != paren)
        return NULL;
    while(--natom > 0)
        *dst++ = '.';
    for(; nalt > 0; nalt--)
        *dst++ = '|';
    *dst = 0;
    return buf;
}
/*
* Represents an NFA state plus zero or one or two arrows exiting.
* if c == Match, no arrows out; matching state.
* If c == Split, unlabeled arrows to out and out1 (if != NULL).
* If c < 256, labeled arrow with character c to out.
*/
enum{
    Match = 256,
    Split = 257
};
typedef struct State State;
struct State{
    int c;
    State *out;
    State *out1;
    int lastlist;
};
State matchstate = { Match };        /* matching state */
int nstate;
/* Allocate and initialize State */
State*
state(int c, State *out, State *out1){
    State *s;
    nstate++;
    s = malloc(sizeof *s);
    s->lastlist = 0;
    s->c = c;
    s->out = out;
    s->out1 = out1;
    return s;
}
/*
* A partially built NFA without the matching state filled in.
* Frag.start points at the start state.
* Frag.out is a list of places that need to be set to the
* next state for this fragment.
*/
typedef struct Frag Frag;
typedef union Ptrlist Ptrlist;
struct Frag{
    State *start;
    Ptrlist *out;
};
/* Initialize Frag struct. */
Frag
frag(State *start, Ptrlist *out){
    Frag n = { start, out };
    return n;
}
/*
* Since the out pointers in the list are always
* uninitialized, we use the pointers themselves
* as storage for the Ptrlists.
*/
union Ptrlist{
    Ptrlist *next;
    State *s;
};
/* Create singleton list containing just outp. */
Ptrlist*
list1(State **outp){
    Ptrlist *l;
    l = (Ptrlist*)outp;
    l->next = NULL;
    return l;
}
/* Patch the list of states at out to point to start. */
void
patch(Ptrlist *l, State *s){
    Ptrlist *next;
    for(; l; l=next){
        next = l->next;
        l->s = s;
    }
}
/* Join the two lists l1 and l2, returning the combination. */
Ptrlist*
append(Ptrlist *l1, Ptrlist *l2){
    Ptrlist *oldl1;
    oldl1 = l1;
    while(l1->next)
        l1 = l1->next;
    l1->next = l2;
    return oldl1;
}
/*
* Convert postfix regular expression to NFA.
* Return start state.
*/
State*
post2nfa(char *postfix){
    char *p;
    Frag stack[1000], *stackp, e1, e2, e;
    State *s;
    // fprintf(stderr, "postfix: %s\n", postfix);
    if(postfix == NULL
        return NULL;
    #define push(s) *stackp++ = s
    #define pop() *--stackp
    stackp = stack;
    for(p=postfix; *p; p++){
        switch(*p){
        default:
            s = state(*p, NULL, NULL);
            push(frag(s, list1(&s->out)));
            break;
        case '.':        /* catenate */
            e2 = pop();
            e1 = pop();
            patch(e1.out, e2.start);
            push(frag(e1.start, e2.out));
            break;
        case '|':        /* alternate */
            e2 = pop();
            e1 = pop();
            s = state(Split, e1.start, e2.start);
            push(frag(s, append(e1.out, e2.out)));
            break;
        case '?':        /* zero or one */
            e = pop();
            s = state(Split, e.start, NULL);
            push(frag(s, append(e.out, list1(&s->out1))));
            break;
        case '*':        /* zero or more */
            e = pop();
            s = state(Split, e.start, NULL);
            patch(e.out, s);
            push(frag(s, list1(&s->out1)));
            break;
        case '+':        /* one or more */
            e = pop();
            s = state(Split, e.start, NULL);
            patch(e.out, s);
            push(frag(e.start, list1(&s->out1)));
            break;
        }
    }
    e = pop();
    if(stackp != stack)
        return NULL;
    patch(e.out, &matchstate);
    return e.start;
#undef pop
#undef push
}
typedef struct List List;
struct List{
    State **s;
    int n;
};
List l1, l2;
static int listid;
void addstate(List*, State*);
void step(List*, int, List*);
/* Compute initial state list */
List*
startlist(State *start, List *l){
    l->n = 0;
    listid++;
    addstate(l, start);
    return l;
}
/* Check whether state list contains a match. */
int
ismatch(List *l){
    int i;
    for(i=0; i<l->n; i++)
        if(l->s == &matchstate)
            return 1;
    return 0;
}
/* Add s to l, following unlabeled arrows. */
void
addstate(List *l, State *s){
    if(s == NULL || s->lastlist == listid)
        return;
    s->lastlist = listid;
    if(s->c == Split){
        /* follow unlabeled arrows */
        addstate(l, s->out);
        addstate(l, s->out1);
        return;
    }
    l->s[l->n++] = s;
}
/*
* Step the NFA from the states in clist
* past the character c,
* to create next NFA state set nlist.
*/
void
step(List *clist, int c, List *nlist){
    int i;
    State *s;
    listid++;
    nlist->n = 0;
    for(i=0; i<clist->n; i++){
        s = clist->s;
        if(s->c == c)
            addstate(nlist, s->out);
    }
}
/* Run NFA to determine whether it matches s. */
int
match(State *start, char *s){
    int i, c;
    List *clist, *nlist, *t;
    clist = startlist(start, &l1);
    nlist = &l2;
    for(; *s; s++){
        c = *s & 0xFF;
        step(clist, c, nlist);
        t = clist; clist = nlist; nlist = t;        /* swap clist, nlist */
    }
    return ismatch(clist);
}
int
main(int argc, char **argv){
    int i;
    char *post;
    State *start;
    if(argc < 3){
        fprintf(stderr, "usage: nfa regexp string...\n";
        return 1;
    }
    post = re2post(argv[1]);
    if(post == NULL){
        fprintf(stderr, "bad regexp %s\n", argv[1]);
        return 1;
    }
    start = post2nfa(post);
    if(start == NULL){
        fprintf(stderr, "error in post2nfa %s\n", post);
        return 1;
    }
    l1.s = malloc(nstate*sizeof l1.s[0]);
    l2.s = malloc(nstate*sizeof l2.s[0]);
    for(i=2; i<argc; i++)
        if(match(start, argv))
            printf("%s\n", argv);
    return 0;
}
/*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated
* documentation files (the "Software", to deal in the
* Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall
* be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
2 [报告]
发表于 2016-09-29 11:35 |只看该作者

论坛徽章:
95
程序设计版块每日发帖之星
日期:2015-09-05 06:20:00程序设计版块每日发帖之星
日期:2015-09-17 06:20:00程序设计版块每日发帖之星
日期:2015-09-18 06:20:002015亚冠之阿尔艾因
日期:2015-09-18 10:35:08月度论坛发贴之星
日期:2015-09-30 22:25:002015亚冠之阿尔沙巴布
日期:2015-10-03 08:57:39程序设计版块每日发帖之星
日期:2015-10-05 06:20:00每日论坛发贴之星
日期:2015-10-05 06:20:002015年亚冠纪念徽章
日期:2015-10-06 10:06:482015亚冠之塔什干棉农
日期:2015-10-19 19:43:35程序设计版块每日发帖之星
日期:2015-10-21 06:20:00每日论坛发贴之星
日期:2015-09-14 06:20:00
3 [报告]
发表于 2016-09-29 15:42 |只看该作者
回复 2# MMMIX

我去,是 Russ Cox 的主页呀。

论坛徽章:
14
水瓶座
日期:2014-06-10 09:51:0215-16赛季CBA联赛之江苏
日期:2017-11-27 11:42:3515-16赛季CBA联赛之八一
日期:2017-04-12 14:26:2815-16赛季CBA联赛之吉林
日期:2016-08-20 10:43:1215-16赛季CBA联赛之广夏
日期:2016-06-23 09:53:58程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-09 06:20:0015-16赛季CBA联赛之上海
日期:2015-12-25 16:40:3515-16赛季CBA联赛之广夏
日期:2015-12-22 09:39:36程序设计版块每日发帖之星
日期:2015-08-24 06:20:002015亚冠之德黑兰石油
日期:2015-08-07 09:57:302015年辞旧岁徽章
日期:2015-03-03 16:54:15
4 [报告]
发表于 2016-09-29 15:52 |只看该作者
可以扣分吗?代码你好歹对齐呀

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
5 [报告]
发表于 2016-09-29 16:26 |只看该作者
回复 3# MMMIX


    装了UNIX的PDP-11最早被安装在Bell Lab里供大家日常使用。
    很快大家就发现Ken爷爷总能进入他们的帐户,获得最高权限。Bell Lab里的科学家都心比天高,当然被搞得郁闷无比。于是有高手怒了,跳出来分析了UNIX代码,找到后门,修改代码,然后重新编译了整个UNIX。就在大家都以为“这个世界清净了”的时候,他们发现Ken爷爷还是轻而易举地拿到他们的帐户权限,百思不解后,只好继续郁闷。谁知道这一郁闷,就郁闷了14年,直到Ken爷爷获得图灵奖之后,发表自己获奖感言时道出个其中缘由。原来,代码里的确有后门,但后门不在Unix代码里,而在编译Unix代码的C编译器里。

论坛徽章:
6
数据库技术版块每日发帖之星
日期:2015-11-27 06:20:00程序设计版块每日发帖之星
日期:2015-12-01 06:20:00每日论坛发贴之星
日期:2015-12-01 06:20:0015-16赛季CBA联赛之佛山
日期:2017-03-26 23:38:0315-16赛季CBA联赛之江苏
日期:2017-07-17 10:08:4415-16赛季CBA联赛之北京
日期:2018-03-04 17:01:50
6 [报告]
发表于 2016-10-08 12:53 |只看该作者
打赏鼓励一下!

论坛徽章:
146
2015年亚洲杯之日本
日期:2015-04-28 13:32:012015年亚洲杯之朝鲜
日期:2015-05-06 10:16:442015年亚洲杯之日本
日期:2015-05-06 10:21:342015年亚洲杯纪念徽章
日期:2015-05-13 17:16:442015亚冠之北京国安
日期:2015-05-13 17:18:292015亚冠之鹿岛鹿角
日期:2015-05-13 17:19:062015亚冠之德黑兰石油
日期:2015-05-27 16:47:402015亚冠之塔什干棉农
日期:2015-05-28 15:24:122015亚冠之卡尔希纳萨夫
日期:2015-06-01 13:52:392015亚冠之柏斯波利斯
日期:2015-06-04 17:37:292015亚冠之阿尔纳斯尔
日期:2015-06-16 11:31:202015亚冠之塔什干火车头
日期:2015-06-23 10:12:33
7 [报告]
发表于 2016-10-08 13:25 |只看该作者
已打赏回复 1# _nosay


论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
8 [报告]
发表于 2016-10-08 15:58 |只看该作者
回复 7# 王楠w_n


谢谢老板
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP