tokstart => ts and tokend => te
[ragel.git] / test / awkemu.rl
blob343f3e6f6f0ff5e787800edc7e35b988d3920d08
1 /*
2  * @LANG: c
3  */
5 /*
6  * Emulate the basic parser of the awk program. Breaks lines up into
7  * words and prints the words.
8  */
10 #include <stdio.h>
11 #include <string.h>
13 #define LINEBUF 2048
14 static char lineBuf[LINEBUF];
15 static char blineBuf[LINEBUF];
16 static int lineLen;
17 static int blineLen;
18 static int words;
20 void finishLine();
22 struct awkemu
24         int cs;
27 %%{
28         machine awkemu;
30         variable cs fsm->cs;
32         # Starts a line. Will initialize all the data necessary for capturing the line.
33         action startline {
34                 lineLen = 0;    
35                 blineLen = 0;   
36                 words = 0;
37         }
39         # Will be executed on every character seen in a word. Captures the word
40         # to the broken up line buffer.
41         action wordchar {
42                 blineBuf[blineLen++] = fc;
43         }
45         # Terminate a word. Adds the null after the word and increments the word count
46         # for the line.
47         action termword {
48                 blineBuf[blineLen++] = 0;
49                 words += 1;
50         }
52         # Will be executed on every character seen in a line (not including 
53         # the newline itself.
54         action linechar {
55                 lineBuf[lineLen++] = fc;
56         }
58         # This section of the machine deals with breaking up lines into fields.
59         # Lines are separed by the whitespace and put in an array of words.
61         # Words in a line.
62         word = (extend - [ \t\n])+;
64         # The whitespace separating words in a line.
65         whitespace = [ \t];
67         # The components in a line to break up. Either a word or a single char of
68         # whitespace. On the word capture characters.
69         blineElements = word $wordchar %termword | whitespace;
71         # Star the break line elements. Just be careful to decrement the leaving
72         # priority as we don't want multiple character identifiers to be treated as
73         # multiple single char identifiers.
74         breakLine = ( blineElements $1 %0 )* . '\n';
76         # This machine lets us capture entire lines. We do it separate from the words
77         # in a line.
78         bufLine = (extend - '\n')* $linechar %{ finishLine(); } . '\n';
80         # A line can then consist of the machine that will break up the line into
81         # words and a machine that will buffer the entire line. 
82         line = ( breakLine | bufLine ) > startline;
84         # Any number of lines.
85         main := line*;
86 }%%
88 void finishLine()
90         int i;
91         char *pword = blineBuf;
92         lineBuf[lineLen] = 0;
93         printf("endline(%i): %s\n", words, lineBuf );
94         for ( i = 0; i < words; i++ ) {
95                 printf("  word: %s\n", pword );
96                 pword += strlen(pword) + 1;
97         }
100 %% write data;
102 void awkemu_init( struct awkemu *fsm )
104     %% write init;
107 void awkemu_execute( struct awkemu *fsm, const char *_data, int _len )
109     const char *p = _data;
110     const char *pe = _data+_len;
111         %% write exec;
114 int awkemu_finish( struct awkemu *fsm )
116         if ( fsm->cs == awkemu_error ) 
117                 return -1;
118         if ( fsm->cs >= awkemu_first_final ) 
119                 return 1;
120         return 0;
123 #include <stdio.h>
124 #define BUFSIZE 2048
126 struct awkemu fsm;
127 char buf[BUFSIZE];
129 void test( char *buf )
131         int len = strlen( buf );
132         awkemu_init( &fsm );
133         awkemu_execute( &fsm, buf, len );
134         if ( awkemu_finish( &fsm ) > 0 )
135                 printf("ACCEPT\n");
136         else
137                 printf("FAIL\n");
140 int main()
142         test( "" );
143         test( "one line with no newline" );
144         test( "one line\n" );
145         return 0;
148 #ifdef _____OUTPUT_____
149 ACCEPT
150 FAIL
151 endline(2): one line
152   word: one
153   word: line
154 ACCEPT
155 #endif