Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

CFG grammar parser

Name: Anonymous 2008-04-13 18:52

I know there's gonna be some witty regular expression faggot posting here, but whatever.
Let's see your language do this.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>

/* CFG grammar */

typedef struct {
    int c;
    const char *str;
} cfg_t;

int eval(const char *buf, const cfg_t *, char *res, size_t sz);

int main(void)
{

    char buf[BUFSIZ];
    char res[BUFSIZ];
    char *p, *s, *tmp;
    int ret;
    size_t n;
    const cfg_t cfg[26] = {
    {'A', "hello"},
    {'B', "world"},
    {'C', "A B"},
    {'D', "A D"}
    };

    while (fgets(buf, sizeof buf, stdin) != NULL) {

    if (*buf && buf[strlen(buf) - 1] == '\n')
        buf[strlen(buf) - 1] = 0;

    p = buf;
    s = res;
    n = 0;

    while ((ret = eval(p, cfg, s, BUFSIZ)) == 1) {
        printf("%lu ==> %s\n", (unsigned long) n, s);
        tmp = p;
        p = s;
        s = tmp;
        n++;
    }

    if (ret == -1)
        printf("'%s': expansion too big to fit in %d buf\n",
           p, BUFSIZ);
    else
        printf("result: '%s'\n", s);

    }

    if (ferror(stdin)) {
    perror("stdin");
    return EXIT_FAILURE;
    }

    return 0;
}

int eval(const char *buf, const cfg_t * cfg, char *res, size_t sz)
{

    size_t i;
    int done = 0;

    while (*buf != 0) {
    if (isupper((unsigned char) *buf)) {
        for (i = 0; i < 26; i++)
        if (*buf == cfg[i].c)
            break;
        if (i != 26) {
        done = 1;
        if (strlen(cfg[i].str) >= sz)
            return -1;
        strcpy(res, cfg[i].str);
        res += strlen(cfg[i].str);
        sz -= strlen(cfg[i].str);
        }
    } else {
        if (sz <= 1)
        return -1;
        *res = *buf;
        res++;
        sz--;
    }
    buf++;
    }
    *res = 0;

    return done;
}


example

$ ./cfg
A
0 ==> hello
result: 'hello'
A B
0 ==> hello world
result: 'hello world'
BB
0 ==> worldworld
result: 'worldworld'
C
0 ==> A B
1 ==> hello world
result: 'hello world'
^D
$

Name: Anonymous 2008-04-13 20:25

import random, re
cfg = lambda g, r=random, t='%*', d=100: re.sub(r'%(.)', lambda m: cfg(g, r, r.choice(g.get(m.group(1), [m.group(1)])), d-1), t) if d else t

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List