diff options
Diffstat (limited to 'test/union.rl')
-rw-r--r-- | test/union.rl | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/test/union.rl b/test/union.rl new file mode 100644 index 0000000..6ad7e9a --- /dev/null +++ b/test/union.rl @@ -0,0 +1,189 @@ +/* + * @LANG: c++ + * Show off concurrent abilities. + */ + +#include <iostream> +#include <stdlib.h> +#include <stdio.h> + +using namespace std; + +#define BUFSIZE 2048 + +struct Concurrent +{ + int cur_char; + int start_word; + int start_comment; + int start_literal; + + int cs; + + // Initialize the machine. Invokes any init statement blocks. Returns 0 + // if the machine begins in a non-accepting state and 1 if the machine + // begins in an accepting state. + void init( ); + + // Execute the machine on a block of data. Returns -1 if after processing + // the data, the machine is in the error state and can never accept, 0 if + // the machine is in a non-accepting state and 1 if the machine is in an + // accepting state. + void execute( const char *data, int len ); + + // Indicate that there is no more data. Returns -1 if the machine finishes + // in the error state and does not accept, 0 if the machine finishes + // in any other non-accepting state and 1 if the machine finishes in an + // accepting state. + int finish( ); +}; + +%%{ + machine Concurrent; + + action next_char { + cur_char += 1; + } + + action start_word { + start_word = cur_char; + } + action end_word { + cout << "word: " << start_word << + " " << cur_char-1 << endl; + } + + action start_comment { + start_comment = cur_char; + } + action end_comment { + cout << "comment: " << start_comment << + " " << cur_char-1 << endl; + } + + action start_literal { + start_literal = cur_char; + } + action end_literal { + cout << "literal: " << start_literal << + " " << cur_char-1 << endl; + } + + # Count characters. + chars = ( any @next_char )*; + + # Words are non-whitespace. + word = ( any-space )+ >start_word %end_word; + words = ( ( word | space ) $1 %0 )*; + + # Finds C style comments. + comment = ( '/*' any* $0 '*/'@1 ) >start_comment %end_comment; + comments = ( ( comment | any ) $1 %0 )*; + + # Finds single quoted strings. + literalChar = ( any - ['\\] ) | ( '\\' . any ); + literal = ('\'' literalChar* '\'' ) >start_literal %end_literal; + literals = ( ( literal | (any-'\'') ) $1 %0 )*; + + main := chars | words | comments | literals; +}%% + +%% write data; + +void Concurrent::init( ) +{ + cur_char = 0; + %% write init; +} + +void Concurrent::execute( const char *data, int len ) +{ + const char *p = data; + const char *pe = data + len; + + %% write exec; +} + +int Concurrent::finish( ) +{ + %% write eof; + if ( cs == Concurrent_error ) + return -1; + if ( cs >= Concurrent_first_final ) + return 1; + return 0; +} + +void test( char *buf ) +{ + Concurrent concurrent; + concurrent.init(); + concurrent.execute( buf, strlen(buf) ); + if ( concurrent.finish() > 0 ) + cout << "ACCEPT" << endl; + else + cout << "FAIL" << endl; +} + +int main() +{ + test( + "/* in a comment,\n" + " * ' and now in a literal string\n" + " */ \n" + " \n" + "the comment has now ended but the literal string lives on\n" + "\n" + "' comment closed\n" ); + test( "/* * ' \\' */ \\' '\n" ); + test( "/**/'\\''/*/*/\n" ); + return 0; +} + +#ifdef _____OUTPUT_____ +word: 1 2 +word: 4 5 +word: 7 7 +word: 9 16 +word: 19 19 +word: 21 21 +word: 23 25 +word: 27 29 +word: 31 32 +word: 34 34 +word: 36 42 +word: 44 49 +word: 52 53 +comment: 1 53 +word: 58 60 +word: 62 68 +word: 70 72 +word: 74 76 +word: 78 82 +word: 84 86 +word: 88 90 +word: 92 98 +word: 100 105 +word: 107 111 +word: 113 114 +word: 117 117 +literal: 21 117 +word: 119 125 +word: 127 132 +ACCEPT +word: 1 2 +word: 4 4 +word: 6 6 +word: 8 9 +word: 11 12 +comment: 1 12 +word: 14 15 +word: 17 17 +literal: 6 17 +ACCEPT +comment: 1 4 +literal: 5 8 +word: 1 13 +comment: 9 13 +ACCEPT +#endif |