CFG grammar parser
1
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
$
2
Name:
Anonymous
2008-04-13 19:18
{ 'A', "SICP" },
{ 'B', READ A\nB" }
AB
3
Name:
Anonymous
2008-04-13 19:19
$cfg = {'A' => 'hello',
'B' => 'world',
'C' => 'A B',
'D' => 'A D'}
def cfg_eval(str)
r = ''
str.split(//).each {|k| r += $cfg.has_key?(k) ? cfg_eval($cfg[k]) : k }
r
end
$stdin.each_line {|l| puts 'result: ' + cfg_eval(l.rstrip).inspect}
4
Name:
Anonymous
2008-04-13 19:36
>>3
Your solution is recursive, not iterative like OPs.
It would fail in 'D' => 'D'.
5
Name:
Anonymous
2008-04-13 19:53
In "CFG grammar", what does the "G" stand for?
6
Name:
Anonymous
2008-04-13 20:00
7
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
8
Name:
Anonymous
2008-04-13 20:58
>>7
wtf theres no indentation
9
Name:
Anonymous
2008-04-13 21:22
>>8
[spoiler] [b] [i] THE FORCED UNINDENTATION OF CODE[/i] [/b] [/spoiler]
10
Name:
Anonymous
2008-04-13 21:30
>>1
I bet you input your PIN number to use an ATM machine so you can obtain money to buy a Network NAS device.
11
Name:
Anonymous
2008-04-13 21:42
12
Name:
Anonymous
2008-04-14 0:26
#!/usr/bin/perl
use strict;
use warnings;
my %re=(
A => "hello",
B => "world",
C => "A B",
D => "A D",
);
sub replace($){
$_[0]=join "",map{
while(my($k,$v)=each %re){
s|$k|$v| and last
}
$_
} split //,$_[0];
}
while(my $line=$_=<>){
my $index=0;
while($line ne replace $_){
print $index++," => ",$line=$_;
}
print "result: ",$_;
}
__END__
b:\>perl go.pl
C
0 => A B
1 => hello world
result: hello world
D
0 => A D
1 => hello A D
2 => hello hello A D
3 => hello hello hello A D
4 => hello hello hello hello A D
5 => hello hello hello hello hello A D
6 => hello hello hello hello hello hello A D
7 => hello hello hello hello hello hello hello A D
8 => hello hello hello hello hello hello hello hello A D
9 => hello hello hello hello hello hello hello hello hello A D
10 => hello hello hello hello hello hello hello hello hello hello A D
11 => hello hello hello hello hello hello hello hello hello hello hello A D
12 => hello hello hello hello hello hello hello hello hello hello hello hello A D
13 => hello hello hello hello hello hello hello hello hello hello hello hello hello A D
14 => hello hello hello hello hello hello hello hello hello hello hello hello hello hello A D
15 => hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello A D
16 => hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello A D
13
Name:
Anonymous
2008-04-14 0:28
b:\>perl go.pl
wat
14
Name:
Anonymous
2008-04-14 0:57
>>13
Yes, I'm using windows
15
Name:
Anonymous
2008-04-14 1:27
>>11
Hahaha, oh wow, I lol'd (LOL'd Out Loud).
16
Name:
Anonymous
2008-04-14 3:17
>>14
I'm more interested in the b: part.
Are you working off of a 5
1 /
4 " disk or something?
17
Name:
Anonymous
2008-04-14 3:47
>>16
It's a hard drive. You can rename them now
18
Name:
Anonymous
2008-04-14 4:06
>>17
I'm somewhat disappointed now :(
19
Name:
Anonymous
2008-04-14 5:08
20
Name:
Anonymous
2008-04-14 5:13
:-(
21
Name:
Anonymous
2008-04-14 5:36
:(
22
Name:
Anonymous
2008-04-14 5:57
ITT sad
23
Name:
Anonymous
2008-04-14 7:41
:') HAPPY TEARS
24
Name:
Anonymous
2008-04-14 7:52
import Control.Monad (forever)
cfg = [('A', "hello"),
('B', "world"),
('C', "A B"),
('D', "A D")]
fix f x | x' == x = [x]
| otherwise = x : fix f x'
where x' = f x
replace = concatMap (\c -> maybe [c] id $ lookup c cfg)
eval = unlines . enum . fix replace
where enum = zipWith (\a b -> show a ++ " => " ++ b) [0 ..]
main = forever (getLine >>= putStr . eval)
25
Name:
Anonymous
2008-04-14 8:47
>>4
$cfg = {'A' => 'hello',
'B' => 'world',
'C' => 'A B',
'D' => 'A D'}
def cfg_eval(str)
c, r = false, str.split(//).inject('') { |m,k|
m += $cfg.has_key?(k) ? c = true && cfg_eval($cfg[k]).to_s : k }
c ? cfg_eval(r) : r
end
$stdin.each_line {|l| puts 'result: ' + cfg_eval(l.rstrip).inspect}
26
Name:
Anonymous
2008-04-14 8:48
>>25
Oops, I saved the wrong version.
27
Name:
Anonymous
2008-04-14 8:55
$cfg = {'A' => 'hello',
'B' => 'world',
'C' => 'A B',
'D' => 'A D'}
def cfg_eval(str)
loop do
c = false
str = str.split(//).inject('') { |m,k| m += $cfg.has_key?(k) ? c = true && $cfg[k] : k }
break if not c
end
str
end
$stdin.each_line {|l| puts 'result: ' + cfg_eval(l.rstrip).inspect}
28
Name:
Anonymous
2008-04-14 9:55
No lispus? fale
29
Name:
Anonymous
2008-04-14 10:07
rispu
30
Name:
Anonymous
2008-04-14 10:25
In before flex version.
31
Name:
Anonymous
2008-04-14 10:40
>>28
Shows that nobody on /prog/ has actually read SICP.
32
Name:
Anonymous
2008-04-14 11:54
Not as elegant as the original C code but here's my attempt in Prolog:
a --> "hello".
b --> "world".
c --> a, " ", b.
d --> a, " ", d.
% ?- phrase(a,X), atom_codes(Y,X).
%
% X = [104, 101, 108, 108, 111],
% Y = hello
% ?- phrase((a," ",b),X), atom_codes(Y,X).
%
% X = [104, 101, 108, 108, 111, 32, 119, 111, 114|...],
% Y = 'hello world'
% ?- phrase((b,b),X), atom_codes(Y,X).
%
% X = [119, 111, 114, 108, 100, 119, 111, 114, 108|...],
% Y = worldworld
% ?- phrase(c,X), atom_codes(Y,X).
%
% X = [104, 101, 108, 108, 111, 32, 119, 111, 114|...],
% Y = 'hello world'
33
Name:
Anonymous
2008-04-14 13:37
module CFG where
a = "hello"
b = "world"
c = a ++ " " ++ b
d = a ++ " " ++ d
Prelude> :l CFG
[1 of 1] Compiling CFG ( CFG.hs, interpreted )
Ok, modules loaded: CFG.
*CFG> a
"hello"
*CFG> b
"world"
*CFG> c
"hello world"
*CFG> d
"hello hello hello hello hello hello hello hello hello hello hello ...
34
Name:
Anonymous
2008-04-14 13:49
>>33
Expert ConFiGuration file programmer.
35
Name:
Anonymous
2008-04-14 15:06
>>33
Ah, but can you compile it and run?
36
Name:
Anonymous
2008-04-14 15:44
>>33
that's fucking fail, read OPs problem, understand why yours is not a solution and come back to us.
37
Name:
Anonymous
2008-04-14 17:09
Here's it in basic:
print"hello world"
Of course it only works if a and b is hello world and the input is a b.
38
Name:
Anonymous
2008-04-14 17:11
39
Name:
Anonymous
2008-04-14 17:17
>>10
And he'll use that to send packets through the IP protocol?
40
Name:
Anonymous
2008-04-14 17:37
>>39
Do you have any idea what the IP (or rather, IPv4 or IPv6 -- please be specific) protocol is?
Or what the definition of a packet is?
Was that an attempt at funny internet?
41
Name:
Anonymous
2008-04-14 17:44
>>10
Do you have something against
GJS Jay Sussman ?
42
Name:
Anonymous
2008-04-14 17:57
>>40
IP protocol.
Internet protocol protocol.
Read
>>10 again.
43
Name:
Anonymous
2008-04-14 17:58
>>40
I'm proud to announce that you have been successfully trolled. How do you feel?
44
Name:
39
2008-04-14 18:08
>>43
I wasn't even trolling, he just completely missed the RAS Syndrome joke I made. Considering I was replying to
>>10, who made 3 of those, you can say that this was a severe case of JOKE OVER HEAD.
Which makes him a dumbass, because he's acting like he's an
EXPERT NETWORKING PROGRAMMER , yet he didn't realize that IP stands for Internet Protocol.
45
Name:
Anonymous
2008-04-14 18:46
>>44
FUQING BULL
ASK ME ANYTHING ABOUT NETWORQING
OR CAN YOU ONLY MUMBO JUMBO ABOUT 3WAY HANDSHAKE MOTHERFUCKER
46
Name:
Anonymous
2008-04-14 18:48
47
Name:
Anonymous
2008-04-14 19:02
I hate people who whine about RAS syndrome.
For talking to people who might not know what an acronym means, it can be useful to reduce ambiguity in such a way. Language is around to further communication, not to pedantize about stupid details.
>>1-46 are the same person and
IHBTC .
48
Name:
Anonymous
2008-04-14 19:03
>>47
I was trolled as well, but in O(log n)
49
Name:
Anonymous
2008-04-14 19:27
>>47
Don't use the acronym if it will cause confusion.
50
Name:
Anonymous
2008-04-14 19:46
51
Name:
Anonymous
2008-04-14 20:11
DUTAIIWCC confusion
52
Name:
Anonymous
2008-04-15 1:31
>>40
[b] [o] [i] DO YOU MOTHERFUCKER?[/b] [/o] [/i]
53
Name:
Anonymous
2008-04-15 3:23
>>52
Use a stack, not a queue.
54
Name:
Anonymous
2008-04-15 9:00
55
Name:
Anonymous
2008-04-15 9:10
56
Name:
Anonymous
2008-04-15 12:09
+<section
+ title="News: new WineTricks, 1.0 status updates and more"
+ subject="Wine"
+ archive="http://www.xkcd.com "
+ posts="0"
+>
How is the url above related to the title?
It isn't, I had nothing else to put. I generally leave them blank but
I for some reason decided to throw xkcd in there this time.
57
Name:
Anonymous
2008-04-15 17:34
>>52
BBCODE MAH
[b] [o] [i]
58
Name:
Anonymous
2008-04-15 17:45
59
Name:
Anonymous
2008-04-15 18:28
60
Name:
Anonymous
2008-04-16 5:19
>>50
PROTIP: When you set the context, you can use the acronym form as there shouldn't be any more abiguity
61
Name:
Anonymous
2008-04-17 11:52
gtfo
62
Name:
Anonymous
2008-04-17 16:44
63
Name:
Anonymous
2008-04-17 17:31
>>61
saw that reply when I mentioned I'm the OP of this thread.
Obviously
>>61,62 is the same person.
You fail, so far I've seen every fucking thing you've tried to do.
64
Name:
Anonymous
2008-04-17 18:09
>>63
Actually no, I am
>>61 but not
>>62 .
Obviously,
>>63 and
>>62 are the same person since
>>63 is the OP.
gtfo
65
Name:
Anonymous
2008-04-17 19:43
Obviously, >>63 and >>62 are the same person since >>63 is the OP.
No that doesn't make sense, but since you sage you are an ally.
66
Name:
Anonymous
2008-04-17 20:27
>>65
That makes sense, and since you sage you are an ally.
67
Name:
Anonymous
2011-02-02 22:58
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy
All work and no play makes Jack a dull boy