6615943d4f353393cf63c704d477b5f832c15477
[external/ragel.git] / examples / awkemu / awkemu.rl
1 /*
2  * Perform the basic line parsing of input performed by awk.
3  */
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9
10 %%{
11         machine awkemu;
12
13         action start_word {
14                 ws[nwords] = fpc;
15         }
16
17         action end_word {
18                 we[nwords++] = fpc;
19         }
20
21         action start_line {
22                 nwords = 0;
23                 ls = fpc;
24         }
25
26         action end_line {
27                 printf("endline(%i): ", nwords );
28                 fwrite( ls, 1, p - ls, stdout );
29                 printf("\n");
30
31                 for ( i = 0; i < nwords; i++ ) {
32                         printf("  word: ");
33                         fwrite( ws[i], 1, we[i] - ws[i], stdout );
34                         printf("\n");
35                 }
36         }
37
38         # Words in a line.
39         word = ^[ \t\n]+;
40
41         # The whitespace separating words in a line.
42         whitespace = [ \t];
43
44         # The components in a line to break up. Either a word or a single char of
45         # whitespace. On the word capture characters.
46         blineElements = word >start_word %end_word | whitespace;
47
48         # Star the break line elements. Just be careful to decrement the leaving
49         # priority as we don't want multiple character identifiers to be treated as
50         # multiple single char identifiers.
51         line = ( blineElements** '\n' ) >start_line @end_line;
52
53         # Any number of lines.
54         main := line*;
55 }%%
56
57 %% write data noerror nofinal;
58
59 #define MAXWORDS 256
60 #define BUFSIZE 4096
61 char buf[BUFSIZE];
62
63 int main()
64 {
65         int i, nwords = 0;
66         char *ls = 0;
67         char *ws[MAXWORDS];
68         char *we[MAXWORDS];
69
70         int cs;
71         int have = 0;
72
73         %% write init;
74
75         while ( 1 ) {
76                 char *p, *pe, *data = buf + have;
77                 int len, space = BUFSIZE - have;
78                 /* fprintf( stderr, "space: %i\n", space ); */
79
80                 if ( space == 0 ) { 
81                         fprintf(stderr, "buffer out of space\n");
82                         exit(1);
83                 }
84
85                 len = fread( data, 1, space, stdin );
86                 /* fprintf( stderr, "len: %i\n", len ); */
87                 if ( len == 0 )
88                         break;
89
90                 /* Find the last newline by searching backwards. This is where 
91                  * we will stop processing on this iteration. */
92                 p = buf;
93                 pe = buf + have + len - 1;
94                 while ( *pe != '\n' && pe >= buf )
95                         pe--;
96                 pe += 1;
97
98                 /* fprintf( stderr, "running on: %i\n", pe - p ); */
99
100                 %% write exec;
101
102                 /* How much is still in the buffer. */
103                 have = data + len - pe;
104                 if ( have > 0 )
105                         memmove( buf, pe, have );
106
107                 /* fprintf(stderr, "have: %i\n", have ); */
108
109                 if ( len < space )
110                         break;
111         }
112
113         if ( have > 0 )
114                 fprintf(stderr, "input not newline terminated\n");
115         return 0;
116 }